10

I want to implement i18n feature for ActiveRecord class FaqCategory using this extension. Here are my tables:

CREATE TABLE `FaqCategory` 
(
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `icon` varchar(255) DEFAULT NULL,
     PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

CREATE TABLE 
`FaqCategoryTranslation` 
(
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `catID` int(10) unsigned DEFAULT NULL,
    `languageID` tinyint(2) unsigned NOT NULL,
    `title` varchar(255) DEFAULT NULL,
    `slug` varchar(255) DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `catID` (`catID`) USING BTREE,
     KEY `languageID` (`languageID`),
     CONSTRAINT `FCT_FK1` FOREIGN KEY (`catID`) REFERENCES `FaqCategory` (`id`) ON DELETE             CASCADE ON UPDATE CASCADE,
    CONSTRAINT `FCT_FK2` FOREIGN KEY (`languageID`) REFERENCES `Language` (`id`) ON   DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8

CREATE TABLE `Language` 
(
  `id` tinyint(2) unsigned NOT NULL AUTO_INCREMENT,
  `locale` varchar(2) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

FaqCategory model:

class FaqCategory extends \yii\db\ActiveRecord
{

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

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'FaqCategory';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['icon', 'name'], 'string', 'max' => 255]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => 'Name',
            'icon' => 'Icon',
        ];
    }

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

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

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

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

Create action:

public function actionCreate()
    {
        $model = new FaqCategory();

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


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

And view file:

<div class="faq-category-create">

    <h1><?= Html::encode($this->title) ?></h1>

    <div class="faq-category-form">

        <?php $form = ActiveForm::begin(); ?>

        <?= $form->field($model, 'name'); ?>

        <? foreach ($model->getVariationModels() as $index => $variationModel): ?>
            <?= $form->field($variationModel, "[{$index}]title")->label($variationModel->getAttributeLabel('title') . ' (' . $variationModel->languageID . ')'); ?>
        <?php endforeach; ?>

        <div class="form-group">
            <?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
        </div>

        <?php ActiveForm::end(); ?>

    </div>

</div>

In frontend :

public function actionIndex()
    {
        $categories = FaqCategory::find()->with('translations')->all();
        return $this->render('index', ["categories" => $categories]);

    }

View file of actionIndex:

<div class="cat-descr"><?= $category->title ?></div>

Everything was ok, all data insterted properly to FaqCategoryTranslation table with languageID. But when I want to get these values from translation table, it returns only the value of name field in FaqCategory table. Lastly, I'm not completely understood AttributeDefaultValueMap. What is this attribute used for? In other words, if our default app language is for example en why not to use en title as default. Thanks!

Danila Ganchar
  • 7,271
  • 11
  • 35
  • 59
Sarkhan
  • 259
  • 1
  • 2
  • 8

1 Answers1

1

I suppose you should refer this :https://github.com/yii2tech/ar-variation

For example:

$items = Item::find()->with('translations')->all(); // only 2 queries will be performed
foreach ($items as $item) {
    echo $item->title . '<br>'; // add other stuffs you want to produce, like name, id or whatever you may have.
    var_dump($item->defaultTranslation);  // no extra query, `defaultTranslation` is populated from `translations`
}