/
v.bolshakov
/
AIEcosystem-Testing
Обзор
Документация
Войти
/
v.bolshakov
/
AIEcosystem-Testing
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
dev
common/forms/base/BaseModel.php
329 строк
8 KB
Developer
Initial commit
03 авг 2026, 17:43
03 авг 2026, 17:43
7433917
Код
Авторство
О чём код?
<?php namespace common\forms\base; use common\helpers\ModelHelper; use Yii; use yii\base\Component; use yii\base\Event; use yii\base\Model; use yii\base\ModelEvent; use yii\helpers\ArrayHelper; /** * Модель для работы с формой * * Данная модель для работы с пользователем через UI, использует одну или несколько моделей данных. * Должна включать в себя логигу обработки моделей данных. * * Может генерировать исключения. * * @author Dmitry E. Semenov <sde.tomsk@gmail.com> * @copyright Self (c) 2019 */ abstract class BaseModel extends \common\models\base\Model { /** * Результат работы формы * @var \common\models\base\BaseModel */ protected $model = null; const EVENT_BEFORE_SAVE = 'beforeSave'; const EVENT_AFTER_SAVE = 'afterSave'; const SCENARIO_LOAD = 'load'; const SCENARIO_SAVE = 'save'; /** * The name of the default scenario. */ const SCENARIO_CREATE = 'create'; /** * The name of the default scenario. */ const SCENARIO_UPDATE = 'update'; /** * Сценарий действия * @var null */ protected $action_state = null; /** * Использовать транзацию * @var bool */ protected $use_transaction = true; /** * Обновить страницу после закрытия модального окна * @var bool */ protected $reload_after_save = false; /** * Ключ для target обновления данных * @var bool */ protected $target = false; /** * Непосредственное сохранение данных * @return mixed */ protected function doSave() { return false; } /** * Данный метод будет вызван вне транзакции до сохранения данных * @return bool */ protected function beforeSave() { $event = new ModelEvent(); $this->trigger(self::EVENT_BEFORE_SAVE, $event); return $event->isValid; } /** * Данный метод будет вызван вне транзакции после сохранения * * @param bool $result данные были успешно добавлены или нет */ protected function afterSave($result) { $this->trigger(self::EVENT_AFTER_SAVE, new Event()); } /** * Сохранение введённых данных с проверкой валидатора * * @param bool $validate Использовать валидацию при сохранении данных * @return bool|mixed * @throws \Throwable */ public function save($validate = true) { if ($validate) { if (!$this->validate()) { return false; } } if ($this->beforeSave()) { if ($this->use_transaction) { $result = Yii::$app->db->saveTransaction(function ($db) { return $this->doSave(); }); } else { $result = $this->doSave(); } $this->afterSave($result); return $result; } else { return false; } } /** * Данный метод будет вызван вне транзакции после удаляния * * @param bool $result данные были успешно удалены или нет */ protected function afterDelete($result) { } /** * Удаление данных, созданных в форме * * @return bool|mixed * @throws \Throwable */ public function delete() { if ($this->use_transaction) { $result = Yii::$app->db->transaction(function () { return $this->doDelete(); }); } else { $result = $this->doDelete(); } $this->afterDelete($result); return $result; } /** * Непосредственное удаление данных, созданных в форме * @return mixed */ protected function doDelete() { return false; } /** * Данный метод необходим для совместимости с ActiveQuery при использовании в Crud-формах * @param $condition * @return mixed */ public static function findOne($condition) { $className = get_called_class(); $form = new $className; $form->loadModel($condition); return $form; } /** * @inheritdoc */ public function loadModel($condition) { $this->reload_after_save = (bool)ArrayHelper::getValue($condition, 'reload', $this->reload_after_save); $this->target = ArrayHelper::getValue($condition, 'target'); } /** * @inheritdoc */ public function load($data, $formName = null) { if (parent::load($data, $formName)) { $this->state = ModelHelper::prepareState($this); return true; } else { return false; } } /** * Инициализация первоначального состояния, загрузка данных из базы * данный метод заполняет поля модели * * @param Component $object объект, от которого происходит инициализация модели */ public function initState($object) { $fields = $this->attributes(); if ($object) { foreach ($fields as $index => $field) { if ($field instanceof \Closure) { $name = $index; } else { $name = $field; } if ($object->hasProperty($name)) { $value = $object->{$name}; if (is_scalar($value)) { $this->{$name} = $value; } } } } $this->model = $object; $this->state = ModelHelper::prepareState($this, $fields); } /** * @inheritdoc */ public function getId() { if ($this->model and ($this->model instanceof Model)) { return $this->model->getId(); } else { return null; } } /** * @inheritdoc */ public function getModel() { return $this->model; } /** * @inheritdoc */ public function getPrimaryKey($asArray = false) { if ($this->model and ($this->model instanceof Model)) { return $this->model->getPrimaryKey($asArray); } else { if ($asArray) { return []; } else { return null; } } } /** * @inheritdoc */ public function getIsNewRecord() { if ($this->model and ($this->model instanceof Model)) { return $this->model->getIsNewRecord(); } else { return true; } } /** * Установить текущее состояние * @param $value */ public function setActionState($value) { $this->action_state = $value; return $this; } /** * @inheritdoc */ public function getData() { return [ 'reload' => $this->reload_after_save, 'target' => $this->target ? $this->getTarget() : [] ]; } /** * Возвращаем массив данных для работы компонента target.js * @return array */ public function getTarget() { return [ [ 'id' => $this->model->id, 'text' => $this->model->title, 'target_id' => $this->target ] ]; } }