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