OmgDef / yii2-multilingual-behavior

Yii2 port of the yii-multilingual-behavior.
146 stars 60 forks source link

Behavior of translation model class not run. #23

Open thuongqbd opened 9 years ago

thuongqbd commented 9 years ago

In my translation model class use SluggableBehavior.

public function behaviors()
    {
        return [
            [
                'class'=>SluggableBehavior::className(),
                'attribute'=>'title',
                'immutable' => true
            ],
        ];
    }

but this behavior not run. I tried print $translation->behaviors in function saveTranslations (MultilingualBehavior) and result was empty

array (size=0)
empty

private function saveTranslations($translations = [])
    {
        /** @var ActiveRecord $owner */
        $owner = $this->owner;

        foreach ($this->languages as $lang) {
            $defaultLanguage = $lang == $this->defaultLanguage;

            if (!isset($translations[$lang])) {
                /** @var ActiveRecord $translation */
                $translation = new $this->langClassName;
                $translation->{$this->languageField} = $lang;
                $translation->{$this->langForeignKey} = $owner->getPrimaryKey();
            } else {
                $translation = $translations[$lang];
            }

            $save = false;
            foreach ($this->attributes as $attribute) {
                $value = $defaultLanguage ? $owner->$attribute : $this->getLangAttribute($attribute . "_" . $lang);

                if ($value !== null) {
                    $field = $this->localizedPrefix . $attribute;
                    $translation->$field = $value;
                    $save = true;
                }
            }
            var_dump($translation->behaviors);die;
            if ($translation->isNewRecord && !$save)
                continue;

            $translation->save();
        }
OmgDef commented 9 years ago

@thuongqbd can you paste the model here?

thuongqbd commented 9 years ago

Model ProductCategory

namespace common\models;
use trntv\filekit\behaviors\UploadBehavior;
use Yii;
use yii\behaviors\SluggableBehavior;
use yii\behaviors\TimestampBehavior;
use common\components\ActiveRecord;
/**
 * This is the model class for table "product_category".
 *
 * @property integer $category_id
 * @property string $title
 * @property string $slug
 * @property integer $parent_id
 * @property integer $product_type
 * @property string $description
 * @property string $keyword
 * @property string $thumbnail_base_url
 * @property string $thumbnail_path
 * @property integer $order_num
 * @property integer $published
 * @property integer $deleted
 * @property integer $created_at
 * @property integer $updated_at
 */
class ProductCategory extends ActiveRecord
{
    public $thumbnail;
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'product_category';
    }

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            TimestampBehavior::className(),
            [
                'class'=>SluggableBehavior::className(),
                'attribute'=>'title',
                'immutable' => true
            ],
            [
                'class' => UploadBehavior::className(),
                'attribute' => 'thumbnail',
                'pathAttribute' => 'thumbnail_path',
                'baseUrlAttribute' => 'thumbnail_base_url'
            ],
            'ml' => [
                'class' => \omgdef\multilingual\MultilingualBehavior::className(),
                'languages' => \Yii::$app->params['availableLocales'],
                //'languageField' => 'language',
                //'localizedPrefix' => '',
                //'forceOverwrite' => false',
                //'dynamicLangClass' => true',
//              'langClassName' => ProductCategoryLang::className(), // or namespace/for/a/class/PostLang
                'defaultLanguage' => \Yii::$app->params['defaultLanguage'],
                'langForeignKey' => 'category_id',
                'tableName' => "{{%product_category_lang}}",
                'attributes' => [
                    'title', 'description','keyword','slug'
                ],
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['title', 'slug', 'product_type'], 'required'],
            [['parent_id', 'product_type', 'order_num', 'published', 'deleted', 'created_at', 'updated_at'], 'integer'],
            [['title', 'slug', 'description', 'keyword'], 'string', 'max' => 255],
            [['thumbnail_base_url', 'thumbnail_path'], 'string', 'max' => 1024],
            [['thumbnail'], 'safe'],
        ];
    }
    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'category_id' => Yii::t('product_category', 'Category ID'),
            'title' => Yii::t('product_category', 'Title'),
            'slug' => Yii::t('product_category', 'Slug'),
            'parent_id' => Yii::t('product_category', 'Parent ID'),
            'product_type' => Yii::t('product_category', 'Product Type'),
            'description' => Yii::t('common', 'Description'),
            'keyword' => Yii::t('common', 'Keyword'),
            'thumbnail' => Yii::t('product_category', 'Thumbnail'),
            'order_num' => Yii::t('common', 'Order'),
            'published' => Yii::t('common', 'Published'),
            'deleted' => Yii::t('common', 'Deleted'),
            'created_at' => Yii::t('common', 'Created At'),
            'updated_at' => Yii::t('common', 'Updated At'),
        ];
    }

    public static function find()
    {
        $q = new \omgdef\multilingual\MultilingualQuery(get_called_class());
        return $q;
    }
}

Model ProductCategoryLang

namespace common\models;
use Yii;
use yii\behaviors\SluggableBehavior;
use common\components\ActiveRecord;
/**
 * This is the model class for table "product_category_lang".
 *
 * @property integer $id
 * @property integer $category_id
 * @property string $language
 * @property string $title
 * @property string $slug
 * @property string $description
 * @property string $keyword
 *
 * @property ProductCategory $category
 */
class ProductCategoryLang extends ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'product_category_lang';
    }

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            [
                'class'=>SluggableBehavior::className(),
                'attribute'=>'title',
                'immutable' => true
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['category_id', 'language', 'title', 'slug'], 'required'],
            [['category_id'], 'integer'],
            [['language'], 'string', 'max' => 6],
            [['title', 'slug', 'description', 'keyword'], 'string', 'max' => 255]
        ];
    }
   /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('product_category', 'ID'),
            'category_id' => Yii::t('product_category', 'Category ID'),
            'language' => Yii::t('product_category', 'Language'),
            'title' => Yii::t('product_category', 'Title'),
            'slug' => Yii::t('product_category', 'Slug'),
            'description' => Yii::t('product_category', 'Description'),
            'keyword' => Yii::t('product_category', 'Keyword'),
        ];
    }
    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCategory()
    {
        return $this->hasOne(ProductCategory::className(), ['category_id' => 'category_id']);
    }

}
OmgDef commented 9 years ago

@thuongqbd Did you set dynamicLangClass to false? I'm sorry for not having replied was very busy

ustmaestro commented 9 years ago

I have this issue too

LangClass rules is not appended automatic LangClass behaviors not working

Category Class

<?php
namespace common\modules\blog\models;

use Yii;
use yii\db\ActiveRecord;
use yii\helpers\Inflector;
use ReflectionClass;

use yii\behaviors\TimestampBehavior;
use common\modules\blog\behaviors\MultilingualBehavior;
use common\modules\blog\behaviors\MultilingualQuery;

/**
 * This is the model class for table "category".
 *
 * @property integer $id
 * @property integer $author_id
 * @property string $icon
 * @property string $image
 * @property integer $sort_order
 * @property integer $views
 * @property integer $status
 * @property string $create_time
 * @property string $update_time
 * 
 * @property Author $author
 * @property CategoryLang[] $categoryLangs
 * @property PostCategory[] $postCategories
 */
class Category extends ActiveRecord
{
    /**
     * @var int Active status
     */
    const STATUS_ACTIVE = 1;

    /**
     * @var int Inactive status
     */
    const STATUS_INACTIVE = 0;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return Yii::$app->getModule('blog')->dataTableShema . static::getDb()->tablePrefix . 'category';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['author_id','sort_order', 'views', 'status'], 'integer'],
            [['create_time', 'update_time'], 'safe'],
            [['icon', 'image'], 'string', 'max' => 255],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id'            => Yii::t('blog', 'ID'),
            'author_id'     => Yii::t('blog', 'Author'),
            'icon'          => Yii::t('blog', 'Icon'),
            'image'         => Yii::t('blog', 'Image'),
            'sort_order'    => Yii::t('blog', 'Sort Order'),
            'views'         => Yii::t('blog', 'Views'),
            'status'        => Yii::t('blog', 'Status'),
            'create_time'   => Yii::t('blog', 'Create Time'),
            'update_time'   => Yii::t('blog', 'Update Time'),
        ];
    }

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'timestamp' => [
                'class'      => TimestampBehavior::className(),
                'value'      => function () { return date("Y-m-d H:i:s"); },
                'attributes' => [
                    ActiveRecord::EVENT_BEFORE_INSERT => 'create_time',
                    ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time',
                ],
            ],
            'ml' => [
                'class'             => MultilingualBehavior::className(),
                'languages'         => Yii::$app->params['languages'],
                'defaultLanguage'   => Yii::$app->params['defaultLanguage'],                
                'dynamicLangClass'  => false,
                'tableName'         => CategoryLang::tableName(),
                'langClassName'     => CategoryLang::className(),
                'langForeignKey'    => 'category_id',
                'attributes'        => ['name', 'slug', 'meta_description','meta_keywords', 'content', 'short_description', 'tags'],

                //'languageField' => 'language',
                //'localizedPrefix' => '',
                'requireTranslations' => true,
            ],
        ];
    }

    public static function find()
    {
        return new MultilingualQuery(get_called_class());
    }

    /**
     * @return \yii\db\ActiveQuery
     */   
    public function getAuthor()
    {
        return $this->hasOne(Author::className(), ['id' => 'author_id']);
    }

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

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

    /**
     * Update views counter.
     *
     * @return boolean Whether views counter was updated or not
     */
    public function updateViews()
    {
        return $this->updateCounters(['views' => 1]);
    }

    /**
     * Get list of statuses for creating dropdowns
     *
     * @return array
     */ 
    public static function statusDropdown(){
        static $dropdown;
        if($dropdown === null){
            $reflClass = new ReflectionClass(get_called_class());
            $constants = $reflClass->getConstants();
            foreach ($constants as $constantName => $constantValue){
                if (strpos($constantName, "STATUS_") === 0){
                    $prettyName               = str_replace("STATUS_", "", $constantName);
                    $prettyName               = Inflector::humanize(strtolower($prettyName));
                    $dropdown[$constantValue] = $prettyName;
                }
            }
        }
        return $dropdown;
    }

    /**
     * Get list of statuses for creating dropdowns
     *
     * @return array
     */ 
    public static function dropdown(){
        static $dropdown;
        if($dropdown === null){
            $models = static::find()->localized()->where(['status' => self::STATUS_ACTIVE])->all();
            foreach ($models as $model) {
                $dropdown[$model->id] = $model->status;
            }
        }
        return $dropdown;
    }
}

CategoryLang class

    <?php 
    namespace common\modules\blog\models;

    use Yii;
    use yii\db\ActiveRecord;

    use common\modules\blog\behaviors\SluggableBehavior;

    /**
     * This is the model class for table "category_lang".
     *
     * @property integer $category_id
     * @property string $language
     * @property string $name
     * @property string $slug
     * @property string $meta_description
     * @property string $meta_keywords
     * @property string $content
     * @property string $short_description
     * @property string $tags
     *
     * @property Category $category
     */
    class CategoryLang extends ActiveRecord
    {
        /**
         * @inheritdoc
         */
        public static function tableName()
        {
            return Yii::$app->getModule('blog')->dataTableShema . static::getDb()->tablePrefix . 'category_lang';
        }

        /**
         * @inheritdoc
         */
        public function rules()
        {
            return [
                [['language', 'name'], 'required'],
                [['category_id'], 'integer'],
                [['language', 'name', 'slug', 'meta_description', 'meta_keywords', 'content', 'short_description', 'tags'], 'safe'],
                [['content', 'short_description', 'tags'], 'string'],
                [['language'], 'string', 'max' => 16],
                [['name', 'slug', 'meta_description', 'meta_keywords'], 'string', 'max' => 255]
            ];
        }

        /**
         * @inheritdoc
         */
        public function attributeLabels()
        {
            return [
                'category_id'       => Yii::t('blog', 'Category ID'),
                'language'          => Yii::t('blog', 'Language'),
                'name'              => Yii::t('blog', 'Name'),
                'slug'              => Yii::t('blog', 'Slug'),
                'meta_description'  => Yii::t('blog', 'Meta Description'),
                'meta_keywords'     => Yii::t('blog', 'Meta Keywords'),
                'content'           => Yii::t('blog', 'Content'),
                'short_description' => Yii::t('blog', 'Short Description'),
                'tags'              => Yii::t('blog', 'Tags'),
            ];
        } 

        /**
         * @inheritdoc
         */
        public function behaviors()
        {

            return [
                [
                    'class'             => SluggableBehavior::className(),
                    'attribute'         => 'name',
                    'immutable'         => true,
                    'ensureUnique'      => true,
                    'forceUpdate'       => true,
                ],
            ];
        } 

        /**
         * @return \yii\db\ActiveQuery
         */
        public function getCategory()
        {
            return $this->hasOne(Category::className(), ['id' => 'category_id']);
        }
    }