20250203
This commit is contained in:
		
							
								
								
									
										363
									
								
								sources/classes/ActionState.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										363
									
								
								sources/classes/ActionState.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,363 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Отключаем ненужные проверки. | ||||
|  * | ||||
|  * @noinspection PhpUnusedParameterInspection, PhpUnused | ||||
|  */ | ||||
|  | ||||
| namespace goodboyalex\php_components_pack\classes; | ||||
|  | ||||
| use Closure; | ||||
| use goodboyalex\php_components_pack\enums\MessageType; | ||||
| use goodboyalex\php_components_pack\interfaces\ISerializable; | ||||
| use goodboyalex\php_components_pack\models\ActionStateMessageModel; | ||||
|  | ||||
| /** | ||||
|  * Состояние действия. | ||||
|  * | ||||
|  * @author Александр Бабаев | ||||
|  * @package php_components_pack | ||||
|  * @version 1.0 | ||||
|  * @since 1.0 | ||||
|  */ | ||||
| final class ActionState implements ISerializable | ||||
| { | ||||
|     /** | ||||
|      * @var mixed|null $Value Значение | ||||
|      */ | ||||
|     public mixed $Value; | ||||
|  | ||||
|     /** | ||||
|      * @var array $Messages Список информации | ||||
|      */ | ||||
|     private array $Messages = []; | ||||
|  | ||||
|     /** | ||||
|      * Конструктор | ||||
|      * | ||||
|      * @param mixed|null $defValue Значение по умолчанию | ||||
|      */ | ||||
|     public function __construct (mixed $defValue = null) | ||||
|     { | ||||
|         $this->Value = $defValue; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * При выводе GetStringMessages выводит только ошибки. | ||||
|      * | ||||
|      * @return Closure Возвращает функцию, проверяющую сообщение на соответствие типу. | ||||
|      */ | ||||
|     public static function GET_STRING_ERROR_ONLY (): Closure | ||||
|     { | ||||
|         return fn (ActionStateMessageModel $message) | ||||
|             => $message->MessageType === MessageType::Error; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * При выводе GetStringMessages выводит ошибки и предупреждения. | ||||
|      * | ||||
|      * @return Closure Возвращает функцию, проверяющую сообщение на соответствие типу. | ||||
|      */ | ||||
|     public static function GET_STRING_ERROR_AND_WARNING (): Closure | ||||
|     { | ||||
|         return fn (ActionStateMessageModel $message) | ||||
|             => $message->MessageType === MessageType::Error | ||||
|             || $message->MessageType === MessageType::Warning; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * При выводе GetStringMessages выводит все сообщения. | ||||
|      * | ||||
|      * @return Closure Возвращает функцию, проверяющую сообщение на соответствие типу. | ||||
|      */ | ||||
|     public static function GET_STRING_ALL (): Closure | ||||
|     { | ||||
|         return fn (ActionStateMessageModel $message) => true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Добавляет данные из другого состояния. | ||||
|      * | ||||
|      * @param ActionState $state Другое состояние | ||||
|      * @param bool $clearAllBefore Очищать сообщения перед добавлением (true) или просто добавить к текущим (false) | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function AddState (ActionState $state, bool $clearAllBefore = false): void | ||||
|     { | ||||
|         // Если нужно очистить список сообщений | ||||
|         if ($clearAllBefore) | ||||
|             // - то очищаю список сообщений | ||||
|             $this->Clear(fn (ActionStateMessageModel $message) => true); | ||||
|  | ||||
|         // Добавляю сообщения из другого состояния | ||||
|         $this->AddRange($state->GetMessages(function (ActionStateMessageModel $message) | ||||
|         { | ||||
|             return true; | ||||
|         })); | ||||
|  | ||||
|         // Добавляю значение | ||||
|         $this->Value = $state->Value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Очищает список сообщений, согласно условию. | ||||
|      * | ||||
|      * @param callable $predicate Условие выборки | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function Clear (callable $predicate): void | ||||
|     { | ||||
|         // Выбираю все сообщения, удовлетворяющие условию | ||||
|         $list = $this->GetMessages($predicate); | ||||
|  | ||||
|         // Удаляю их из списка | ||||
|         $this->Messages = array_diff($this->Messages, $list); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Выбирает сообщения по условию predicate. | ||||
|      * | ||||
|      * @param callable $predicate Условие выборки | ||||
|      * | ||||
|      * @return array Список отобранных сообщений | ||||
|      */ | ||||
|     public function GetMessages (callable $predicate): array | ||||
|     { | ||||
|         // Получаю список элементов | ||||
|         $list = []; | ||||
|  | ||||
|         // Для каждого элемента | ||||
|         foreach ($this->Messages as $actionStateMessage) | ||||
|             // - если он подходит под условие | ||||
|             if ($predicate($actionStateMessage)) | ||||
|                 // - добавляю его в список | ||||
|                 $list[] = $actionStateMessage; | ||||
|  | ||||
|         // Возвращаю список | ||||
|         return $list; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Добавляет список | ||||
|      * | ||||
|      * @param array $messages Список сообщений | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function AddRange (array $messages): void | ||||
|     { | ||||
|         $this->Messages = array_merge($this->Messages, $messages); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Возвращает список сообщений (параметр Message у каждого сообщения). | ||||
|      * | ||||
|      * @param callable $predicate Условие выборки | ||||
|      * @param string $separator Разделитель | ||||
|      * | ||||
|      * @return string Список сообщений | ||||
|      */ | ||||
|     public function GetStringMessages (callable $predicate, string $separator = '\n'): string | ||||
|     { | ||||
|         // Делаю выборку | ||||
|         $list = $this->GetMessages($predicate); | ||||
|  | ||||
|         // Формирую список сообщений | ||||
|         $result = []; | ||||
|  | ||||
|         // Для каждого сообщения из выборки | ||||
|         foreach ($list as $message) { | ||||
|             // - если оно не нужного нам класса | ||||
|             if (!$message instanceof ActionStateMessageModel) | ||||
|                 // -- то пропускаю | ||||
|                 continue; | ||||
|  | ||||
|             // - добавляю сообщение | ||||
|             $result[] = $message->Message; | ||||
|         } | ||||
|  | ||||
|         // Возвращаю список | ||||
|         return implode($separator, $result); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Добавляет сообщение о критической ошибке. | ||||
|      * | ||||
|      * @param string $message Сообщение | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function AddCritical (string $message): void | ||||
|     { | ||||
|         $this->Add(new ActionStateMessageModel(MessageType::Error, true, $message)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Добавление сообщения. | ||||
|      * | ||||
|      * @param ActionStateMessageModel $message Сообщение | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function Add (ActionStateMessageModel $message): void | ||||
|     { | ||||
|         $this->Messages[] = $message; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Добавляет сообщение об ошибке. | ||||
|      * | ||||
|      * @param string $message Сообщение | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function AddError (string $message): void | ||||
|     { | ||||
|         $this->Add(new ActionStateMessageModel(MessageType::Error, false, $message)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Добавляет предупреждение. | ||||
|      * | ||||
|      * @param string $message Сообщение. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function AddWarning (string $message): void | ||||
|     { | ||||
|         $this->Add(new ActionStateMessageModel(MessageType::Warning, false, $message)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Добавляет информационное сообщение. | ||||
|      * | ||||
|      * @param string $message Сообщение. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function AddInfo (string $message): void | ||||
|     { | ||||
|         $this->Add(new ActionStateMessageModel(MessageType::Info, false, $message)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Проверяет, есть ли информационные сообщения. | ||||
|      * | ||||
|      * @return bool Наличие сообщений | ||||
|      */ | ||||
|     public function HasInfos (): bool | ||||
|     { | ||||
|         return $this->Count(fn (ActionStateMessageModel $message) => $message->MessageType == MessageType::Info) > 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Количество сообщений, удовлетворяющих условию. | ||||
|      * | ||||
|      * @param callable $predicate Условие выборки | ||||
|      * | ||||
|      * @return int Число сообщений | ||||
|      */ | ||||
|     public function Count (callable $predicate): int | ||||
|     { | ||||
|         // Получаю список сообщений | ||||
|         $list = $this->GetMessages($predicate); | ||||
|  | ||||
|         // Возвращаю результат | ||||
|         return count($list); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Проверяет, успешно ли завершилась операция. | ||||
|      * | ||||
|      * @param bool $onlyCritical Игнорировать все некритические ошибки и предупреждения (не рекомендуется!) | ||||
|      * | ||||
|      * @return bool Успешно ли завершилась операция. | ||||
|      */ | ||||
|     public function IsSuccess (bool $onlyCritical = false): bool | ||||
|     { | ||||
|         // Если нужно учитывать только критические ошибки | ||||
|         if ($onlyCritical) | ||||
|             // - то проверяю наличие критических ошибок | ||||
|             return !$this->HasErrors($onlyCritical); | ||||
|  | ||||
|         // Возвращаю результат | ||||
|         return !$this->HasErrors() && !$this->HasWarnings(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Проверяет, есть ли ошибки. | ||||
|      * | ||||
|      * @param bool $onlyCritical Учитывать только критические ошибки. | ||||
|      * | ||||
|      * @return bool Наличие ошибок. | ||||
|      */ | ||||
|     public function HasErrors (bool $onlyCritical = false): bool | ||||
|     { | ||||
|         return $this->Count(function (ActionStateMessageModel $message) use ($onlyCritical): bool | ||||
|         { | ||||
|             // - сравниваю тип сообщения | ||||
|             if ($message->MessageType != MessageType::Error) | ||||
|                 // -- если не совпадает, то возвращаю false | ||||
|                 return false; | ||||
|  | ||||
|             // - если нужно выводить только критические ошибки, а сообщение не критическое | ||||
|             if ($onlyCritical && !$message->IsCritical) | ||||
|                 // -- то возвращаю false | ||||
|                 return false; | ||||
|  | ||||
|             // Возвращаю true | ||||
|             return true; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Проверяет, есть ли предупреждения. | ||||
|      * | ||||
|      * @return bool Наличие предупреждений | ||||
|      */ | ||||
|     public function HasWarnings (): bool | ||||
|     { | ||||
|         return $this->Count(fn (ActionStateMessageModel $message) => $message->MessageType == MessageType::Warning) > 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function Serialize (): string | ||||
|     { | ||||
|         // Создаю список сообщений | ||||
|         $list = []; | ||||
|  | ||||
|         // Для каждого сообщения | ||||
|         foreach ($this->Messages as $message) | ||||
|             // - сериализую его и добавляю в список | ||||
|             $list[] = $message->Serialize(); | ||||
|  | ||||
|         // Возвращаю результат | ||||
|         return serialize($list); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function UnSerialize (string $serialized): void | ||||
|     { | ||||
|         // Очищаю список сообщений | ||||
|         $this->Clear(fn (ActionStateMessageModel $message) => true); | ||||
|  | ||||
|         // Десериализую список сообщений | ||||
|         $list = unserialize($serialized); | ||||
|  | ||||
|         // Для каждого сообщения | ||||
|         foreach ($list as $messageSerialized) { | ||||
|             // - создаю новое сообщение | ||||
|             $message = new ActionStateMessageModel(); | ||||
|             // - десериализую его | ||||
|             $message->UnSerialize($messageSerialized); | ||||
|             // - добавляю в список | ||||
|             $this->Add($message); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										335
									
								
								sources/classes/ClassMapper.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								sources/classes/ClassMapper.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,335 @@ | ||||
| <?php | ||||
|  | ||||
| namespace goodboyalex\php_components_pack\classes; | ||||
|  | ||||
| use DateTimeImmutable; | ||||
| use DateTimeInterface; | ||||
| use Exception; | ||||
| use ReflectionClass; | ||||
| use ReflectionException; | ||||
| use stdClass; | ||||
| use UnitEnum; | ||||
|  | ||||
| /** | ||||
|  * Класс сопоставлений классов и объектов. | ||||
|  * | ||||
|  * @author Александр Бабаев | ||||
|  * @package php_components_pack | ||||
|  * @version 1.0 | ||||
|  * @since 1.0 | ||||
|  */ | ||||
| final class ClassMapper | ||||
| { | ||||
|     /** | ||||
|      * @var array $DefaultOptions Настройки | ||||
|      */ | ||||
|     public const array DefaultOptions = [ | ||||
|         'ignored' => [], | ||||
|         'allowed' => [] | ||||
|     ]; | ||||
|  | ||||
|     /** | ||||
|      * Передаёт одинаковые параметры из класса $from в класс $to, учитывая игнорируемые ($ignoredProperties) и | ||||
|      * разрешенные ($allowedProperties) свойства. | ||||
|      * | ||||
|      * @param object $from Класс-донор | ||||
|      * @param object $to Класс-приемник | ||||
|      * @param array $options Параметры привязки свойств (см атрибут Bind). | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public static function MapClass (object $from, object $to, array $options = self::DefaultOptions): void | ||||
|     { | ||||
|         // Если есть игнорируемые или разрешенные свойства | ||||
|         if (!(count($options['ignored']) == 0 && count($options['allowed']) == 0)) | ||||
|             // -- то для каждого игнорируемого свойства | ||||
|             foreach ($options['ignored'] as $ignoredProperty) | ||||
|                 // --- и если оно есть в массиве разрешенных | ||||
|                 if (in_array($ignoredProperty, $options['allowed'])) | ||||
|                     // ---- то исключаю его из массива разрешенных | ||||
|                     unset($options['allowed'][array_search($ignoredProperty, $options['allowed'])]); | ||||
|  | ||||
|         // Получаю массив свойств | ||||
|         $properties = get_class_vars(get_class($from)); | ||||
|  | ||||
|         // Для каждого элемента массива | ||||
|         foreach ($properties as $name => $value) { | ||||
|             // - если свойство игнорируется | ||||
|             if (in_array($name, $options['ignored'])) | ||||
|                 // -- пропускаю | ||||
|                 continue; | ||||
|  | ||||
|             // - если свойство не разрешено | ||||
|             if (count($options['allowed']) > 0 && !in_array($name, $options['allowed'])) | ||||
|                 // -- пропускаю | ||||
|                 continue; | ||||
|  | ||||
|             // - если свойство есть в объекте | ||||
|             if (property_exists($to, $name)) | ||||
|                 // -- то присваиваю значение | ||||
|                 $to->$name = $from->$name; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Подготавливает значения свойств класса. | ||||
|      * | ||||
|      * @param array $params Данные запроса. | ||||
|      * @param ReflectionClass $classReflector Анализатор класса. | ||||
|      * @param array $options Массив свойств привязки. | ||||
|      * | ||||
|      * @return array Массив данных класса. | ||||
|      */ | ||||
|     public static function PrepareClassProperties (array $params, ReflectionClass $classReflector, | ||||
|         array $options = self::DefaultOptions): array | ||||
|     { | ||||
|         // Создаю массив данных класса | ||||
|         $classData = []; | ||||
|  | ||||
|         // Для каждого свойства класса | ||||
|         foreach ($classReflector->getProperties() as $property) { | ||||
|             // - получаю имя свойства | ||||
|             $propertyName = $property->getName(); | ||||
|  | ||||
|             // - если это свойство задано в массиве параметров | ||||
|             if (array_key_exists($propertyName, $params)) { | ||||
|                 // -- если задан массив разрешённых свойств | ||||
|                 if (!empty($options["allowed"])) | ||||
|                     // --- если свойство не разрешено | ||||
|                     if (!in_array($propertyName, $options["allowed"])) | ||||
|                         // ---- то пропускаю | ||||
|                         continue; | ||||
|  | ||||
|                 // -- если задан массив запрещённых свойств | ||||
|                 if (!empty($options["ignored"])) | ||||
|                     // --- если свойство должно игнорироваться | ||||
|                     if (in_array($propertyName, $options["ignored"])) | ||||
|                         // ---- то пропускаю | ||||
|                         continue; | ||||
|  | ||||
|                 // -- добавляю значение свойства в результат | ||||
|                 $classData[$propertyName] = $params[$propertyName]; | ||||
|             } | ||||
|             else { | ||||
|                 // - в противном случае, пробегаю массив параметров | ||||
|                 foreach ($params as $key => $value) { | ||||
|                     // -- если в имени параметра есть разделитель "_" | ||||
|                     if (str_starts_with($key, $propertyName . "_")) { | ||||
|                         // -- разбиваю имя параметра на части | ||||
|                         $keyParts = explode("_", $key); | ||||
|  | ||||
|                         // -- добавляю значение свойства в результат | ||||
|                         self::GetClassParametersArrayParser($classData, $keyParts, $value); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Возвращаю массив данных класса | ||||
|         return $classData; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Парсит массив свойств класса. | ||||
|      * | ||||
|      * @param array $source Исходный массив (он же и результат парсинга). | ||||
|      * @param array $parametersKeys Массив имен свойств. Например, Page_Meta_Id должен быть разбит на | ||||
|      * ["Page", "Meta", "Id"]. | ||||
|      * @param mixed $value Значение свойства. | ||||
|      * @param array $options Массив параметров привязки свойств. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public static function GetClassParametersArrayParser (array &$source, array $parametersKeys, mixed $value, | ||||
|         array $options = self::DefaultOptions): void | ||||
|     { | ||||
|         // Если массив имен свойств пустой | ||||
|         if (empty($parametersKeys)) | ||||
|             // - то прерываю парсинг | ||||
|             return; | ||||
|  | ||||
|         // Получаю имя текущего свойства | ||||
|         $currentName = array_shift($parametersKeys); | ||||
|  | ||||
|         // Если текущего свойства нет в массиве | ||||
|         if (!isset($source[$currentName])) | ||||
|             // - то создаю его | ||||
|             $source[$currentName] = []; | ||||
|  | ||||
|         // Если массив имен свойств содержит только одно свойство | ||||
|         if (count($parametersKeys) === 0) { | ||||
|             // - если задан массив разрешённых свойств | ||||
|             if (!empty($options["allowed"])) | ||||
|                 // --- если свойство не разрешено | ||||
|                 if (!in_array($currentName, $options["allowed"])) | ||||
|                     // ---- то пропускаю | ||||
|                     return; | ||||
|  | ||||
|             // -- если задан массив запрещённых свойств | ||||
|             if (!empty($options["ignored"])) | ||||
|                 // --- если свойство должно игнорироваться | ||||
|                 if (in_array($currentName, $options["ignored"])) | ||||
|                     // ---- то пропускаю | ||||
|                     return; | ||||
|  | ||||
|             // - добавляю значение свойства в результат | ||||
|             $source[$currentName] = $value; | ||||
|         } | ||||
|         else | ||||
|             // - иначе продолжаю парсинг | ||||
|             self::GetClassParametersArrayParser($source[$currentName], $parametersKeys, $value, $options); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Переводит данные из массива в объект класса. | ||||
|      * | ||||
|      * @param string $className Имя класса | ||||
|      * @param array $properties Массив данных | ||||
|      * | ||||
|      * @return mixed Объект класса | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     public static function MapToClassProperty (string $className, array $properties): mixed | ||||
|     { | ||||
|         // Создаю | ||||
|         try { | ||||
|             $classReflector = new ReflectionClass($className); | ||||
|  | ||||
|             // Создаю объект класса | ||||
|             $classObj = new $className(); | ||||
|  | ||||
|             // Для каждого свойства класса | ||||
|             foreach ($properties as $key => $value) { | ||||
|                 // - проверяю наличие свойства | ||||
|                 if (!$classReflector->hasProperty($key)) | ||||
|                     // -- иду к следующему | ||||
|                     continue; | ||||
|  | ||||
|                 // - получаю данные про свойство | ||||
|                 // -- само свойство | ||||
|                 $property = $classReflector->getProperty($key); | ||||
|                 // -- тип свойства | ||||
|                 $propertyType = $property->getType(); | ||||
|  | ||||
|                 // - если значение является классом | ||||
|                 if (!$propertyType->isBuiltin() && is_array($value)) { | ||||
|                     // -- присваиваю объект | ||||
|                     self::SetParameterToClass($classReflector, $key, $classObj, | ||||
|                         self::MapToClassProperty($propertyType->getName(), $value)); | ||||
|  | ||||
|                     // -- следующий элемент | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 // - если значение является датой | ||||
|                 if ($classObj->$key instanceof DateTimeInterface) { | ||||
|                     // -- получаю дату | ||||
|                     $dateValue = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $value . " 00:00:00"); | ||||
|  | ||||
|                     // -- если не получилось | ||||
|                     if ($dateValue === false) | ||||
|                         // --- то добавляю дату по умолчанию (1970-01-01 00:00:00) | ||||
|                         $dateValue = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', "1970-01-01 00:00:00"); | ||||
|  | ||||
|                     // -- присваиваю дату | ||||
|                     self::SetParameterToClass($classReflector, $key, $classObj, $dateValue); | ||||
|  | ||||
|                     // -- следующий элемент | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 // - если значение является перечислением | ||||
|                 if ($classObj->$key instanceof UnitEnum) { | ||||
|                     // -- если значение уже является перечислением | ||||
|                     if ($value instanceof UnitEnum) | ||||
|                         // --- присваиваю перечисление | ||||
|                         self::SetParameterToClass($classReflector, $key, $classObj, $value); | ||||
|                     else | ||||
|                         // -- иначе | ||||
|                         self::SetParameterToClass($classReflector, $key, $classObj, | ||||
|                             is_numeric($value) ? $classObj->$key::FromInt($value) : $classObj->$key::FromName($value)); | ||||
|  | ||||
|                     // -- следующий элемент | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 // - если значение является NULL | ||||
|                 if ($value == "null") { | ||||
|                     // -- присваиваю NULL | ||||
|                     self::SetParameterToClass($classReflector, $key, $classObj, | ||||
|                         is_array($key) ? [] : null); | ||||
|  | ||||
|                     // -- следующий элемент | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 // - присваиваю значение | ||||
|                 self::SetParameterToClass($classReflector, $key, $classObj, $value); | ||||
|             } | ||||
|  | ||||
|             // Возвращаю объект класса | ||||
|             return $classObj; | ||||
|         } | ||||
|         catch (Exception $exception) { | ||||
|             throw new Exception($exception->getMessage()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Присваивает значение параметра объекту класса. | ||||
|      * | ||||
|      * @param ReflectionClass $classReflector Рефлектор класса. | ||||
|      * @param string $propertyName Имя свойства. | ||||
|      * @param mixed $classObj Объект класса. | ||||
|      * @param mixed $value Значение. | ||||
|      * | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     public static function SetParameterToClass (ReflectionClass $classReflector, string $propertyName, | ||||
|         mixed $classObj, mixed $value): void | ||||
|     { | ||||
|         try { | ||||
|             // Получаю свойство | ||||
|             $property = $classReflector->getProperty($propertyName); | ||||
|  | ||||
|             /** | ||||
|              * Устанавливаю доступ значения свойства. | ||||
|              * | ||||
|              * @noinspection PhpExpressionResultUnusedInspection | ||||
|              */ | ||||
|             $property->setAccessible(true); | ||||
|  | ||||
|             // Если значение null | ||||
|             if ($value == null || $value == "null") | ||||
|                 // - то присваиваю значение по умолчанию | ||||
|                 $value = self::GetDefaults($property->getType()->getName()); | ||||
|  | ||||
|             // Присваиваю значение | ||||
|             $property->setValue($classObj, $value); | ||||
|         } | ||||
|         catch (ReflectionException $exception) { | ||||
|             // Выбрасываю исключение | ||||
|             throw new Exception($exception->getMessage()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Получает значение по умолчанию для разных типов данных. | ||||
|      * | ||||
|      * @param string $typeName Имя типа данных. | ||||
|      * | ||||
|      * @return mixed|null Результат. | ||||
|      */ | ||||
|     public static function GetDefaults (string $typeName): mixed | ||||
|     { | ||||
|         return match ($typeName) { | ||||
|             'int' => 0, | ||||
|             'float' => 0.0, | ||||
|             'bool' => false, | ||||
|             'string' => '', | ||||
|             'array' => [], | ||||
|             'object' => new stdClass(), | ||||
|             default => null, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										60
									
								
								sources/classes/ObjectArray.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								sources/classes/ObjectArray.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| <?php | ||||
|  | ||||
| namespace goodboyalex\php_components_pack\classes; | ||||
|  | ||||
| use ArrayAccess; | ||||
| use Countable; | ||||
| use goodboyalex\php_components_pack\interfaces\ISerializable; | ||||
| use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayBasicTrait; | ||||
| use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayConstantsTrait; | ||||
| use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayLINQTrait; | ||||
| use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySearchAndSortTrait; | ||||
| use IteratorAggregate; | ||||
|  | ||||
| /** | ||||
|  * Класс, описывающий массив объектов. | ||||
|  * | ||||
|  * @author Александр Бабаев | ||||
|  * @package php_components_pack | ||||
|  * @version 1.0 | ||||
|  * @since 1.0 | ||||
|  */ | ||||
| final class ObjectArray implements ArrayAccess, IteratorAggregate, Countable, ISerializable | ||||
| { | ||||
|     /** | ||||
|      * @var array $Container Массив объектов, хранящихся в данном классе. | ||||
|      */ | ||||
|     private array $Container; | ||||
|  | ||||
|     // Реализация наследуемых интерфейсов и классов | ||||
|     use ObjectArrayBasicTrait; | ||||
|  | ||||
|     // Константы | ||||
|     use ObjectArrayConstantsTrait; | ||||
|  | ||||
|     // Поиск элемента | ||||
|     use ObjectArraySearchAndSortTrait; | ||||
|  | ||||
|     // LINQ-подобные методы | ||||
|     use ObjectArrayLINQTrait; | ||||
|  | ||||
|     /** | ||||
|      * Конструктор класса. | ||||
|      * | ||||
|      * @param array $array Массив объектов, который будет храниться в данном классе. | ||||
|      */ | ||||
|     public function __construct (array $array = []) | ||||
|     { | ||||
|         $this->Container = $array; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Возвращает массив объектов, хранящихся в данном классе. | ||||
|      * | ||||
|      * @return array Массив объектов, хранящихся в данном классе. | ||||
|      */ | ||||
|     public function ToArray (): array | ||||
|     { | ||||
|         return $this->Container; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user