a2lix / TranslationFormBundle

Ease translations with some dedicated Symfony form types
https://a2lix.fr/bundles/translation-form
MIT License
330 stars 140 forks source link

method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given #384

Open garak opened 9 months ago

garak commented 9 months ago

Environment

Composer packages

$ composer show
a2lix/auto-form-bundle                        0.4.4
a2lix/translation-form-bundle                 3.2.1
[...]
symfony/framework-bundle                      v5.4.24

PHP version

$ php -v
PHP 8.1.25

Subject

The submit method in the TranslationsListener class calls the method_exists function on the form data without checking if the data is null, resulting in the exception mentioned above.

I guess this change should be made:

public function submit(FormEvent $event): void
{
    $form = $event->getForm();
    $formOptions = $form->getConfig()->getOptions();

    $data = $event->getData();

    foreach ($data as $locale => $translation) {
        if (null === $translation) {   // <!--- add this check
            continue;
        }

        // Remove useless Translation object <!--- here is the failing call when $translation is null
        if ((method_exists($translation, 'isEmpty') && $translation->isEmpty() && !\in_array($locale, $formOptions['required_locales'], true)) // Knp
            || empty($translation) // Default
        ) {
            $data->removeElement($translation);
            continue;
        }

        $translation->setLocale($locale);
    }
}

Steps to reproduce

Not sure about it

Expected results

No exception

Actual results

  at vendor/a2lix/translation-form-bundle/src/Form/EventListener/TranslationsListener.php:79
  at method_exists(null, 'isEmpty')
     (vendor/a2lix/translation-form-bundle/src/Form/EventListener/TranslationsListener.php:79)
  at A2lix\TranslationFormBundle\Form\EventListener\TranslationsListener->submit(object(SubmitEvent), 'form.submit', object(EventDispatcher))
     (vendor/symfony/event-dispatcher/EventDispatcher.php:230)
  at Symfony\Component\EventDispatcher\EventDispatcher->callListeners(array(object(Closure)), 'form.submit', object(SubmitEvent))
     (vendor/symfony/event-dispatcher/EventDispatcher.php:59)
  at Symfony\Component\EventDispatcher\EventDispatcher->dispatch(object(SubmitEvent), 'form.submit')
     (vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php:33)
  at Symfony\Component\EventDispatcher\ImmutableEventDispatcher->dispatch(object(SubmitEvent), 'form.submit')
     (vendor/symfony/form/Form.php:654)
  at Symfony\Component\Form\Form->submit(array(), true)
     (vendor/symfony/form/Form.php:589)
  at Symfony\Component\Form\Form->submit(array('image' => array('uploaded' => '[{"name":"default-user.png","fileName":"default-user.png"},{"name":"default-user.png","fileName":"default-user.png"}]', 'new' => array()), 'translations' => array('en' => array('description' => 'asdasas'), 'fr' => array('description' => ''))), true)
     (vendor/symfony/form/Extension/HttpFoundation/HttpFoundationRequestHandler.php:109)
  at Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest(object(Form), object(Request))
     (vendor/symfony/form/Form.php:503)
  at Symfony\Component\Form\Form->handleRequest(object(Request))
     (context/app/src/Auth/User/Presentation/Controller/Dashboard/ProfileController.php:59)
  at App\Auth\User\Presentation\Controller\Dashboard\ProfileController->editAction(object(Request))
     (vendor/symfony/http-kernel/HttpKernel.php:163)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:75)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:202)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php:35)
  at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
     (vendor/autoload_runtime.php:35)
  at require_once('/var/www/myproject/vendor/autoload_runtime.php')
     (public/index.php:6)