OmgDef / yii2-multilingual-behavior

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

Why cut off language to 2 chars length? #22

Closed anton-p-ivanov closed 9 years ago

anton-p-ivanov commented 9 years ago

I dont understand why i cant use en-US or ru-RU languages. They cuts off to 2 chars en and ru respectively but getLanguageBaseName function. For what reason?

OmgDef commented 9 years ago

@yapi68 You should use abridged versions of the language id everywhere, because long options are only needed in very severe cases, when there is a difference between the translation of the phrase for example, in en-US and en-GB. If you do not have such a situation, do not use full versions of id, nor for the base or the extension.

padlyuck commented 9 years ago

@OmgDef sr-Latn and sr has difference. sr uses cyrillic alphabet

anton-p-ivanov commented 9 years ago

Ok, but how can i use full lang_id en-US if I NEED IT? This behaviour cut off lang_id always.

OmgDef commented 9 years ago

@yapi68 That's not supported now

OmgDef commented 9 years ago

@yapi68 I implemented this feature. Now we have option abridge which should be set to false in your case, Also, if you use localized scope, you should pass second parameter Post::find()->localized('en-US', false)->where(['id' => 2])->one()

anton-p-ivanov commented 9 years ago

Wow! Thanks for efficiency!

pohnean commented 9 years ago

This is exactly what i needed! I needed it to implement Chinese (Simplified) and Chinese (Traditional).

OmgDef commented 9 years ago

@pohnean you can use this feature from dev-master. If you didn't find any bug, I'll make a release

alexweb-zz commented 9 years ago

When I have "abridge" option set to false, I can create form input like this:

 <?= $form->field($model, 'name_en')->textInput() ?>

But when I store language in long format like en-US and I set "abridge" to true, the following code shows an error: Attribute name must contain word characters only.

<?= $form->field($model, 'name_en-US')->textInput() ?>

How can I create an input in this case?

Maybe we can consider some another syntax for that like?

<?= $form->field($model, 'name_enUS')->textInput() ?>
alexweb-zz commented 9 years ago

Update: Ok, I checked the code. You've already implemented syntax for that. Maybe it's better to add example to docs.

 <?= $form->field($model, 'name_en_us')->textInput() ?>
anton-p-ivanov commented 9 years ago

@alexweb @OmgDef Ok, but now i have another trouble. I have 2 languages: en-US and ru-RU (selected). When im requesting $model->name it returns value in russian (correct). But when im requesting $model->name_en_us or $model->name_ru_ru its empty (NULL). What im doing wrong?

P.s. My search query is: Users::find()->multilingual()->one();

OmgDef commented 9 years ago

@yapi68 for me it works fine. Can you paste your models, table schema and example data set here?

anton-p-ivanov commented 9 years ago

@OmgDef Take it ...

Yii Framework: 2.0.4 PHP 5.6.7

Class CatalogType (model)

<?php

namespace app\modules\api\modules\catalogs\models;

use app\components\ActiveRecord;
use app\components\behaviors\PurifyBehavior;
use app\components\behaviors\WorkflowBehavior;
use app\models\Workflow;
use omgdef\multilingual\MultilingualBehavior;

/**
 * Class CatalogType
 * @package app\modules\api\modules\catalogs\models
 */
class CatalogType extends ActiveRecord
{
    /**
     * @return string
     */
    public static function tableName()
    {
        return '{{%catalogs_types}}';
    }

    /**
     * @return CatalogTypeQuery
     */
    public static function find()
    {
        return new CatalogTypeQuery(get_called_class());
    }

    /**
     * @return array
     */
    public function behaviors()
    {
        $behaviors = parent::behaviors();

        $behaviors['lang'] = [
                'class' => MultilingualBehavior::className(),
                'requireTranslations' => true,
                'languages' => ['ru-RU', 'en-US'],
                'languageField' => 'lang_id',
                'langForeignKey' => 'type_id',
                'tableName' => "{{%catalogs_types_lang}}",
                'attributes' => ['title'],
                'abridge' => false
        ];

        return $behaviors;
    }

    /**
     * @return array
     */
    public function rules()
    {
        return [
            [['title'], 'required'],
            [['title'], 'string', 'max' => 255],
            ['sort', 'integer']
        ];
    }
}
?>

Class CatalogTypeQuery (query)

<?php

namespace app\modules\api\modules\catalogs\models;

use app\components\ActiveQuery;
use omgdef\multilingual\MultilingualTrait;

/**
 * Class CatalogTypeQuery
 * @package app\modules\api\modules\catalogs\models
 */
class CatalogTypeQuery extends ActiveQuery
{
    use MultilingualTrait;
}
?>

Table schema

CREATE TABLE `a_catalogs_types` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `sort` int(10) unsigned NOT NULL DEFAULT '100',
 `workflow_id` int(10) unsigned DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `workflow_id` (`workflow_id`),
 CONSTRAINT `a_catalogs_types_ibfk_1` FOREIGN KEY (`workflow_id`) REFERENCES `a_workflow` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
CREATE TABLE `a_catalogs_types_lang` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `type_id` int(10) unsigned NOT NULL,
 `lang_id` varchar(6) NOT NULL,
 `title` varchar(255) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `type_id` (`type_id`),
 KEY `lang_id` (`lang_id`),
 CONSTRAINT `a_catalogs_types_lang_ibfk_1` FOREIGN KEY (`type_id`) REFERENCES `a_catalogs_types` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8

Example data

INSERT INTO `a_catalogs_types_lang` (`id`, `type_id`, `lang_id`, `title`) VALUES
(1, 1, 'ru-RU', 'Справочники изделия'),
(2, 2, 'ru-RU', 'Общие справочники'),
(3, 3, 'ru-RU', 'Каталоги'),
(4, 4, 'ru-RU', 'Тех. партнёрство'),
(5, 1, 'en-US', 'Product reference'),
(6, 2, 'en-US', 'Shared reference'),
(7, 3, 'en-US', 'Products'),
(8, 4, 'en-US', 'Solutions'),
(9, 5, 'ru-RU', 'Справочники изделия 1'),
(10, 5, 'en-US', 'Product reference 1'),
(13, 7, 'ru-RU', 'test ru'),
(14, 7, 'en-US', 'test en');

INSERT INTO `a_catalogs_types` (`id`, `sort`, `workflow_id`) VALUES
(1, 100, NULL),
(2, 1000, NULL),
(3, 50, NULL),
(4, 300, NULL),
(5, 200, NULL),
(7, 120, NULL);
OmgDef commented 9 years ago

@yapi68 Checkout https://github.com/OmgDef/yii2-multilingual-behavior/tree/issue22 and run tests

./vendor/bin/phpunit tests/Issue22.php

My output is

.string(16) "Каталоги"
string(8) "Products"
anton-p-ivanov commented 9 years ago

Found a mistake in my code! I forgot to use multilingual() method when requesting a model: correct way is:

Model::find()->where(...)->multilingual()->one();

So, everything is fine now!