Closed
Description
Symfony version(s) affected: 5.3.4
Description
I use PHP 8 and my entities use the type declaration on setter and getter.
When validating a Form with a null
value on a field that require non null (eg: method(string $value)
), the handle()
method throw an InvalidArgumentException
and a TypeError
.
How to reproduce
Example Entity, Form and Controller
src/Entity/Structure.php
<?php
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
namespace App\Entity;
/**
* @ORM\Entity()
*/
class Structure {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBank()
*/
private $name;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}
src/Form/StructureType.php
<?php
namespace App\Form;
use App\Entity\Structure;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class StructureType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Structure::class,
]);
}
}
src/Controller/Structure.php
<?php
namespace App\Controller;
use App\Entity\Structure;
use App\Form\StructureType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class StructureController extends AbstractController
{
#[Route('/test_form', name: 'test_form')]
public function create(Request $request): Response
{
$structure = new Structure();
$form = $this->createForm(StructureType::class, $structure);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/* ... */
}
return $this->render('structure/form.html.twig', [
'form' => $form->createView(),
]);
}
}
Possible Solution
Catch these exceptions and add a validation error asking a non null value (or use the existing Validator on the field)
Additional context
The stack trace when $form->handleRequest($request)
is called
Symfony\Component\PropertyAccess\Exception\InvalidArgumentException:
Expected argument of type "string", "null" given at property path "name".
at vendor/symfony/property-access/PropertyAccessor.php:268
at Symfony\Component\PropertyAccess\PropertyAccessor::throwInvalidArgumentException()
(vendor/symfony/property-access/PropertyAccessor.php:179)
at Symfony\Component\PropertyAccess\PropertyAccessor->setValue()
(vendor/symfony/form/Extension/Core/DataAccessor/PropertyPathAccessor.php:68)
at Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor->setValue()
(vendor/symfony/form/Extension/Core/DataAccessor/ChainAccessor.php:54)
at Symfony\Component\Form\Extension\Core\DataAccessor\ChainAccessor->setValue()
(vendor/symfony/form/Extension/Core/DataMapper/DataMapper.php:87)
at Symfony\Component\Form\Extension\Core\DataMapper\DataMapper->mapFormsToData()
(vendor/symfony/form/Form.php:640)
at Symfony\Component\Form\Form->submit()
(vendor/symfony/form/Extension/HttpFoundation/HttpFoundationRequestHandler.php:109)
at Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest()
(vendor/symfony/form/Form.php:501)
at Symfony\Component\Form\Form->handleRequest()
(src/Controller/StructureController.php:36)
at App\Controller\StructureController->edit()
(vendor/symfony/http-kernel/HttpKernel.php:156)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
(vendor/symfony/http-kernel/HttpKernel.php:78)
at Symfony\Component\HttpKernel\HttpKernel->handle()
(vendor/symfony/http-kernel/Kernel.php:199)
at Symfony\Component\HttpKernel\Kernel->handle()
(public/index.php:20)
TypeError:
Proxies\__CG__\App\Entity\Structure::setName(): Argument #1 ($name) must be of type string, null given, called in /***/vendor/symfony/property-access/PropertyAccessor.php on line 576
at var/cache/dev/doctrine/orm/Proxies/__CG__AppEntityStructure.php:251
at Proxies\__CG__\App\Entity\Structure->setName()
(vendor/symfony/property-access/PropertyAccessor.php:576)
at Symfony\Component\PropertyAccess\PropertyAccessor->writeProperty()
(vendor/symfony/property-access/PropertyAccessor.php:175)
at Symfony\Component\PropertyAccess\PropertyAccessor->setValue()
(vendor/symfony/form/Extension/Core/DataAccessor/PropertyPathAccessor.php:68)
at Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor->setValue()
(vendor/symfony/form/Extension/Core/DataAccessor/ChainAccessor.php:54)
at Symfony\Component\Form\Extension\Core\DataAccessor\ChainAccessor->setValue()
(vendor/symfony/form/Extension/Core/DataMapper/DataMapper.php:87)
at Symfony\Component\Form\Extension\Core\DataMapper\DataMapper->mapFormsToData()
(vendor/symfony/form/Form.php:640)
at Symfony\Component\Form\Form->submit()
(vendor/symfony/form/Extension/HttpFoundation/HttpFoundationRequestHandler.php:109)
at Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest()
(vendor/symfony/form/Form.php:501)
at Symfony\Component\Form\Form->handleRequest()
(src/Controller/StructureController.php:36)
at App\Controller\StructureController->edit()
(vendor/symfony/http-kernel/HttpKernel.php:156)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw()
(vendor/symfony/http-kernel/HttpKernel.php:78)
at Symfony\Component\HttpKernel\HttpKernel->handle()
(vendor/symfony/http-kernel/Kernel.php:199)
at Symfony\Component\HttpKernel\Kernel->handle()
(public/index.php:20)