Yii2 using traits in a model and overriding them

Yii2 using traits in a model and overriding them

There’s a saying:

live and learn — and still die a fool

Why am I saying this? It’s about traits in PHP. They’ve been around for quite a while, but I only recently started using them in a new project.

The first thing I had to do was move the attributeLabels method into a trait. Yes, I could have created a single base class and extended it. But I decided to go with traits instead. So, here’s what we have:

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'),
        ];
    }
}

This trait was reused multiple times in models. Here’s one example:

namespace commonmodelsterritory;

use yiidbActiveRecord;

use commontraitsobjectObjectModelTrait;

class TerritoryAreaModel extends ActiveRecord
{
	use ObjectModelTrait;
	
    public static function tableName()
    {
        return '{{%territory_area}}';
    }
}

And in the city model, I needed to add an extra attribute for the area. To do this, I had to override the trait’s method name and call its result from the working attributeLabels method. Otherwise, there would be a conflict. As a result, we have the following:

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;
    }
}

I did the same thing with validation rules (rules), by the way. I usually extend forms from models. Here’s what I ended up with:

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;
	}
}

Are you having problems with your Yii2 framework website? Do you need additional functionality?
>Then write to me via the feedback form, and I will try to help you.

Write a comment

Your email address will not be published. Required fields are marked *