0
votes

I use https://github.com/Atlantic18/DoctrineExtensions, I want to combine in my project translatable and sluggable. First I used translatable, the default language is Polish, translate into English and German. Everything works beautifully, add, edit, delete. then I used sluggable, also works nicely, but only with the default language. however does not create a slug for other languages.

config.yml:

doctrine:
dbal:
    driver:   "%database_driver%"
    host:     "%database_host%"
    port:     "%database_port%"
    dbname:   "%database_name%"
    user:     "%database_user%"
    password: "%database_password%"
    charset:  UTF8
    # if using pdo_sqlite as your database driver:
    #   1. add the path in parameters.yml
    #     e.g. database_path: "%kernel.root_dir%/data/data.db3"
    #   2. Uncomment database_path in parameters.yml.dist
    #   3. Uncomment next line:
    #     path:     "%database_path%"

orm:
    auto_generate_proxy_classes: "%kernel.debug%"
    auto_mapping: true
    mappings:
        translatable:
            type: annotation
            alias: Gedmo
            prefix: Gedmo\Translatable\Entity
            # make sure vendor library location is correct
            dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"

services.yml:

    parameters:
#    portal_cms.example.class: Portal\CmsBundle\Example

services:
    extension.listener:
        class: Portal\CmsBundle\EventListener\DoctrineExtensionListener
        calls:
            - [ setContainer, [ @service_container ] ]
        tags:
            # translatable sets locale after router processing
            - { name: kernel.event_listener, event: kernel.request, method: onLateKernelRequest, priority: -10 }
    gedmo.listener.sluggable:
        class: Gedmo\Sluggable\SluggableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]
    gedmo.listener.translatable:
        class: Gedmo\Translatable\TranslatableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]
            - [ setDefaultLocale, [ %locale% ] ]
            - [ setTranslationFallback, [ false ] ]

#    portal_cms.example:
#        class: %portal_cms.example.class%
#        arguments: [@service_id, "plain_value", %parameter%]

DoctrineExtensionListener.php:

    <?php

namespace Portal\CmsBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class DoctrineExtensionListener implements ContainerAwareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function onLateKernelRequest(GetResponseEvent $event)
    {
        $translatable = $this->container->get('gedmo.listener.translatable');
        $translatable->setTranslatableLocale($event->getRequest()->getLocale());
    }
}

Entity Tag.php:

    <?php

namespace Portal\CmsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;

/**
 * Tag
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Tag implements Translatable
{
    /**
     * @ORM\OneToMany(targetEntity="ArticleTag", mappedBy="tag")
     */
    protected $articleTags;

    public function __construct()
    {
        $this->articleTags = new ArrayCollection();
    }

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created", type="datetime", nullable=true)
     */
    private $created;

    /**
     * @var string
     *
     * @Gedmo\Translatable
     * @Gedmo\Slug(fields={"name"})
     * @ORM\Column(name="url", type="string", length=150, unique=true)
     */
    private $url;

    /**
     * @var string
     *
     * @Gedmo\Translatable
     * @ORM\Column(name="name", type="string", length=150)
     */
    private $name;

    /**
     * @Gedmo\Locale
     * Used locale to override Translation listener`s locale
     * this is not a mapped field of entity metadata, just a simple property
     */
    private $locale;

    private $translations;


    /**
     * Set created
     *
     * @param \DateTime $created
     * @return Tag
     */
    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

    /**
     * Get created
     *
     * @return \DateTime 
     */
    public function getCreated()
    {
        return $this->created;
    }

    /**
     * Set url
     *
     * @param string $url
     * @return Tag
     */
    public function setUrl($url)
    {
        $this->url = $url;

        return $this;
    }

    /**
     * Get url
     *
     * @return string 
     */
    public function getUrl()
    {
        return $this->url;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Tag
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set translations
     *
     * @param string $translations
     * @return Tag
     */
    public function setTranslations($translations)
    {
        $this->translations = $translations;

        return $this;
    }

    /**
     * Get translations
     *
     * @return string 
     */
    public function getTranslations()
    {
        return $this->translations;
    }

    /**
     * Add articleTags
     *
     * @param \Portal\CmsBundle\Entity\ArticleTag $articleTags
     * @return Tag
     */
    public function addArticleTag(\Portal\CmsBundle\Entity\ArticleTag $articleTags)
    {
        $this->articleTags[] = $articleTags;

        return $this;
    }

    /**
     * Remove articleTags
     *
     * @param \Portal\CmsBundle\Entity\ArticleTag $articleTags
     */
    public function removeArticleTag(\Portal\CmsBundle\Entity\ArticleTag $articleTags)
    {
        $this->articleTags->removeElement($articleTags);
    }

    /**
     * Get articleTags
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getArticleTags()
    {
        return $this->articleTags;
    }

    public function setTranslatableLocale($locale)
    {
        $this->locale = $locale;
    }
}

Controller

    <?php

namespace Portal\CmsBundle\Controller;

use Portal\CmsBundle\Entity\Tag;
use Portal\CmsBundle\Entity\ArticleTag;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityRepository;
use Gedmo\Translatable\TranslatableListener;

class AdminTagsController extends AbstractController
{
    public function indexAction(Request $request)
    {
// action code here - negligible
    }

    public function addAction(Request $request)
    {
        if ($request->getMethod() == 'POST') {
            $tag = new Tag();
            $em = $this->getDoctrine()->getManager();

            $formArray = $request->request->get('formTag');

            $repository = $em->getRepository('PortalCmsBundle:Article');

            $repository2 = $em->getRepository('Gedmo\\Translatable\\Entity\\Translation');

            $tag->setName($formArray['name']);
            $repository2->translate($tag, 'name', 'en', $formArray['name_en']);
            $repository2->translate($tag, 'name', 'de', $formArray['name_de']);
            $tag->setCreated(new \DateTime('now', new \DateTimeZone('Europe/Warsaw')));

            $validator = $this->get('validator');
            $errors = $validator->validate($tag);

            if (count($errors) > 0) {
                foreach ($errors as $error) {
                    $this->message .= $error->getPropertyPath().' <-- '.$error->getMessage().'
    ';
                }
            } else {
                $em->persist($tag);
                if (isset($formArray['articles'])) {
                    foreach ($formArray['articles'] as $article_id) {
                        $article = $repository->find((int)$article_id);
                        $article_tag = new ArticleTag($article, $tag);
                        $em->persist($article_tag);
                    }
                }
                $em->flush();

                $this->message = 'Tag dodany';
            }

            return $this->redirect($this->generateUrl(
                    'admin_tags',
                    array(
                        'message' => $this->message,
                        'messageType' => $this->messageType
                    )
                ));
        }

        return $this->redirect($this->generateUrl(
                    'admin_tags'
                )); 
    }

// other actions
}

Generally part of the documentation located here: https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/sluggable.md#using-translationlistener-to-translate-our-slug for me is not entirely clear. Does the code:

    <?php
$evm = new \Doctrine\Common\EventManager();
$sluggableListener = new \Gedmo\Sluggable\SluggableListener();
$evm->addEventSubscriber($sluggableListener);
$translatableListener = new \Gedmo\Translatable\TranslationListener();
$translatableListener->setTranslatableLocale('en_us');
$evm->addEventSubscriber($translatableListener);
// now this event manager should be passed to entity manager constructor

I have to insert somewhere, and if so, where? There is nowhere that information. Out of curiosity, I put it in the controller in the addAction and got an error, that can not be found \Gedmo\Translatable\TranslationListener(). Indeed, in this location Gedmo no such class. Is it a mistake in the documentation, that should not be there \Gedmo\Translatable\TranslatableListener() ?

The second issue, or slug field on the entity and in database should be called the 'slug'? In my case, it has another name, but slug generates Polish language properly. Could this be a problem in the generation of slug for translations?

The third issue, whether it is necessary to add these fields in the entity:

    <?php
/**
     * @ORM\Column(type="string", length=64)
     */
    private $uniqueTitle;

    /**
     * @Gedmo\Slug(fields={"uniqueTitle"}, prefix="some-prefix-")
     * @ORM\Column(type="string", length=128, unique=true)
     */
    private $uniqueSlug;

I would be grateful for any response, maybe a guiding me to solve this problem.

1
This should be broken into multiple questions with only the relevant code included.Jay Blanchard

1 Answers

1
votes

Change this line:

$translatableListener = new \Gedmo\Translatable\TranslationListener();

To this:

$translatableListener = new \Gedmo\Translatable\TranslatableListener();

Note the change of class name (ation vs atable).