/
v.bolshakov
/
AIEcosystem-Testing
Обзор
Документация
Войти
/
v.bolshakov
/
AIEcosystem-Testing
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
dev
common/models/base/BaseModel.php
509 строк
13 KB
Developer
Initial commit
03 авг 2026, 17:43
03 авг 2026, 17:43
7433917
Код
Авторство
О чём код?
<?php namespace common\models\base; use common\helpers\DateHelper; use common\kdf\KModelStatus; use common\models\User; use common\traits\FactoryTrait; use Exception; use Throwable; use Yii; use yii\base\InvalidConfigException; use yii\behaviors\BlameableBehavior; use yii\behaviors\TimestampBehavior; use yii\db\ActiveQuery; use yii\db\ActiveRecord; use yii\db\BaseActiveRecord; use yii\db\StaleObjectException; use yii\helpers\ArrayHelper; /** * Базовая модель для работы * * @property int $id * @property int $created_at Когда добавлено * @property int $created_by Кем добавлено * @property int $updated_at Кем обновлено * @property int $updated_by Когда обновлено * @property int $rec_status Статус записи * * @property User $updatedBy * @property User $createdBy * * @author Dmitry E. Semenov <sde.tomsk@gmail.com> * @copyright Self (c) 2019 */ abstract class BaseModel extends ActiveRecord { use FactoryTrait; /** * Имя базового ActiveQuery класса * @var string */ protected static $queryClass = 'common\models\base\BaseQuery'; /** * @var array */ public $created_attribute = [ 'user' => 'created_by', 'date' => 'created_at' ]; /** * @var array */ public $updated_attribute = [ 'user' => 'updated_by', 'date' => 'updated_at' ]; /** * Мягкое удаление * @var bool */ public $softDelete = false; /** * @event Event Событие, которое генерируется после восстановления объекта */ const EVENT_AFTER_RESTORE = 'afterRestore'; /** * Имя формы * @var array|string */ protected $modelName = []; /** * Поле используемое для хранения результатов работы агрегирующих функций БД * @var null */ public $mixed = null; /** * Название модели * @return array|string */ public function modelName($index = 0) { if (is_array($this->modelName)) { if ($index == -1) { return $this->modelName; } else { return Yii::t('app', ArrayHelper::getValue($this->modelName, $index)); } } return Yii::t('app', $this->modelName); } /** * @inheritdoc */ public function behaviors() { $blameableAttributes = []; if ($this->hasAttribute($this->created_attribute['user'])) { $blameableAttributes[BaseActiveRecord::EVENT_BEFORE_INSERT] = $this->created_attribute['user']; } if ($this->hasAttribute($this->updated_attribute['user'])) { $blameableAttributes[BaseActiveRecord::EVENT_BEFORE_UPDATE] = $this->updated_attribute['user']; } $timestampAttributes = []; if ($this->hasAttribute($this->created_attribute['date'])) { $timestampAttributes[BaseActiveRecord::EVENT_BEFORE_INSERT] = $this->created_attribute['date']; } if ($this->hasAttribute($this->updated_attribute['date'])) { $timestampAttributes[BaseActiveRecord::EVENT_BEFORE_UPDATE] = $this->updated_attribute['date']; } $behaviors = []; if (!empty($blameableAttributes)) { $behaviors['BlameableBehavior'] = [ 'class' => BlameableBehavior::class, 'attributes' => $blameableAttributes, 'defaultValue' => 0 ]; } if (!empty($timestampAttributes)) { $behaviors['TimestampBehavior'] = [ 'class' => TimestampBehavior::class, 'attributes' => $timestampAttributes, 'value' => DateHelper::now(), ]; } return $behaviors; } /** * {@inheritdoc} */ public function rules() { $rules_dt = []; $rules_int = []; if ($this->hasAttribute($this->created_attribute['date'])) { $rules_dt[] = $this->created_attribute['date']; } if ($this->hasAttribute($this->updated_attribute['date'])) { $rules_dt[] = $this->updated_attribute['date']; } if ($this->hasAttribute($this->created_attribute['user'])) { $rules_int[] = $this->created_attribute['user']; } if ($this->hasAttribute($this->updated_attribute['user'])) { $rules_int[] = $this->updated_attribute['user']; } if ($this->hasAttribute('rec_status')) { $rules_int[] = 'rec_status'; } if (!empty($rules_dt)) { $rules_dt = [[$rules_dt, 'string']]; } if (!empty($rules_int)) { $rules_int = [[$rules_int, 'integer']]; } return ArrayHelper::merge(parent::rules(), $rules_int, $rules_dt); } /** * Базовые значения labels * * @return array */ public function attributeLabels() { $labels = []; $labels['id'] = Yii::t('app', 'ID'); $labels['rec_status'] = Yii::t('app', 'Status'); if ($this->hasAttribute($this->created_attribute['user'])) { $labels[$this->created_attribute['date']] = Yii::t('app', 'Created At'); $labels[$this->created_attribute['user']] = Yii::t('app', 'Created By'); } if ($this->hasAttribute($this->updated_attribute['date'])) { $labels[$this->updated_attribute['date']] = Yii::t('app', 'Updated At'); } if ($this->hasAttribute($this->updated_attribute['user'])) { $labels[$this->updated_attribute['user']] = Yii::t('app', 'Updated By'); } return $labels; } /** * Проверить является ли текущий пользователь владельцем этой записи * * @return bool|null */ public function isOwner() { if ($this->hasAttribute($this->created_attribute['user'])) { if (!Yii::$app->user->isGuest) { return Yii::$app->user->id === $this->getAttribute($this->created_attribute['user']); } else { return false; } } return null; } /** * Получить логин создавшего запись * @return mixed|null */ public function getCreatedById() { if ($this->hasAttribute($this->created_attribute['user'])) { return $this->{$this->created_attribute['user']}; } return null; } /** * Получить дату создания объекта * @return mixed|null */ public function getCreated() { if ($this->hasAttribute($this->created_attribute['date'])) { return $this->{$this->created_attribute['date']}; } return null; } /** * Получить логин обновившего запись * @return mixed|null */ public function getUpdatedById() { if ($this->hasAttribute($this->updated_attribute['user'])) { return $this->{$this->updated_attribute['user']}; } return null; } /** * Получить время обновления записи * @return mixed|null */ public function getUpdated() { if ($this->hasAttribute($this->updated_attribute['date'])) { return $this->{$this->updated_attribute['date']}; } return null; } /** * Время последнего обновления * @return mixed|null */ public function getLastChange() { return $this->getUpdated() ?: $this->getCreated(); } /** * Получить алиас таблицы для выполнения запросов * @return null|string */ public static function getAlias() { static $alias_list = []; $tpl = static::tableName(); if (!($alias = ArrayHelper::getValue($alias_list, $tpl))) { $array = preg_split("/[\._]/", $tpl); foreach ((array)$array as $value) { $alias .= substr($value, 0, 1); } $alias = strtolower($alias); $alias_list[$tpl] = $alias; } return $alias; } /** * @return ActiveQuery */ public function getUpdatedBy() { return $this->hasOne(User::class, ['id' => $this->updated_attribute['user']]); } /** * @return ActiveQuery */ public function getCreatedBy() { return $this->hasOne(User::class, ['id' => $this->created_attribute['user']]); } /** * Перегружаем данный метод, для того что бы была возможность подменять ActiveQuery динамически * @return object|ActiveQuery * @throws InvalidConfigException */ public static function find() { $queryClass = get_called_class() . 'Query'; if (class_exists($queryClass)) { return Yii::createObject($queryClass, [get_called_class()]); } else { return Yii::createObject(static::$queryClass, [get_called_class()]); } } /** * @return ActiveQuery */ public function getRecStatus() { return $this->hasOne(KModelStatus::class, ['id' => 'rec_status']); } /** * Возвращает TRUE если у модели есть поле статус * * @return bool */ public function hasStatus() { return $this->hasAttribute('rec_status'); } /** * Текущий объект опубликован * * @return bool */ public function isPublished() { if ($this->hasStatus()) { return $this->rec_status == KModelStatus::PUBLISHED; } else { return true; } } /** * Текущий объект удален * * @return bool */ public function isDeleted() { if ($this->hasStatus()) { return $this->rec_status == KModelStatus::DELETED; } else { return false; } } /** * Найти объект или создать новый * * @param $condition * @return object|static * @throws InvalidConfigException */ public static function findOrNew($condition = null) { if ($condition) { $condition = array_diff((array)$condition, array('', '-', null, false)); if ($object = self::findOne($condition)) { return $object; } } /** @var BaseModel $object */ $object = Yii::createObject(get_called_class()); // соблюдение типов if (!ArrayHelper::isAssociative($condition)) { $primaryKey = static::primaryKey(); if (isset($primaryKey[0])) { $condition = [$primaryKey[0] => $condition]; } else { throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.'); } } $object->setAttributes($condition); return $object; } /** * Получить идентификатор текущей записи * @return mixed */ public function getId() { return $this->primaryKey; } /** * Получить представление модели в виде строки * @return string */ public function __toString() { return $this->getId(); } /** * @inheritdoc */ public function delete($forced = false) { if ($forced or !$this->softDelete) { return parent::delete(); } if (!$this->hasStatus()) { throw new Exception("Model has no 'rec_status' attribute and can't be soft deleted."); } $this->rec_status = KModelStatus::DELETED; $this->trigger(self::EVENT_BEFORE_DELETE); if ($result = $this->update(true, ['rec_status'])) { $this->trigger(self::EVENT_AFTER_DELETE); } return $result; } /** * Восстановить удаленную запись * * @return bool|false|int * @throws Throwable * @throws StaleObjectException */ public function restore() { if (!$this->hasStatus()) { throw new Exception("Model without 'rec_status' attribute can't be restored"); } if (!$this->isDeleted()) { return false; } $this->rec_status = KModelStatus::PUBLISHED; $result = $this->update(true, ['rec_status']); if ($result) { $this->trigger(self::EVENT_AFTER_RESTORE); } return $result; } /** * Возвращает информацию о моделях которые являются родительскики, * для выстраивания последовательности в выборка * ~~~ * [ * 'filed_id' => 'relation_name', * ] * ~~~ * @return array */ public function getParentModel() { return []; } }