363 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			363 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?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);
 | ||
|         }
 | ||
|     }
 | ||
| } |