Кажуть:
вік живи, вік учись, а дурнем помреш
До чого це? А це про трейти в PHP. Вони вже давно з’явилися, а я тільки нещодавно почав їх використовувати в новому проєкті.
Перше, що довелося зробити — винести в trait метод з атрибутами. Так, можна було б створити один батьківський клас і наслідуватися від нього. Але я вирішив зупинитись на трейтах. Що ми маємо:
namespace commontraitsobject;
use Yii;
trait ObjectModelTrait
{
/**
* Labels
* @return array
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'name' => Yii::t('app', 'Name'),
'desc' => Yii::t('app', 'Description'),
'index_id' => Yii::t('app', 'Index'),
'is_active' => Yii::t('app', 'Is active'),
];
}
}Цей trait багаторазово використовувався в моделях. Ось один із прикладів:
namespace commonmodelsterritory;
use yiidbActiveRecord;
use commontraitsobjectObjectModelTrait;
class TerritoryAreaModel extends ActiveRecord
{
use ObjectModelTrait;
public static function tableName()
{
return '{{%territory_area}}';
}
}А ось у моделі з містами мені потрібно було додати ще атрибут області. Для цього довелося перевизначити назву методу з трейта і викликати результат у "робочому" методі attributeLabels. Без цього виникав би конфлікт. У результаті маємо наступне:
namespace commonmodelsterritory;
use Yii;
use yiidbActiveRecord;
use commontraitsobjectObjectModelTrait;
class TerritoryCityModel extends ActiveRecord
{
use ObjectModelTrait {
ObjectModelTrait::attributeLabels as attributeLabelsObject;
}
public static function tableName()
{
return '{{%territory_city}}';
}
/**
* Labels
* @return array
*/
public function attributeLabels()
{
$labels = $this -> attributeLabelsObject();
$labels['territory_area_id'] = Yii::t('app', 'Area');
return $labels;
}
}Аналогічно я, до речі, зробив і з правилами (rules). Форми я зазвичай наслідую від моделей. Вийшло так:
namespace backendformsterritory;
use Yii;
use commonmodelsterritoryTerritoryCityModel;
use commontraitsobjectObjectFormTrait;
use commonmodelsterritoryTerritoryAreaModel;
class TerritoryCityForm extends TerritoryCityModel
{
use ObjectFormTrait {
ObjectFormTrait::rules as rulesObject;
}
public function rules()
{
$rules = $this -> rulesObject();
$rules[] = [['territory_area_id'], 'exist',
'targetClass' => TerritoryAreaModel::className(),
'targetAttribute' => ['territory_area_id' => 'id'],
'message' => Yii::t('app','Selected Area does not exist'),
];
return $rules;
}
}