diff --git a/CHANGELOG.md b/CHANGELOG.md index a275cb9..b3a90ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # (MODX)EvolutionCMS.libraries.ddTools changelog +## Version 0.56 (2023-01-29) +* \+ `\ddTools::sort2dArray` → Parameters → `$array[$i]`: Can also be set as object. +* \* `\DDTools\Base\Base`: + * \* The class has been renamed from `\DDTools\BaseClass`. Backward compatibility is maintained (you can still use `\DDTools\BaseClass`, but it is not recommended). + * \* The class has become abstract. + * \- `createChildInstance`: The method has been removed, use `\DDTools\Base\AncestorTrait::createChildInstance` instead. Backward compatibility is maintained (you can still use `\DDTools\BaseClass::createChildInstance`, but it is not recommended). + * \+ `toJSON`: Returns JSON-array if `$this->toArray` returns indexed array. +* \+ `\DDTools\Base\AncestorTrait`: The new trait. +* \+ `\DDTools\ObjectCollection`: + * \+ `toJSON`, `__toString`: The new public methods. Get an JSON-array of all collection items. + * \+ `\DDTools\ObjectCollection::setOneItemData`, `getOneItemData`: The new protected methods. + + ## Version 0.55.1 (2022-12-03) * \* `\DDTools\FilesTools::modifyImage`: Included PHP.libraries.phpThumb has been updated from 1.7.15-202004301145 to 1.7.19-202210110924 (now supports WebP, PHP8, etc). diff --git a/CHANGELOG_ru.md b/CHANGELOG_ru.md index 6ec0653..cb625b7 100644 --- a/CHANGELOG_ru.md +++ b/CHANGELOG_ru.md @@ -1,6 +1,19 @@ # (MODX)EvolutionCMS.libraries.ddTools changelog +## Версия 0.56 (2023-01-29) +* \+ `\ddTools::sort2dArray` → Параметры → `$array[$i]`: Также может быть задан, как объект. +* \* `\DDTools\Base\Base`: + * \* Класс переименован из `\DDTools\BaseClass`. Обратная совместимость сохранена (множно использовать `\DDTools\BaseClass`, но не рекомендуется). + * \* Класс стал абстрактным. + * \- `createChildInstance`: Метод удалён, используйте вместо него `\DDTools\Base\AncestorTrait::createChildInstance`. Обратная совместимость сохранена (можно использовать `\DDTools\BaseClass::createChildInstance`, но не рекомендуется). + * \+ `toJSON`: Возвращает JSON-массив если `$this->toArray` возвращает индексированный массив. +* \+ `\DDTools\Base\AncestorTrait`: Новый trait. +* \+ `\DDTools\ObjectCollection`: + * \+ `toJSON`, `__toString`: Новые публичные методы. Возвращают JSON-массив всех элементов коллекции. + * \+ `\DDTools\ObjectCollection::setOneItemData`, `getOneItemData`: Новые protected методы. + + ## Версия 0.55.1 (2022-12-03) * \* `\DDTools\FilesTools::modifyImage`: PHP.libraries.phpThumb, включённая в репозиторий, обновлена с 1.7.15-202004301145 до 1.7.19-202210110924 (теперь поддерживает WebP, PHP8, etc). diff --git a/README.md b/README.md index 2ca61c5..308ad4c 100644 --- a/README.md +++ b/README.md @@ -760,15 +760,81 @@ Deletes required items from collection. * Default value: `0` -### `\DDTools\BaseClass` +#### `\DDTools\ObjectCollection::toJSON()`, `\DDTools\ObjectCollection::__toString()` -Simple class with some small methods facilitating your work. +Gets an JSON-array of all collection items. + + +##### Returns + +* `$result` + * Desctription: An JSON-array of items. + * Valid values: `stringJsonArray` + + +#### `\DDTools\ObjectCollection::setOneItemData` (protected) + +Sets data of an item object. All setting of an item data inside the class must be use this method. +It's convenient to override this method in child classes if items are not plain objects. + +* `$params` + * Desctription: Parameters, the pass-by-name style is used. + * Valid values: + * `stdClass` + * `arrayAssociative` + * **Required** + +* `$params->itemIndex` + * Desctription: Item index which data will be set. + * Valid values: `integer` + * **Required** + +* `$params->itemData` + * Desctription: New item data. + * Valid values: + * `array` — indexed arrays are supported as well as associative + * `object` + * **Required** + + +#### `\DDTools\ObjectCollection::getOneItemData` (protected) + +Returns data of an item object. All getting of an item data inside the class must use this method. +It's convenient to override this method in child classes if items are not plain objects. + +* `$params` + * Desctription: Parameters, the pass-by-name style is used. + * Valid values: + * `stdClass` + * `arrayAssociative` + * **Required** + +* `$params->itemObject` + * Desctription: An item object which data will be returned. + * Valid values: + * `array` — indexed arrays are supported as well as associative + * `object` + * **Required** + + +##### Returns + +* `$result` + * Desctription: Data of an item object. + * Valid values: + * `array` + * `object` + + +### `\DDTools\Base\Base` + +Simple abstract class with some small methods facilitating your work. It is convenient to inherit your classes from this. You can see an example of how it works in the [(MODX)EvolutionCMS.snippets.ddGetDocumentField](https://code.divandesign.biz/modx/ddgetdocumentfield) code. -#### `\DDTools\BaseClass::setExistingProps($props)` +#### `\DDTools\Base\Base::setExistingProps($props)` Sets existing object properties. @@ -791,7 +857,7 @@ Sets existing object properties. * **Required** -#### `\DDTools\BaseClass::toArray()` +#### `\DDTools\Base\Base::toArray()` Returns all properties of this object as an associative array independent of their visibility. @@ -808,7 +874,7 @@ Returns all properties of this object as an associative array independent of the * Valid values: `mixed` -#### `\DDTools\BaseClass::toJSON()` +#### `\DDTools\Base\Base::toJSON()` Returns all properties of this object as an JSON string independent of their visibility. @@ -818,19 +884,28 @@ Returns all properties of this object as an JSON string independent of their vis * `$result` * Desctription: An JSON string representation of this object. The method returns all existing properties: public, private and protected. - * Valid values: `stringJsonObject` + * Valid values: + * `stringJsonObject` + * `stringJsonArray` — if `$this->toArray` returns indexed array * `$result->{$propName}` * Desctription: The key is the object field name and the value is the object field value. * Valid values: `mixed` -#### `\DDTools\BaseClass::__toString()` +#### `\DDTools\Base\Base::__toString()` + +The same as `\DDTools\Base\Base::toJSON()`. + -The same as `\DDTools\BaseClass::toJSON()`. +### `\DDTools\Base\AncestorTrait` + +Simple trait for ancestors with some small methods facilitating your work. + +You can see an example of how it works in the [(MODX)EvolutionCMS.snippets.ddGetDocumentField](https://code.divandesign.biz/modx/ddgetdocumentfield) code. -#### `\DDTools\BaseClass::createChildInstance($params)` +#### `\DDTools\Base\AncestorTrait::createChildInstance($params)` * `$params` * Desctription: Parameters, the pass-by-name style is used. diff --git a/composer.json b/composer.json index d1caacc..2bb3bd4 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "dd/evolutioncms-libraries-ddtools", "type": "modxevo-library-ddtools", - "version": "0.55.1", + "version": "0.56.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 95a8703..87ada1b 100644 --- a/modx.ddtools.class.php +++ b/modx.ddtools.class.php @@ -1,11 +1,11 @@ array_values($array)[0], + 'propName' => $sortBy[$i] + ]); + $isCurrentItemComparisonValueNumeric = is_numeric($currentItem_comparisonValue); $isArrayAssociative = count(array_filter( @@ -324,20 +328,25 @@ public static function sort2dArray( //Перебираем массив foreach ( $array as - $rowKey => - $rowValue + $arrayItemKey => + $arrayItem ){ + $arrayItem_comparisonValue = \DDTools\ObjectTools::getPropValue([ + 'object' => $arrayItem, + 'propName' => $sortBy[$i] + ]); + //Если эталон и текущее значение — числа if ( - $isCurrentRowNumeric && - is_numeric($rowValue[$sortBy[$i]]) + $isCurrentItemComparisonValueNumeric && + is_numeric($arrayItem_comparisonValue) ){ //Получаем нужную циферку $cmpRes = - $rowValue[$sortBy[$i]] == $currentRow ? + $arrayItem_comparisonValue == $currentItem_comparisonValue ? 0 : ( - $rowValue[$sortBy[$i]] > $currentRow ? + $arrayItem_comparisonValue > $currentItem_comparisonValue ? 1 : -1 ) @@ -346,8 +355,8 @@ public static function sort2dArray( }else{ //Сравниваем текущее значение со значением эталонного $cmpRes = strcmp( - $rowValue[$sortBy[$i]], - $currentRow + $arrayItem_comparisonValue, + $currentItem_comparisonValue ); } @@ -363,9 +372,9 @@ public static function sort2dArray( } if ($isArrayAssociative){ - $resultArray[$rowKey] = $rowValue; + $resultArray[$arrayItemKey] = $arrayItem; }else{ - $resultArray[] = $rowValue; + $resultArray[] = $arrayItem; } } diff --git a/require.php b/require.php index ba46219..c64e503 100644 --- a/require.php +++ b/require.php @@ -1,5 +1,8 @@ [], + 'capitalizeName' => true + ], + (array) $params + ); + + $thisClassName = get_called_class(); + + $thisNameSpace = substr( + $thisClassName, + 0, + strrpos( + $thisClassName, + '\\' + ) + ); + + //Current classname without namespace + $thisClassName = substr( + $thisClassName, + strrpos( + $thisClassName, + '\\' + ) + 1 + ); + + //Capitalize child name if needed + if ($params->capitalizeName){ + $params->name = ucfirst(strtolower($params->name)); + } + + $filePath = + $params->parentDir . + DIRECTORY_SEPARATOR . + $params->name . + DIRECTORY_SEPARATOR . + $thisClassName . + '.php' + ; + + if(is_file($filePath)){ + require_once($filePath); + + $objectClass = + '\\' . + $thisNameSpace . + '\\' . + $params->name . + '\\' . + $thisClassName + ; + + return new $objectClass($params->params); + }else{ + throw new \Exception( + $thisClassName . ' “' . $params->name . '” not found.', + 500 + ); + } + } +} \ No newline at end of file diff --git a/src/BaseClass/BaseClass.php b/src/Base/Base.php similarity index 72% rename from src/BaseClass/BaseClass.php rename to src/Base/Base.php index ffe4a49..8f60c05 100644 --- a/src/BaseClass/BaseClass.php +++ b/src/Base/Base.php @@ -1,7 +1,7 @@ [], - 'capitalizeName' => true - ], - (array) $params - ); - - $thisClassName = get_called_class(); - - $thisNameSpace = substr( - $thisClassName, - 0, - strrpos( - $thisClassName, - '\\' - ) - ); - - //Current classname without namespace - $thisClassName = substr( - $thisClassName, - strrpos( - $thisClassName, - '\\' - ) + 1 - ); - - //Capitalize child name if needed - if ($params->capitalizeName){ - $params->name = ucfirst(strtolower($params->name)); - } - - $filePath = - $params->parentDir . - DIRECTORY_SEPARATOR . - $params->name . - DIRECTORY_SEPARATOR . - $thisClassName . - '.php' - ; - - if(is_file($filePath)){ - require_once($filePath); - - $objectClass = - '\\' . - $thisNameSpace . - '\\' . - $params->name . - '\\' . - $thisClassName - ; - - return new $objectClass($params->params); - }else{ - throw new \Exception( - $thisClassName . ' “' . $params->name . '” not found.', - 500 - ); - } - } - /** * toArray * @version 1.0 (2020-05-06) @@ -216,7 +143,7 @@ public function toArray(){ /** * toJSON - * @version 1.0.1 (2021-03-10) + * @version 1.1 (2022-12-26) * * @see README.md * @@ -225,7 +152,7 @@ public function toArray(){ public function toJSON(){ return \DDTools\ObjectTools::convertType([ 'object' => $this->toArray(), - 'type' => 'stringJsonObject' + 'type' => 'stringJsonAuto' ]); } diff --git a/src/Base/BaseClass.php b/src/Base/BaseClass.php new file mode 100644 index 0000000..b41feb3 --- /dev/null +++ b/src/Base/BaseClass.php @@ -0,0 +1,7 @@ +isItemMatchFilter([ - 'item' => $itemObject, + 'itemObject' => $itemObject, 'filter' => $params->filter ]) ){ - $this->items[$itemIndex] = \DDTools\ObjectTools::convertType([ - 'object' => $itemObject, - 'type' => $params->itemType + $this->setOneItemData([ + 'itemIndex' => $itemIndex, + 'itemData' => \DDTools\ObjectTools::convertType([ + 'object' => $this->getOneItemData([ + 'itemObject' => $itemObject + ]), + 'type' => $params->itemType + ]) ]); } } @@ -133,7 +138,7 @@ public function convertItemsType($params = []){ /** * updateItems - * @version 1.0 (2021-12-02) + * @version 1.0.2 (2022-12-28) * * @see README.md */ @@ -165,15 +170,20 @@ public function updateItems($params = []){ if ( //If item is matched to filter $this->isItemMatchFilter([ - 'item' => $itemObject, + 'itemObject' => $itemObject, 'filter' => $params->filter ]) ){ - $this->items[$itemIndex] = \DDTools\ObjectTools::extend([ - 'objects' => [ - $itemObject, - $params->data - ] + $this->setOneItemData([ + 'itemIndex' => $itemIndex, + 'itemData' => \DDTools\ObjectTools::extend([ + 'objects' => [ + $this->getOneItemData([ + 'itemObject' => $itemObject + ]), + $params->data + ] + ]) ]); //Increment result count @@ -190,7 +200,7 @@ public function updateItems($params = []){ /** * getItems - * @version 2.0 (2021-12-02) + * @version 2.0.2 (2022-12-28) * * @see README.md */ @@ -224,14 +234,18 @@ public function getItems($params = []){ if ( //If item is matched to filter $this->isItemMatchFilter([ - 'item' => $itemObject, + 'itemObject' => $itemObject, 'filter' => $params->filter ]) ){ + $itemData = $this->getOneItemData([ + 'itemObject' => $itemObject + ]); + //Save only field value instead of object if needed if (!is_null($params->propAsResultValue)){ $resultItemObject = \DDTools\ObjectTools::getPropValue([ - 'object' => $itemObject, + 'object' => $itemData, 'propName' => $params->propAsResultValue ]); }else{ @@ -242,7 +256,7 @@ public function getItems($params = []){ if (!is_null($params->propAsResultKey)){ $result[ \DDTools\ObjectTools::getPropValue([ - 'object' => $itemObject, + 'object' => $itemData, 'propName' => $params->propAsResultKey ]) ] = $resultItemObject; @@ -301,7 +315,7 @@ public function getOneItem($params = []){ /** * deleteItems - * @version 1.0 (2021-12-02) + * @version 1.0.1 (2022-12-28) * * @see README.md */ @@ -332,7 +346,7 @@ public function deleteItems($params = []){ if ( //If item is matched to filter $this->isItemMatchFilter([ - 'item' => $itemObject, + 'itemObject' => $itemObject, 'filter' => $params->filter ]) ){ @@ -354,12 +368,47 @@ public function deleteItems($params = []){ } } + /** + * setOneItemData + * @version 1.0 (2022-12-27) + * + * @desc Sets data of an item object. All setting of an item data inside the class must be use this method. It's convenient to override this method in child classes if items are not plain objects. + * + * @param $params {stdClass|arrayAssociative} — Parameters, the pass-by-name style is used. @required + * @param $params->itemIndex {integer} — Item index which data will be set. @required + * @param $params->itemData {array|object} — New item data. @required + * + * @return {void} + */ + protected function setOneItemData($params){ + $params = (object) $params; + + $this->items[$params->itemIndex] = $params->itemData; + } + + /** + * getOneItemData + * @version 1.0 (2022-12-27) + * + * @desc Returns data of an item object. All getting of an item data inside the class must use this method. It's convenient to override this method in child classes if items are not plain objects. + * + * @param $params {stdClass|arrayAssociative} — Parameters, the pass-by-name style is used. @required + * @param $params->itemObject {array|object} — An item object which data will be returned. @required + * + * @return $result {object|arrayAssociative} + */ + protected function getOneItemData($params){ + $params = (object) $params; + + return $params->itemObject; + } + /** * isItemMatchFilter - * @version 1.0 (2021-12-01) + * @version 2.0.1 (2022-12-28) * - * @param $params {array} — Parameters, the pass-by-name style is used. @required - * @param $params->item {array|object} — An item to test. @required + * @param $params {stdClass|arrayAssociative} — Parameters, the pass-by-name style is used. @required + * @param $params->itemObject {array|object} — An item to test. @required * @param $params->filter {array} — Result of $this->prepareItemsFilter. @required * * @return $result {boolean} @@ -370,6 +419,10 @@ private function isItemMatchFilter($params){ //By default assume that item is matched $result = true; + $itemData = $this->getOneItemData([ + 'itemObject' => $params->itemObject + ]); + //Iterate over “or” conditions foreach ( $params->filter as @@ -383,7 +436,7 @@ private function isItemMatchFilter($params){ //If the item has no the property if ( !\DDTools\ObjectTools::isPropExists([ - 'object' => $params->item, + 'object' => $itemData, 'propName' => $andCondition->propName ]) ){ @@ -395,7 +448,7 @@ private function isItemMatchFilter($params){ }elseif ($andCondition->operator == '=='){ $result = \DDTools\ObjectTools::getPropValue([ - 'object' => $params->item, + 'object' => $itemData, 'propName' => $andCondition->propName ]) == $andCondition->propValue @@ -404,7 +457,7 @@ private function isItemMatchFilter($params){ }else{ $result = \DDTools\ObjectTools::getPropValue([ - 'object' => $params->item, + 'object' => $itemData, 'propName' => $andCondition->propName ]) != $andCondition->propValue @@ -536,5 +589,15 @@ private function prepareItemsFilter($filter = ''){ public function count(){ return count($this->items); } + + /** + * toArray + * @version 1.0 (2022-12-26) + * + * @desc Simple implementation of $this->getItems. Used for correct working of $this->toJSON, $this->__toString. + */ + public function toArray(){ + return $this->items; + } } ?> \ No newline at end of file