diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ac889c..bb104d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # (MODX)EvolutionCMS.libraries.ddTools changelog +## Version 0.52 (2021-11-16) +* \+ `\DDTools\ObjectTools::unfold`: The new method. + Converts a multidimensional array/object into an one-dimensional one joining the keys with `$params->keySeparator`. + For example, it can be helpful while using placeholders like `[+size.width+]`. + See more info and examples in README.md. + + ## Version 0.51 (2021-11-08) * \+ `\DDTools\ObjectTools::convertType`: Added the ability to return `stringQueryFormated`. diff --git a/CHANGELOG_ru.md b/CHANGELOG_ru.md index d2b8fb1..7f6fbe9 100644 --- a/CHANGELOG_ru.md +++ b/CHANGELOG_ru.md @@ -1,6 +1,13 @@ # (MODX)EvolutionCMS.libraries.ddTools changelog +## Версия 0.52 (2021-11-16) +* \+ `\DDTools\ObjectTools::unfold`: Новый метод. + Преобразует многомерный массив в одномерный, при этом ключи результирующего массива сливаются через `$params->keySeparator`. + Например, это может быть полезно при необходимости использования «вложенных плэйсхолдеров» (`[+size.width+]`). + См. больше информации и примеров в README.md. + + ## Версия 0.51 (2021-11-08) * \+ `\DDTools\ObjectTools::convertType`: Добавлена возможность конвертировать в `stringQueryFormated`. diff --git a/README.md b/README.md index 40d3350..82b97ff 100644 --- a/README.md +++ b/README.md @@ -405,6 +405,45 @@ Merge the contents of two or more objects or arrays together into the first one. * Default value: `true` +##### `\DDTools\ObjectTools::unfold($params)` + +Converts a multidimensional array/object into an one-dimensional one joining the keys with `$params->keySeparator`. +For example, it can be helpful while using placeholders like `[+size.width+]`. + +* `$params` + * Desctription: Parameters, the pass-by-name style is used. + * Valid values: + * `stdClass` + * `arrayAssociative` + * **Required** + +* `$params->object` + * Desctription: An object/array to convert. + * Valid values: + * `stdClass` + * `arrayAssociative` + * **Required** + +* `$params->keySeparator` + * Desctription: Separator between nested keys in the result object/array. + * Valid values: `string` + * Default value: `'.'` + +* `$params->keyPrefix` + * Desctription: Prefix of the keys of an object/array (it's an internal varible, but can be used if required). + * Valid values: `string` + * Default value: `''` + + +###### Returns + +* `$result` + * Desctription: Unfolded object/array. Type of results depends on `$params->object`. + * Valid values: + * `stdClass` + * `array` + + #### `\DDTools\BaseClass` Simple class with some small methods facilitating your work. @@ -975,6 +1014,94 @@ stdClass::__set_state(array( ``` +#### `\DDTools\ObjectTools::unfold($params)` + + +##### Unfold an object + +```php +var_export(\DDTools\ObjectTools::unfold([ + 'object' => (object) [ + 'name' => 'Elon Musk', + 'address' => (object) [ + 'line1' => '3500 Deer Creek Road', + 'city' => 'Palo Alto', + 'state' => 'California', + 'country' => 'United States' + ] + ] +])); +``` + +Returns: + +```php +stdClass::__set_state(array ( + 'name' => 'Elon Musk', + 'address.line1' => '3500 Deer Creek Road', + 'address.city' => 'Palo Alto', + 'address.state' => 'California', + 'address.country' => 'United States' +)) +``` + + +##### Unfold an array + +```php +var_export(\DDTools\ObjectTools::unfold([ + 'object' => [ + 'a' => 'a val', + 'b' => [ + 'b1' => 'b1 val', + 'b2' => [ + 'b21' => 'b21 val', + 'b22' => 'b22 val' + ] + ], + 'c' => 'c val' + ] +])); +``` + +Returns: + +```php +array ( + 'a' => 'a val', + 'b.b1' => 'b1 val', + 'b.b2.b21' => 'b21 val', + 'b.b2.b22' => 'b22 val', + 'c' => 'c val' +) +``` + + +##### Use custom key separator + +```php +var_export(\DDTools\ObjectTools::unfold([ + 'object' => [ + 'name' => 'Elon Musk', + 'parents' => [ + 'mother' => 'Maye Musk', + 'father' => 'Errol Musk' + ] + ], + 'keySeparator' => '_' +])); +``` + +Returns: + +```php +stdClass::__set_state(array ( + 'name' => 'Elon Musk', + 'parents_mother' => 'Maye Musk', + 'parents_father' => 'Errol Musk' +)) + + #### `\DDTools\ObjectTools::isPropExists($params)` Checks if the object, class or array has a property / element using the same syntax. diff --git a/composer.json b/composer.json index 9841f38..539b5f6 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "dd/evolutioncms-libraries-ddtools", "type": "modxevo-library-ddtools", - "version": "0.51.0", + "version": "0.52.0", "description": "A library with various tools facilitating your work.", "keywords": [ "modx", diff --git a/modx.ddtools.class.php b/modx.ddtools.class.php index 7932d98..d0adfc5 100644 --- a/modx.ddtools.class.php +++ b/modx.ddtools.class.php @@ -1,7 +1,7 @@ 'a val', - * 'b' => [ - * 'b1' => 'b1 val', - * 'b2' => [ - * 'b21' => 'b2.1 val', - * 'b22' => 'b2.2 val' - * ] - * ], - * 'c' => 'c val' - * ] turns into [ - * 'a' => 'a val', - * 'b.b1' => 'b1 val', - * 'b.b2.b21' => 'b2.1 val', - * 'b.b2.b22' => 'b2.2 val', - * 'c' => 'c val' - * ]. - * - * @param $array {array} — An array to convert. @required - * @param $keyPrefix {string} — Prefix of the keys of an array (it's an internal varible, can be used if required). Default: ''. - * - * @return {array} — Unfolded array. - */ - public static function unfoldArray( - $array, - $keyPrefix = '' - ){ - $result = []; - - //Перебираем массив - foreach ( - $array as - $key => - $val - ){ - //Если значение является массивом - if (is_array($val)){ - //Запускаем рекурсию дальше - $result = array_merge( - $result, - self::unfoldArray( - $val, - $keyPrefix . $key . '.' - ) - ); - //Если значение — не массив - }else{ - //Запоминаем (в соответствии с ключом родителя) - $result[$keyPrefix . $key] = $val; - } - } - - return $result; - } - /** * sort2dArray * @version 1.2.1 (2021-03-09) @@ -529,56 +469,6 @@ public static function parseFileNameVersion($file){ return $result; } - /** - * createDir - * @version 1.0 (2019-10-22) - * - * @desc Makes directory using `$modx->config['new_folder_permissions']`. Nested directories will be created too. Doesn't throw an exception if the folder already exists. - * - * @param $params {stdClass|arrayAssociative} — Parameters, the pass-by-name style is used. @required - * @param $params->path {string} — The directory path. @required - * - * @return {boolean} — Success status. - */ - public static function createDir($params){ - return \DDTools\FilesTools::createDir($params); - } - - /** - * copyDir - * @version 1.1 (2018-10-02) - * - * @desc Copies a required folder with all contents recursively. - * - * @param $sourcePath {string} — Path to the directory, that should copied. @required - * @param $destinationPath {string} — The destination path. @required - * - * @return {boolean} — Returns true on success or false on failure. - */ - public static function copyDir( - $sourcePath, - $destinationPath - ){ - return \DDTools\FilesTools::copyDir([ - 'sourcePath' => $sourcePath, - 'destinationPath' => $destinationPath - ]); - } - - /** - * removeDir - * @version 1.1 (2018-10-02) - * - * @desc Removes a required folder with all contents recursively. - * - * @param $path {string} — Path to the directory, that should removed. @required - * - * @return {boolean} - */ - public static function removeDir($path){ - return \DDTools\FilesTools::removeDir($path); - } - /** * generateRandomString * @version 1.0.3 (2018-06-17) @@ -2872,6 +2762,72 @@ public static function getResponse(){ return new \DDTools\Response(); } + /** + * unfoldArray + * @version 1.1 (2021-11-16) + * + * @see README.md (\DDTools\ObjectTools::unfold) + */ + public static function unfoldArray( + $array, + $keyPrefix = '' + ){ + return \DDTools\ObjectTools::unfold([ + 'object' => $array, + 'keyPrefix' => $keyPrefix + ]); + } + + /** + * createDir + * @version 1.0 (2019-10-22) + * + * @desc Makes directory using `$modx->config['new_folder_permissions']`. Nested directories will be created too. Doesn't throw an exception if the folder already exists. + * + * @param $params {stdClass|arrayAssociative} — Parameters, the pass-by-name style is used. @required + * @param $params->path {string} — The directory path. @required + * + * @return {boolean} — Success status. + */ + public static function createDir($params){ + return \DDTools\FilesTools::createDir($params); + } + + /** + * copyDir + * @version 1.1 (2018-10-02) + * + * @desc Copies a required folder with all contents recursively. + * + * @param $sourcePath {string} — Path to the directory, that should copied. @required + * @param $destinationPath {string} — The destination path. @required + * + * @return {boolean} — Returns true on success or false on failure. + */ + public static function copyDir( + $sourcePath, + $destinationPath + ){ + return \DDTools\FilesTools::copyDir([ + 'sourcePath' => $sourcePath, + 'destinationPath' => $destinationPath + ]); + } + + /** + * removeDir + * @version 1.1 (2018-10-02) + * + * @desc Removes a required folder with all contents recursively. + * + * @param $path {string} — Path to the directory, that should removed. @required + * + * @return {boolean} + */ + public static function removeDir($path){ + return \DDTools\FilesTools::removeDir($path); + } + /** * screening * @deprecated Use ddTools::escapeForJS. diff --git a/src/ObjectTools/ObjectTools.php b/src/ObjectTools/ObjectTools.php index d8563e7..38ec36c 100644 --- a/src/ObjectTools/ObjectTools.php +++ b/src/ObjectTools/ObjectTools.php @@ -361,4 +361,87 @@ public static function extend($params){ return $result; } + + /** + * unfold + * @version 1.1 (2021-11-17) + * + * @see README.md + * + * @return {stdClass|array} + */ + public static function unfold($params){ + $params = self::extend([ + 'objects' => [ + //Defaults + (object) [ + 'keySeparator' => '.', + 'keyPrefix' => '', + //The internal parameter, should not be used outside. Used only in child calls of recursion. + 'isSourceObject' => null + ], + $params + ] + ]); + + //Array is used as base and it always be returned in child calls of recursion + $result = []; + + $isSourceObject = + //If it's the first call of recurson + is_null($params->isSourceObject) ? + //Use original type + is_object($params->object) : + //Use from parent call of recursion + $params->isSourceObject + ; + + //Iterate over source + foreach ( + $params->object as + $key => + $value + ){ + //If the value must be unfolded + if ( + ( + $isSourceObject && + is_object($value) + ) || + ( + !$isSourceObject && + is_array($value) + ) + ){ + $result = array_merge( + $result, + self::unfold([ + 'object' => $value, + 'keyPrefix' => + $params->keyPrefix . + $key . + $params->keySeparator + , + 'isSourceObject' => $isSourceObject + ]) + ); + //Если значение — не массив + }else{ + //Запоминаем (в соответствии с ключом родителя) + $result[$params->keyPrefix . $key] = $value; + } + } + + if ( + //If it's first call of recurson + is_null($params->isSourceObject) && + //And the final result must be an object + $isSourceObject + ){ + //Only the first call of recursion can return an object + $result = (object) $result; + } + + return $result; + } } \ No newline at end of file