5

I'm using "knp Doctrine Translatable" to translate Entities. So far is working great. Now I come to a point where I would like to have a generic solution, that works for any amount of languages. So I though about using an embeded form (Collections) that will handle the Translatables for an Entity. Now all is working as should, except that for adding new translation the translatable_id is not being set. Anyone has tried to achieve this too ? I was just wondering if there is an easier way to do it, to avoid over complicating things.

So far, so good, here go my Types so you can understand better the architecture.

// Main type that has a linkTranslationType with the translations
class linkType extends AbstractType  {
public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder
        ->add('name', 'text', array(
            'label' => 'Name'
        ))

        ->add('translations', 'collection', array(
                'type' => new linkTranslationType(),
                'label' => false,
                'allow_add' => true,
                'allow_delete' => true
            ));

}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'MyBundle\Entity\Link'
    ));
}
}

This is the LinkTranslationType that is rendered as "a row" per language: en_EN Anchor http//url/en

class linkTranslationType extends AbstractType  {
public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder
        ->add('locale', 'text',array(
            'label' => 'Anchor'
        ))

        ->add('linkText', 'text',array(
            'label' => 'Anchor'
        ))

        ->add('linkUrl', 'text', array(
            'label' => 'Url'
        ))


    ;

}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'MyBundle\Entity\LinkTranslation'
    ));
}
}

So as an example, trying to add this new entry: en_EN Anchor http//url/en

I'm getting :

id  translatable_id     linkText    linkUrl       locale
 7  NULL                Anchor      http//url/en  en_EN

I've tried to discover how translatable_id works, but still didn't had time to examine the whole source. Lastly, I tried to setTranslatableId too, without better luck. (Update: in comments)

So far I could :

  • #1 Insert a new link , but not the translations (They are saved with NULL as traslatable_id)
  • #2 Save existing translations link works perfect

Some other notes to add some context:

1 I tried:

$link = new Link();
if ($form->isValid() ) {
$link->mergeNewTranslations(); // but this also does assigm the Id to the translations
}

2 To save existing translation I just passed the existing Link entity to the form builder

3 I know that I could loop and assign the Translatable elements the parent entity

But that is a hack that I'm not willing to do if I have a better option:

// persist($link); and flush()
foreach ($link->getTranslations() as $linkTranslation) {
  $linkTranslation->setTranslatable($link);
  $em->persist($linkTranslation);
}
$em->flush();

So of course this is not the type of answer I'm looking for :)

Martin Fasani
  • 825
  • 7
  • 20
  • After taking a closer look to the source: doctrine-bahaviors/src/Model/Translatable/TranslationMethods Now I know that adding a 'translatable' (Type: entity) to the linkTranslationType I can set the translation_id. But is a little bit cumbersome with the form collection and so on. I need to find some easier configuration. So if someone has achieved this in a different way, please let me know. – Martin Fasani Nov 06 '14 at 09:06
  • Hi! I have a similar problem and I don't either how to approach it. I tried your solution but I get this error: Neither the property "translations" nor one of the methods "getTranslations()", "translations()", "isTranslations()", "hasTranslations()", "__get()" exist and have public access in class "SocialCar\CoreBundle\Entity\Accessory". – petekaner May 19 '15 at 14:24
  • 1
    Hi, i have tried this solution for symfony 3. and i followed instructions from this Ref. url http://a2lix.fr/bundles/translation-form/3.x.html . The error is as below: Neither the property "translations" nor one of the methods "getTranslations()", "translations()", "isTranslations()", "hasTranslations()", "__get()" exist and have public access in class "CLASS_PATH".. Please let me know if you have solution. I have created two entity ContentPages and ContentPageTranslations. – Nikunj Kabariya Feb 13 '17 at 12:22
  • Hallo Nikunj, I posted an alternative solution. I know it's a bit hacky but you can borrow it from here and adapt it to your needs. Happy coding! – Martin Fasani Feb 21 '17 at 16:22
  • @petekaner I posted a solution – ste Aug 11 '17 at 21:26
  • @Nikunj Kabariya I posted a solution – ste Aug 11 '17 at 21:26

1 Answers1

0

You should add a 'by_reference'=>false option to the translations field and then in your Link entity add these methods (see https://symfony.com/doc/current/form/form_collections.html)

public function addTranslation(LinkTranslation $t)
{
    $t->setTranslatable($this);
    $this->getTranslations()->add($t);
}

public function removeTranslation(LinkTranslation $t)
{
    $this->getTranslations()->remove($t);
}
ste
  • 1,479
  • 10
  • 19