PHP code example of yii2tech / ar-variation

1. Go to this page and download the library: Download yii2tech/ar-variation library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

yii2tech / ar-variation example snippets


class Item extends ActiveRecord
{
    public function behaviors()
    {
        return [
            'translations' => [
                'class' => VariationBehavior::className(),
                'variationsRelation' => 'translations',
                'defaultVariationRelation' => 'defaultTranslation',
                'variationOptionReferenceAttribute' => 'languageId',
                'optionModelClass' => Language::className(),
                'defaultVariationOptionReference' => function() {return Yii::$app->language;},
                'variationAttributeDefaultValueMap' => [
                    'title' => 'name'
                ],
            ],
        ];
    }

    public static function tableName()
    {
        return 'Item';
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getTranslations()
    {
        return $this->hasMany(ItemTranslation::className(), ['itemId' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getDefaultTranslation()
    {
        return $this->hasDefaultVariationRelation(); // convert "has many translations" into "has one defaultTranslation"
    }
}

$item = Item::findOne(1);
echo $item->title; // equal to `$item->defaultTranslation->title`
echo $item->description; // equal to `$item->defaultTranslation->description`

$item = new Item(); // of course there is no translation for the new item
$item->name = 'new item';
echo $item->title; // outputs 'new item'

$items = Item::find()->with('defaultTranslation')->all(); // only 2 queries will be performed
foreach ($items as $item) {
    echo $item->title . '<br>';
}

$items = Item::find()->with('translations')->all(); // only 2 queries will be performed
foreach ($items as $item) {
    echo $item->title . '<br>'; // no extra query
    var_dump($item->defaultTranslation);  // no extra query, `defaultTranslation` is populated from `translations`
}

$items = Item::find()->joinWith('defaultTranslation')->all();

class Item extends ActiveRecord
{
    // ...

    public static function find()
    {
        return parent::find()->with('defaultTranslation');
    }
}

$item = Item::findOne(1);
$variationModel = $item->getDefaultVariationModel(); // get default variation instance
echo $item->defaultVariationModel->title; // default variation is also available as virtual property

$item = Item::findOne(1);
$frenchTranslation = $item->getVariationModel('fr');
$russianTranslation = $item->getVariationModel('ru');

use yii\base\Model;
use yii\web\Controller;
use Yii;

class ItemController extends Controller
{
    public function actionCreate()
    {
        $model = new Item();

        $post = Yii::$app->request->post();
        if ($model->load($post) && Model::loadMultiple($model->getVariationModels(), $post) && $model->save()) {
            return $this->redirect(['index']);
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }
}


use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $model Item */

$item = Item::findOne($id);

$item->title = ''; // setup of `$item->defaultTranslation->title`
var_dump($item->validate()); // outputs: `false`

$item->title = 'new title';
$item->save(); // invokes `$item->defaultTranslation->save()`

$item = new Item();
$item->name = 'new name';
$item->title = 'translation title'; // setup of `$item->defaultTranslation` attribute, creating default variation model
$item->description = 'translation description';
$item->save(); // saving both main model and default variation model

class Item extends ActiveRecord
{
    public function behaviors()
    {
        return [
            'translations' => [
                'class' => VariationBehavior::className(),
                // ...
                'variationAttributeDefaultValueMap' => [
                    'title' => 'name',
                    'description' => null,
                ],
            ],
        ];
    }

    public function rules()
    {
        return [
            // ...
            [['title', 'description'], 'safe'] // allow 'title' and 'description' to be populated via main model
        ];
    }

    // ...
}


use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $model Item */

use yii\web\Controller;
use Yii;

class ItemController extends Controller
{
    public function actionCreate()
    {
        $model = new Item();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            // variation attributes are populated automatically
            // and variation model saved
            return $this->redirect(['index']);
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }
}

class Developer extends ActiveRecord
{
    public function behaviors()
    {
        return [
            'frontEndPaymentRates' => [
                'class' => VariationBehavior::className(),
                'variationsRelation' => 'paymentRates',
                'variationOptionReferenceAttribute' => 'workTypeId',
                'optionModelClass' => WorkType::className(),
                'optionQueryFilter' => [
                    'groupId' => WorkType::GROUP_FRONT_END // add 'where' condition to the `WorkType` query
                ],
            ],
            'backEndPaymentRates' => [
                'class' => VariationBehavior::className(),
                'variationsRelation' => 'paymentRates',
                'variationOptionReferenceAttribute' => 'workTypeId',
                'optionModelClass' => WorkType::className(),
                // you can use a PHP callable as filter as well:
                'optionQueryFilter' => function ($query) {
                    $query->andWhere(['groupId' => WorkType::GROUP_BACK_END]);
                }
            ],
        ];
    }
    // ...
}

$developer = new Developer();
$developer->getBehavior('frontEndPaymentRates')->getVariationModels(); // get 'front-end' payment rates
$developer->getBehavior('backEndPaymentRates')->getVariationModels(); // get 'back-end' payment rates

class Developer extends ActiveRecord
{
    public function behaviors()
    {
        return [
            'regularPaymentRates' => [
                'class' => VariationBehavior::className(),
                'variationsRelation' => 'regularPaymentRates',
                'variationOptionReferenceAttribute' => 'workTypeId',
                'optionModelClass' => WorkType::className(),
            ],
            'overtimePaymentRates' => [
                'class' => VariationBehavior::className(),
                'variationsRelation' => 'overtimePaymentRates',
                'variationOptionReferenceAttribute' => 'workTypeId',
                'optionModelClass' => WorkType::className(),
            ],
        ];
    }

    public function getPaymentRates()
    {
        return $this->hasMany(PaymentRates::className(), ['developerId' => 'id']); // basic 'payment rates' relation
    }

    public function getRegularPaymentRates()
    {
        return $this->getPaymentRates()->andWhere(['isOvertime' => false]); // regular payment rates
    }

    public function getOvertimePaymentRates()
    {
        return $this->getPaymentRates()->andWhere(['isOvertime' => true]); // overtime payment rates
    }

    // ...
}

class Developer extends ActiveRecord
{
    public function behaviors()
    {
        return [
            'paymentRates' => [
                'class' => VariationBehavior::className(),
                'variationsRelation' => 'regularPaymentRates',
                'variationOptionReferenceAttribute' => 'workTypeId',
                'optionModelClass' => WorkType::className(),
                'variationSaveFilter' => function ($model) {
                    return !empty($model->paymentRate);
                },
            ],
        ];
    }

    // ...
}