Search code examples
phpsymfonydoctrine-ormdoctrine-extensions

Doctrine Translatable not showing translated text on locale change


I am using translatable with doctrine in a Symfony project. I've been able to add the translatable entity and store translated texts but when I change the locale in the website the texts are not shown although if I iterate over the translations i can see the texts. I think I am missing something.

Twig code:

<p>Title: {{ course.getTitle() }}</p>
<p>Translations content:</p>
<ul>
    {% for t in course.getTranslations() %}
        <li>{{  t.getLocale() }}: {{ t.getContent() }}</li>
    {% endfor %}
</ul>

The output if I go to /en/ url is:

Title: my title in en
Translations content:
es: Mi titulo en ES

But if I go to /es/ url:

Title:
Translations content:
es: Mi titulo en ES

You can see that the es translation is there, but is not shown when getTitle is called.

I have my Course entity and CourseTranslation entity to store the translations.

Also I have added the listener to set the default locale and checked that is being executed.

<?php
namespace AppBundle\Listener;

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());
    }
}

Course Code:

/**
 * Course
 *
 * @ORM\Table(name="course")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CourseRepository")
 */
class Course implements Translatable
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

    /**
     * @ORM\OneToMany(
     *   targetEntity="CourseTranslation",
     *   mappedBy="object",
     *   cascade={"persist", "remove"}
     * )
     */
    private $translations;

    /**
     * Get title
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }
    ...


    /** Translatable operations */
    public function getTranslations()
    {
        return $this->translations;
    }

    public function addTranslation(CourseTranslation $t)
    {
        if (!$this->translations->contains($t)) {
            $this->translations[] = $t;
            $t->setObject($this);
        }
    }
}

CourseTranslation code:

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonalTranslation;

/**
 * @ORM\Entity
 * @ORM\Table(name="course_translations",
 *     uniqueConstraints={@ORM\UniqueConstraint(name="lookup_unique_idx", columns={
 *         "locale", "object_id", "field"
 *     })}
 * )
 */
class CourseTranslation extends AbstractPersonalTranslation
{
    /**
     * Convenient constructor
     *
     * @param string $locale
     * @param string $field
     * @param string $value
     */
    public function __construct($locale, $field, $value)
    {
        $this->setLocale($locale);
        $this->setField($field);
        $this->setContent($value);
    }

    /**
     * @ORM\ManyToOne(targetEntity="Course", inversedBy="translations")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $object;
}

services yml code:

services:
    extension.listener:
        class: AppBundle\Listener\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.translatable:
        class: Gedmo\Translatable\TranslatableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ "@annotation_reader" ] ]
            - [ setDefaultLocale, [ %locale% ] ]
            - [ setTranslationFallback, [ false ] ]

Solution

  • Ok, problem found.

    In the Entity class I missed the @Gedmo\TranslationEntity so my entity has to be:

    /**
     * Course
     *
     * @ORM\Table(name="course")
     * @ORM\Entity(repositoryClass="AppBundle\Repository\CourseRepository")
     * @Gedmo\TranslationEntity(class="CourseTranslation")
     */
    class Course implements Translatable
    

    @systemasis, I don't know if you were pointing this in your example.