TrueDrago
@TrueDrago

Вопрос про Custom Doctrine Sluggable Transliterator в Symfony 2?

В паре проектов столкнулся с тем фактом, что расширение для Doctrine Sluggable behavior косячно производит транслитерацию.

Например, «е» = «ie», «ь» = "-", и так далее.



В связи с этим, хочу создать кастомный транслитератор, но не совсем понятно как это правильнее сделать, чтобы учесть архитектуру Симфони? (пока еще не разобрался в таких тонкостях) На гитхабе есть весьма абстрактный пример:



<?php<br><br>
$callable = array('My\Class', 'transliterationMethod');<br>
$sluggableListener->setTransliterator($callable);<br><br>
// or use a closure<br><br>
$callable = function($text, $separatorUsed, $objectBeingSlugged) {<br>
    // ...<br>
    return $transliteratedText;<br>
};<br>
$sluggableListener->setTransliterator($callable);<br>


Есть какие-либо встроенные в Симфони изящные варианты назначения кастомного транслитератора?
  • Вопрос задан
  • 3921 просмотр
Решения вопроса 1
Inori
@Inori
Надо переопределить Sluggable слушатель и добавить к нему аргумент с вызовом вашего транслитератора.
Что-то вроде:

<service id="stof_doctrine_extensions.listener.sluggable" class="%stof_doctrine_extensions.listener.sluggable.class%" public="false">
    <call method="setAnnotationReader">
        <argument type="service" id="annotation_reader" />
    </call>
    <call method="setTransliterator">
         <argument type="collection">
             <argument>\path\to\your\Urlizer</argument>
             <argument>transliterate</argument>
         </argument>
     </call>
</service>
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
chetzof
@chetzof
Я делал так. gist.github.com/4244940
Таблицу транслитерации вытянул из одного плагина wordpress.

По-моему у Inori более короткий вариант получился.
Ответ написан
Комментировать
Vir
@Vir
Программист
А чем вариант из примера не устроил? Со sluggable не работал (кстати, на днях буду), поэтому изящных вариантов не знаю.
Ответ написан
Davert
@Davert
Делать форк и патчить не вариант?
Вряд ли кому будут нужны: «е» = «ie», «ь» = "-"
Ответ написан
@karser
В копилку: можно присоединить транслитератор в компайлере
namespace YourBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class AddTransliterator implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $def = $container->findDefinition('stof_doctrine_extensions.listener.sluggable');
        $def->addMethodCall('setTransliterator', [['YourBundle\\Transliterator\\Transliterator', 'transliterate']]);
    }
}
Ответ написан
Комментировать
@igormukhin
Если необходимо предварительно переводить с русского на английский:

# services.yml
    app.transliterator:
        class: AppBundle\Gedmo\Sluggable\SluggableTransliterator
        arguments:
            - @remedge.yandex_translate.manager

    gedmo.listener.sluggable:
        class: Gedmo\Sluggable\SluggableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]
            - [ setTransliterator, [ [@app.transliterator, 'translate'] ] ]


# AppBundle/Gedmo/Sluggable/SluggableTransliterator.php

namespace AppBundle\Gedmo\Sluggable;

use Gedmo\Sluggable\Util\Urlizer;
use Remedge\YandexTranslateBundle\Manager\TranslateManager;

class SluggableTransliterator extends Urlizer
{
    /** @var TranslateManager */
    private $translator;

    /**
     * @param TranslateManager $translator
     */
    public function __construct(TranslateManager $translator)
    {
        $this->translator = $translator;
    }

    public function translate($text, $separator = '-')
    {
        $text = $this->translator->translate($text, 'ru-en');
        return self::urlize($text, $separator);
    }
}


Важно не переопределять в данном случае функцию transliterate, т.к. она статическая - лучше выбрать другое имя, например translate как в примере.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы