Как мне отсортировать интернационализированную таблицу i18n с помощью symfony и doctrine?

Я хотел бы отобразить список записей из интернационализированной таблицы с помощью sfDoctrinePager. Не все записи были переведены на все языки, поддерживаемые приложением, поэтому мне пришлось реализовать резервный механизм для некоторых полей (переопределив функцию getFoo () в Bar.class.php, как описано в другом сообщении здесь) . У меня есть разные резервные списки для каждой культуры. Все работает нормально, пока не доходит до сортировки записей в алфавитном порядке.

Я сортирую записи на уровне SQL (Dql), добавляя -> orderBy ('t.name') к запросу:

    $q = Doctrine::getTable('Foo')
        ->createQuery('f')
        ->leftJoin('f.Translation t')
        ->orderBy('t.name')

Но вот и неприятности: список не сортируется правильно, независимо от активной культуры. Я получаю гораздо лучшие результаты, когда ограничиваю переводы активной культурой, например:

->leftJoin('f.Translation t WITH lang = ?', $request->getParameter('sf_culture');

Тогда сортировка правильная, поскольку все переводы существуют для активной культуры. Если перевод не существует, и мне нужно взять имя из резервного языка, запись будет отображаться в самом начале списка (я понимаю, что это происходит, потому что значение для текущего языка и региональных параметров равно нулю). Мой вопрос: есть ли лучшая практика для получения интернационализированных полей (требующих резервных копий), правильно отсортированных с помощью doctrine и sfDoctrinePager? Заранее спасибо.


person Maurizio    schedule 21.03.2010    source источник


Ответы (3)


  1. Создайте запрос DQL, который возвращает как основной, так и резервный язык: ->innerJoin('f.Translation ft WITH ft.lang IN(?)', array(array('pl', 'en'))
  2. Убедитесь, что основной язык отсортирован перед резервным: ->orderBy('FIELD(ft.lang, "pl", "en")
  3. Теперь вы можете добавить ->orderBy('ft.name'), и он должен работать должным образом.

Используйте sfDoctrinePager :: setQuery () или sfDoctrinePager :: setTableMethod (), чтобы передать запрос для пейджера.

person Crozin    schedule 21.03.2010

Я бы повторил ответ Крозина, хотя я удивлен, что сортировка не работает должным образом (при условии, что вы правильно настроили таблицы i18n в соответствии с правилами Symfony).

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

person Tom    schedule 21.03.2010

Используйте культуру в запросе:

$q = Doctrine::getTable('Foo')
    ->createQuery('f')
    ->leftJoin('f.Translation t')
    ->where('t.lang = ?', sfContext::getInstance()->getUser()->getCulture())
    ->orderBy('t.name')
person szinya    schedule 27.09.2011
comment
Спасибо за ответ, но, используя ваш метод, у меня не было бы альтернативы, если на активном языке нет перевода. - person Maurizio; 11.07.2013