omgdef/yii2-multilingual-behavior

Port of the yii-multilingual-behavior for yii

Installs: 145 238

Dependents: 11

Suggesters: 0

Security: 0

Stars: 146

Watchers: 19

Forks: 60

Open Issues: 26

Type:yii2-extension

2.1.2 2016-02-12 10:38 UTC

This package is auto-updated.

Last update: 2024-12-06 17:42:52 UTC


README

Yii2 port of the yii-multilingual-behavior.

Packagist Version Total Downloads Build Status Code Quality Code Coverage

This behavior allows you to create multilingual models and almost use them as normal models. Translations are stored in a separate table in the database (ex: PostLang or ProductLang) for each model, so you can add or remove a language easily, without modifying your database.

!!! IMPORTANT !!! Docs for vesions 1. here*

In vesion 2. forceOverwrite property is deprecated*

Examples

Example #1: current language translations are inserted to the model as normal attributes by default.

//Assuming current language is english

$model = Post::findOne(1);
echo $model->title; //echo "English title"

//Now let's imagine current language is french 
$model = Post::findOne(1);
echo $model->title; //echo "Titre en Français"

$model = Post::find()->localized('en')->one();
echo $model->title; //echo "English title"

//Current language is still french here

Example #2: if you use multilingual() in a find() query, every model translation is loaded as virtual attributes (title_en, title_fr, title_de, ...).

$model = Post::find()->multilingual()->one();
echo $model->title_en; //echo "English title"
echo $model->title_fr; //echo "Titre en Français"

Installation

Preferred way to install this extension is through composer.

Either run

php composer.phar require --prefer-dist omgdef/yii2-multilingual-behavior

or add

"omgdef/yii2-multilingual-behavior": "~2.0"

to the require section of your composer.json file.

Behavior attributes

Attributes marked as bold are required

Usage

Here an example of base 'post' table :

CREATE TABLE IF NOT EXISTS `post` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `created_at` datetime NOT NULL,
    `updated_at` datetime NOT NULL,
    `enabled` tinyint(1) NOT NULL DEFAULT '1',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

And its associated translation table (configured as default), assuming translated fields are 'title' and 'content':

CREATE TABLE IF NOT EXISTS `postLang` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `post_id` int(11) NOT NULL,
    `language` varchar(6) NOT NULL,
    `title` varchar(255) NOT NULL,
    `content` TEXT NOT NULL,
    PRIMARY KEY (`id`),
    KEY `post_id` (`post_id`),
    KEY `language` (`language`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

ALTER TABLE `postLang`
ADD CONSTRAINT `postlang_ibfk_1` FOREIGN KEY (`post_id`) REFERENCES `post` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

Attaching this behavior to the model (Post in the example). Commented fields have default values.

public function behaviors()
{
    return [
        'ml' => [
            'class' => MultilingualBehavior::className(),
            'languages' => [
                'ru' => 'Russian',
                'en-US' => 'English',
            ],
            //'languageField' => 'language',
            //'localizedPrefix' => '',
            //'requireTranslations' => false',
            //'dynamicLangClass' => true',
            //'langClassName' => PostLang::className(), // or namespace/for/a/class/PostLang
            'defaultLanguage' => 'ru',
            'langForeignKey' => 'post_id',
            'tableName' => "{{%postLang}}",
            'attributes' => [
                'title', 'content',
            ]
        ],
    ];
}

Then you have to overwrite the find() method in your model

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

As this behavior has MultilingualTrait, you can use it in your query classes

namespace app\models;

use yii\db\ActiveQuery;

class MultilingualQuery extends ActiveQuery
{
    use MultilingualTrait;
}

Form example:

//title will be saved to model table and as translation for default language
$form->field($model, 'title')->textInput(['maxlength' => 255]);
$form->field($model, 'title_en')->textInput(['maxlength' => 255]);

Hint: $model has to be populated with translations relative data otherwise translations will not be updated after $form send.