Как использовать Yii с многоязычной моделью базы данных? - PullRequest
11 голосов
/ 31 октября 2011

У меня проблемы с получением данных из базы данных, которую я создал, чтобы она была полностью многоязычной, и я надеюсь, что кто-то здесь может мне помочь.

Я разделил все свои таблицы на 2 части; «универсальная» таблица (не содержит текста, который необходимо перевести) и таблица, содержащая все поля, которые необходимо перевести с их переводами.

Примеры таблиц:

base_material
    id
    picture
base_material_i18n
    base_material_id
    localization_id
    name
    description
    review_status
    review_notes
localization
    id
    language_name

Запрос на получение переводов (с использованием английского (en) в качестве запасного языка, если перевод недоступен):

SELECT o.id
     , o.type
     , o.code
     , o.position
     , ifnull(t.name,d.name) name
     , ifnull(t.description,d.description) description
  FROM base_material o
       INNER JOIN base_material_i18n d
               ON ( o.id=d.base_material_id)
       LEFT OUTER JOIN base_material_i18n t
                    ON ( d.base_material_id=t.base_material_id AND t.localization_id='nl' )
 WHERE d.localization_id='en'

Мой вопрос заключается в том, как я могу автоматически привязать эти переводы (с языком резервирования, как в этом запросе) к моей модели в Yii, когда я ищу объекты base_material? (Это только 1 пример таблицы, но почти все мои таблицы (20+) построены таким образом, поэтому, если возможно, мне понадобится что-то гибкое)

Пример существующей системы, использующей то, что мне нужно, - Propel: http://propel.posterous.com/propel-gets-i18n-behavior-and-why-it-matters

Есть идеи, как это сделать? Я проверил существующие расширения Yii для многоязычных сайтов (например, Multilingual Active Record ), но все они используют разный дизайн базы данных (общая информация + запасной язык в основной таблице, переводы в таблице i18n). ), и я не уверен, как изменить эти расширения для использования моего типа модели БД.

Если кто-то знает способ изменить это существующее расширение, чтобы он мог использовать мой тип схемы БД, то это было бы совершенно блестящим и, вероятно, лучшим способом сделать это.

Edit: я добавил награду, потому что я до сих пор не могу найти что-нибудь о том, как позволить Propel работать с Yii (существует расширение для Doctrine, но Doctrine также не поддерживает такого рода модель DB с переводами). ), а также никакой дополнительной информации о том, как с этим справиться, используя существующее расширение Yii или области действия.

Редактировать : 98 просмотров, но только 3 отзыва и 1 комментарий. Я не могу не чувствовать, что я делаю что-то не так, будь то в моем вопросе или в проекте приложения / базы данных; Либо это, либо моя проблема просто очень уникальна (что удивило бы меня, так как я не думаю, что моя многоязычная база данных настолько абсурдна ;-). Итак, если кто-нибудь знает о лучшем универсальном решении для многоязычных сайтов с Yii и / или Propel (кроме текущих расширений, которые мне действительно не нравятся из-за дублирования текстовых полей) или о чем-то подобном, пожалуйста, дайте мне знать а также.

Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 25 января 2012

Вы пробовали http://www.yiiframework.com/extension/i18n-columns/ (на основе http://www.yiiframework.com/extension/stranslateablebehavior/)?

Это альтернативный, более простой подход - добавление новых полей таблицы в стиле {field} _ {language code}, а затем установка переведенного поля в исходной модели для перевода текущего языка в afterFind.

По сути, это поможет вам настроить переводимые поля с переведенным контентом, извлекаемым «автоматически», хорошо это и плохо :). Добавление и удаление языков (= столбцов) выполняется с помощью миграций.

2 голосов
/ 15 ноября 2011

Я также ищу универсальное решение для внедрения i18n в модели Yii.Недавно я выбрал очень похожую схему базы данных для такого проекта, как вы.Единственное отличие состоит в том, что я не использую отдельную языковую таблицу, я храню информацию о языке в таблице i18n.

Следующее решение не имеет специального оператора SQL, но я думаю, что это можно реализовать с помощью отношенияparams, в любом случае, если вы работаете с внешним ключом в вашей базе данных (например, MySQL InnoDB), gii создаст отношения между вашей таблицей base_material и base_material_i18n, например

class BaseMaterial extends CActiveRecord

public function relations()
{
    return array(
        'baseMaterialI18ns' => array(self::HAS_MANY, 'base_material_i18n', 'id'),
    );
}



class BaseMaterialI18n extends CActiveRecord

public function relations()
{
    return array(
        'baseMaterial' => array(self::BELONGS_TO, 'base_material', 'id'),
    );
}

Теперь вы сможете получить доступваши переводы, используя объектную нотацию для отношений.

$model = BaseMaterial::model()->with('baseMaterialI18ns')->findByPk(1);
foreach($model->baseMaterialI18ns AS $translation) {
  if ($translation->language != "the language I need") continue:
  // do something with translation data ...
}

Я думал о создании поведения или базового класса для тех моделей, которые могли бы выступать в роли помощника для управления переводами - псевдокод:

I18nActiveRecord extends CActiveRecord

protected $_attributesI18n;

// populate _attributesI18n on query ...

public function __get($name) {
  if(isset($this->_attributesI18n['language_I_need'][$name]))
    return $this->_attributesI18n[$name];
  else if(isset($this->_attributesI18n['fallback_language'][$name]))
    return $this->_attributesI18n[$name];
  else 
    parent::__get();
}

CActiveRecord __get () source

Для поиска необходимой записи i18n предстоит еще много работы, также вы можете дополнительно ограничить параметр with (), чтобы повысить производительность и уменьшитьпарсинг на стороне PHP.

Но могут быть разные варианты использования для определения значения, например, все переводы, перевод или отступление, без отступления (пустое значение).Сценарии могут быть полезны здесь.

PS: Я был бы готов к проекту github !

0 голосов
/ 21 января 2013

Вы можете попробовать использовать простое многоязычное расширение CRUD.это очень просто использовать и модифицировать.вам просто нужно добавить поле языка в таблицу.просто посмотрите описание здесь: http://all -of.me / yii-multilingual-crud / он находится в альфа-состоянии, но попробовал несколько проектов.Вы можете легко изменить его или связаться с автором, чтобы исправить или добавить функции

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...