From ad538dd08f2720d3a9e42d76d580c9acf98ff18c Mon Sep 17 00:00:00 2001 From: fredtempez Date: Thu, 14 Apr 2022 22:21:57 +0200 Subject: [PATCH] update dot --- core/class/jsondb/Dot.class.php | 178 +++++++++++++++++++-- core/class/jsondb/LICENSE.md | 19 +++ core/class/jsondb/README.md | 269 ++++++++++++++++++++++++++++++++ 3 files changed, 453 insertions(+), 13 deletions(-) create mode 100644 core/class/jsondb/LICENSE.md create mode 100644 core/class/jsondb/README.md diff --git a/core/class/jsondb/Dot.class.php b/core/class/jsondb/Dot.class.php index 3c4af643..3b75dbc6 100644 --- a/core/class/jsondb/Dot.class.php +++ b/core/class/jsondb/Dot.class.php @@ -10,7 +10,7 @@ use ArrayAccess; * This class provides dot notation access to arrays, so it's easy to handle * multidimensional data in a clean way. */ -class Dot implements ArrayAccess +class Dot implements \ArrayAccess, \Iterator, \Countable { /** @var array Data */ @@ -94,9 +94,14 @@ class Dot implements ArrayAccess */ public static function addValue(&$array, $key, $value = null, $pop = false) { - if (is_string($key)) { + if (is_array($key)) { + // Iterate array of paths and values + foreach ($key as $k => $v) { + self::addValue($array, $k, $v); + } + } else { // Iterate path - $keys = explode('.', $key); + $keys = explode('.', (string)$key); if ($pop === true) { array_pop($keys); } @@ -108,11 +113,6 @@ class Dot implements ArrayAccess } // Add value to path $array[] = $value; - } elseif (is_array($key)) { - // Iterate array of paths and values - foreach ($key as $k => $v) { - self::addValue($array, $k, $v); - } } } @@ -154,9 +154,14 @@ class Dot implements ArrayAccess * @param mixed|null $default Default value * @return mixed Value of path */ - public function get($key = null, $default = null) + public function get($key, $default = null, $asObject = false) { - return self::getValue($this->data, $key, $default); + $value = self::getValue($this->data, $key, $default); + if ($asObject && is_array($value)) { + return new self($value); + } + + return $value; } /** @@ -164,10 +169,12 @@ class Dot implements ArrayAccess * * @param mixed $key Path or array of paths and values * @param mixed|null $value Value to set if path is not an array + * @return $this */ public function set($key, $value = null) { - return self::setValue($this->data, $key, $value); + self::setValue($this->data, $key, $value); + return $this; } /** @@ -176,10 +183,12 @@ class Dot implements ArrayAccess * @param mixed $key Path or array of paths and values * @param mixed|null $value Value to set if path is not an array * @param boolean $pop Helper to pop out last key if value is an array + * @return $this */ public function add($key, $value = null, $pop = false) { - return self::addValue($this->data, $key, $value, $pop); + self::addValue($this->data, $key, $value); + return $this; } /** @@ -206,10 +215,42 @@ class Dot implements ArrayAccess * Delete path or array of paths * * @param mixed $key Path or array of paths to delete + * @return $this */ public function delete($key) { - return self::deleteValue($this->data, $key); + self::deleteValue($this->data, $key); + return $this; + } + + /** + * Increase numeric value + * + * @param string $key + * @param float $number + * @return float + */ + public function plus(string $key, float $number): float + { + $newAmount = $this->get($key, 0) + $number; + $this->set($key, $newAmount); + + return $newAmount; + } + + /** + * Reduce numeric value + * + * @param string $key + * @param float $number + * @return float + */ + public function minus(string $key, float $number): float + { + $newAmount = $this->get($key, 0) - $number; + $this->set($key, $newAmount); + + return $newAmount; } /** @@ -313,4 +354,115 @@ class Dot implements ArrayAccess { $this->delete($key); } + + /** + * Check for emptiness + * + * @return bool + */ + public function isEmpty(): bool + { + return !(bool)count($this->data); + } + + /** + * Return all data as array + * + * @return array + */ + public function toArray() + { + return $this->data; + } + + /** + * Return as json string + * + * @return false|string + */ + public function toJson() + { + return json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT); + } + + /** + * @return string + */ + public function __toString() + { + return $this->toJson(); + } + + /** + * @return array + */ + public function __toArray() + { + return $this->toArray(); + } + + /** + * Return the current element + * @link https://php.net/manual/en/iterator.current.php + * @return mixed Can return any type. + * @since 5.0.0 + */ + public function current() + { + return current($this->data); + } + + /** + * Move forward to next element + * @link https://php.net/manual/en/iterator.next.php + * @return void Any returned value is ignored. + * @since 5.0.0 + */ + public function next() + { + return next($this->data); + } + + /** + * Return the key of the current element + * @link https://php.net/manual/en/iterator.key.php + * @return mixed scalar on success, or null on failure. + * @since 5.0.0 + */ + public function key() + { + return key($this->data); + } + + /** + * Checks if current position is valid + * @link https://php.net/manual/en/iterator.valid.php + * @return bool The return value will be casted to boolean and then evaluated. + * Returns true on success or false on failure. + * @since 5.0.0 + */ + public function valid() + { + $key = key($this->data); + return ($key !== NULL && $key !== FALSE); + } + + /** + * Rewind the Iterator to the first element + * @link https://php.net/manual/en/iterator.rewind.php + * @return void Any returned value is ignored. + * @since 5.0.0 + */ + public function rewind() + { + return reset($this->data); + } + + /** + * @inheritDoc + */ + public function count() + { + return count($this->data); + } } diff --git a/core/class/jsondb/LICENSE.md b/core/class/jsondb/LICENSE.md new file mode 100644 index 00000000..a3ecbe05 --- /dev/null +++ b/core/class/jsondb/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) 2016-2017 Andrey Mistulov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/core/class/jsondb/README.md b/core/class/jsondb/README.md new file mode 100644 index 00000000..6656cd7a --- /dev/null +++ b/core/class/jsondb/README.md @@ -0,0 +1,269 @@ +# Dot - PHP dot notation array access +Based on [adbario/php-dot-notation](https://github.com/adbario/php-dot-notation) package + +Easy access to multidimensional arrays with dot notation. +With dot notation, your code is cleaner and handling deeper arrays is super easy. + +This class implements PHP's ArrayAccess class, so Dot object can also be used the same way as normal arrays with additional dot notation. + +With Dot you can change this: + +```php +echo $data['info']['home']['address']; +``` + +to this: + +```php +echo $data->get('info.home.address'); +``` + +or even this: + +```php +echo $data['info.home.address']; +``` + +## Installation + +Via composer: + +``` +composer require adbario/php-dot-notation +``` + +Or just copy the class file Dot.php and handle namespace yourself. + +#### With [Composer](https://getcomposer.org/): + +``` +composer require adbario/php-dot-notation +``` + +#### Manual installation: +1. Download the latest release +2. Extract the files into your project +3. require_once '/path/to/php-dot-notation/src/Dot.php'; + +## Usage + +This array will be used as a reference on this guide: + +```php +$array = [ + 'user' => [ + 'firstname' => 'John', + 'lastname' => 'Smith' + ], + 'info' => [ + 'kids' => [ + 0 => 'Laura', + 1 => 'Chris', + 2 => 'Little Johnny' + ], + 'home' => [ + 'address' => 'Rocky Road 3' + ] + ] +]; +``` + +### Create a Dot object + +To start with an empty array, just create a new Dot object: + +```php +$data = new \Adbar\Dot; +``` + +If you have an array already available, inject it to the Dot object: + +```php +$data = new \Adbar\Dot($array); +``` + +Set an array after creating the Dot object: + +```php +$data->setArray($array); +``` + +Set an array as a reference, and all changes will be made directly to the original array: + +```php +$data->setReference($array); +``` + +### Set a value + +Set i.e. a phone number in the 'home' array: + +```php +$data->set('info.home.tel', '09-123-456-789'); + +// Array style +$data['info.home.tel'] = '09-123-456-789'; +``` + +Set multiple values at once: + +```php +$data->set([ + 'user.haircolor' => 'blue', + 'info.home.address' => 'Private Lane 1' +]); +``` + +If the value already exists, Dot will override it with a new value. + +### Get a value + +```php +echo $data->get('info.home.address'); + +// Default value if the path doesn't exist +echo $data->get('info.home.country', 'some default value'); + +// Array style +echo $data['info.home.address']; +``` + +Get all the stored values: + +```php +$values = $data->all(); +`` + +Get a value from a path and remove it: + +```php +$address = $data->pull('home.address'); +``` + +Get all the stored values and remove them: + +```php +$values = $data->pull(); +``` + +### Add a value + +```php +$data->add('info.kids', 'Amy'); +``` + +Multiple values at once: + +```php +$data->add('info.kids', [ + 'Ben', 'Claire' +]); +``` + +### Check if a value exists + +```php +if ($data->has('info.home.address')) { + // Do something... +} + +// Array style +if (isset($data['info.home.address'])) { + // Do something... +} +``` + +### Delete a value + +```php +$data->delete('info.home.address'); + +// Array style +unset($data['info.home.address']); +``` + +Multiple values at once: + +```php +$data->delete([ + 'user.lastname', 'info.home.address' +]); +``` + +### Clear values + +Delete all the values from a path: + +```php +$data->clear('info.home'); +``` + +Clear multiple paths at once: + +```php +$data->clear([ + 'user', 'info.home' +]); +``` + +Clear all data: + +```php +$data->clear(); +``` + +### Sort the values + +You can sort the values of a given path or all the stored values. + +Sort the values of a path: + +```php +$kids = $data->sort('info.kids'); + +// Sort recursively +$info = $data->sort('info'); +``` + +Sort all the values + +```php +$sorted = $data->sort(); + +// Sort recursively +$sorted = $data->sort(); +``` + +### Magic methods + +Magic methods can be used to handle single level data (without dot notation). These examples are not using the same data array as examples above. + +Set a value: + +```php +$data->name = 'John'; +``` + +Get a value: + +```php +echo $data->name; +``` + +Check if a value exists: + +```php +if (isset($data->name)) { + // Do something... +} +``` + +Delete a value: + +```php +unset($data->name); +``` + +## License + +[MIT license](LICENSE.md)