Skip to content

ExpressionLanguageSyntax constraint doesn't allow null value #43826

Closed
@pille1842

Description

@pille1842

Symfony version(s) affected

5.3.8

Description

The ExpressionLanguageSyntax constraint doesn't allow null values to pass. This evidently stems from Symfony\Component\Validator\Constraints\ExpressionLanguageSyntaxValidator, lines 42-44:

if (!\is_string($expression)) {
    throw new UnexpectedValueException($expression, 'string');
}

It's true that a null value is not a valid expression. However, this behavior is still different from other constraints: The Email constraint, for example, allows null values to pass, even though they are certainly not a valid email address. The expectation, in my view, is that users of the constraint will add an Assert\NotBlank constraint if they also wish to require the property to contain something.

In effect, the way things are now, even though the property is nullable in the database, it can never be null because the ExpressionLanguageSyntax constraint does the work of the NotBlank constraint.

How to reproduce

Create an entity:

namespace App\Entity;

/**
 * @ORM\Entity(repositoryClass=MyModelRepository::class)
 */
class MyModel
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="text", nullable=true)
     * @Assert\ExpressionLanguageSyntax()
     */
    private $expression;

Create a form type for the model:

namespace App\Form\Type;

use App\Entity\MyModel;
use Symfony\Component\OptionsResolver\OptionsResolver;

class MyModelType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => MyModel::class,
        ]);
    }
}

Create a controller with a form to persist a new instance of MyModel:

namespace App\Controller;

use App\Entity\MyModel;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class MyController extends AbstractController
{
    /**
     * @Route("/mymodel", name="mymodel")
     */
   public function new(Request $request): Response
    {
        $myModel = new MyModel();

        $form = $this->createForm(MyModelType::class, $myModel);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            return $this->redirectToRoute('mymodel_success');
        }

        return $this->renderForm('mymodel/new.html.twig', [
            'form' => $form,
        ]);
    }
}

When trying to submit the form with an empty value for expression, it will complain that type "string" was expected.

Possible Solution

Change ExpressionLanguageSyntaxValidator, lines 42-44, to the following:

if (!\is_string($expression)) {
    return;
}

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions