Говорят:
век живи, век учись, а дураком помрёшь
Это к чему? да это к трейтам в 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; } }