phptranslationsymfony5stofdoctrineextensions

Symfony entity with field of type JSon leads to error with DoctrineExtension Translatable method translate


Using Symfony 5.4 and stof/doctrine-extensions-bundle 1.7

I have an project with existing data in two languages. While asked to add some more languages I try to implement Translatable of the doctrine Extensions and get rid of the old translation-'style'.

So I am writing a command to convert the old data with two fields to one translatable field.

In my entity I have many fields, for example the following:

    #[ORM\Column(type: 'json', nullable: true)]
    private ?array $answers = null;

    #[ORM\Column(name: 'answers_en', type: 'json', nullable: true)]
    private ?array $answersEn = null;

    #[ORM\Column(type: 'json', nullable: true)]
    #[Gedmo\Translatable]
    private ?array $answersI18n = null;

    public function getAnswers(): ?array
    {
        if ($this->answers !== null) {
            $this->answers = array_map(function ($value) {
                return $value === null ? '' : $value;
            }, $this->answers);
        }
        return $this->answers;
    }

    public function setAnswersI18n(?array $answersI18n): static
    {
        $this->answersI18n = $answersI18n;

        return $this;
    }

In my Command I have a loop containing following code:

    if (!empty($question->getAnswers())) {
        $translationRepository->translate($question, 'answersI18n', 'de', $question->getAnswers());
    }
    if (!empty($question->getAnswersEn())) {
        $translationRepository->translate($question, 'answersI18n', 'en', $question->getAnswersEn());
    }

normal fields of type text or string work just fine. But the JSon fields leads to following error:

In RuntimeReflectionProperty.php line 60:
Cannot assign string to property App\Entity\Question::$answersI18n of type ?array

An example Value could be: ["no","yes","n/a"]

The best solution I am thinking of are wrapper methods, datatransformers... something like this... converting the data to the needed format, but this does not feel right... Most propably this works out of the box and I have a mistake somewhere...


Solution

  • Problem solved, at least when the locale of the entity is the default locale. Not tested in other cases. Also not tested if the problem can be solved generally in the doctrine extension itself, or stof/doctrine-extensions-bundle.

    What has happened, or where comes the error from: On types, which get serialized (like array, simple_array, json) the field of the default locale gets serialized before the listener of the translate gets to action. Because of that the array or json is serialized to a string, and when the listener of translate tries to use the setter with the serilized string the error is thrown.

    The solution: The solution is very easy: don't use the translate method for the locale, but use the 'normal' setter.

    in the command the code now looks like the following

    // only tested if the locale is the default_locale
    // if it differs try the following code and if an error is thrown try to use the setAnwersI18n-method
    // with the content of the locale, and use the translate-method on the other locales
    if (!empty($question->getAnswers())) {
        //$translationRepository->translate will lead to an error on types like array, simple_array or json.
        // At least if the locale is the default locale
        $question->setAnswersI18n($question->getAnswersI18n());
    }
    if (!empty($question->getAnswersEn())) {
        $translationRepository->translate($question, 'answersI18n', 'en', json_encode($question->getAnswersEn()));
    }
    

    This works like a charm at least for me