2

I'm just looking the good way to use DoctrineBehaviors by knplabs.

I have allready render a form in sonata admin bundle with the help of this bundle : https://github.com/a2lix/TranslationFormBundle

Now, i want to have my translated field in the admin list.

At this time, it's work with this method:

/**
 * @ORM\Entity
 * @ORM\Table(name="sport") 
 */

class Sport
{
...

    public function getNom(){
        return $this->translate()->getNom();
    }
}

It's work but, i have to remap all the translated field in the original entity. I'm pretty sure i'm missing something, particularly with the magic of the proxy translations.

UPDATE:

class Sport
{

    use \Knp\DoctrineBehaviors\Model\Translatable\Translatable;

    public function __call($method, $arguments)
    {
        return $this->proxyCurrentLocaleTranslation($method, $arguments);
    }   
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    // Need this method for the admin list template
    public function getNom(){
         return $this->translate()->getNom();
    }

    // Work even the precedent method not here, the proxy call work fine.
    public function __toString(){
         return $this->getNom();
    }
}

class SportTranslation
{
    use ORMBehaviors\Translatable\Translation;

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $nom;

    /**
     * @return string
     */
    public function getNom()
    {
        return $this->nom;
    }

    /**
     * @param  string
     * @return null
     */
    public function setNom($nom)
    {
        $this->nom = $nom;
    }
}

Thanks for your fast reply @nifr! The proxy Method work in a controller (i try on the __toString Method of sport, it's work fine).

But the issue apparently coming from sonata admin bundle, i check the template code, don't know why it doesn't work.

I will keep the ugly method until i finda better solution.

At this time it's the only way to print value in the admin list template.

If i find something better i will update this post.

pandesowna
  • 23
  • 1
  • 4

2 Answers2

3

How to use Knp\DoctrineBehaviors magic proxy translations

Given you have MyClass and MyClassTranslation following the naming convention ( translation class suffixed with Translation ).

Only the properties which don't need to be translated live in MyClass and all translatable properties live in MyClassTranslation.

Let's say the translatable property shall be description.


MyClass.php

Attention: Neither property description nor getters/setters for description in MyClass .... otherwise __call() won't be invoked properly!

class MyClass
{

    use \Knp\DoctrineBehaviors\Model\Translatable\Translatable;

    public function __call($method, $arguments)
    {
        return $this->proxyCurrentLocaleTranslation($method, $arguments);
    }

    protected $nonTranslatableProperty;

    // ...

MyClassTranslation.php

use Doctrine\ORM\Mapping as ORM;

class MyClassTranslation
{
    use \Knp\DoctrineBehaviors\Model\Translatable\Translation;


    /**
     * @var string
     */
    protected $description;

    /**
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * @param string $description
     *
     * @return MyClassTranslation
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

Now calling MyClass::getDescription() will invoke the magic method __call() which will return the translation using the current locale because there is no getDescription() method in MyClass .

Solution:

You should remove all the translatable getters/setters/properties present in SportTranslation from your Sport class and instead add the magic __call() method.

Nicolai Fröhlich
  • 51,330
  • 11
  • 126
  • 130
2

At this time it's the only way to print value in the admin list template.

If you want all translations you can simply add in your admin class of sport :

protected function configureListFields(ListMapper $listMapper)
{
   $listMapper
       ->addIdentifier('translations')
}

That way the result will depends on __toString function of SportTranslation class.

Otherwise, if you want to print the current translation, I guess you should use a custom template. For instance I will remove the getNom method in Sport.

Then in your admin class of sport :

protected function configureListFields(ListMapper $listMapper)
{
   $listMapper
       ->addIdentifier('translations', null, array(
           'template' => 'YourAdminBundle:CRUD:translatable.html.twig'
       ));
}

In your template

{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field%}
{{ object }}
{% endblock %}

That way it will call the __toString of your sport Class and it works without the getNom method.

Unfortunately, it does not correct my problem link to yours : How to sort translatable data in sonata admin using knplabs doctrine behavior

Community
  • 1
  • 1
Tabzou
  • 121
  • 1
  • 6