Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Symfony Validator #365

Closed
wehostadm opened this issue Oct 19, 2023 · 6 comments
Closed

Support Symfony Validator #365

wehostadm opened this issue Oct 19, 2023 · 6 comments

Comments

@wehostadm
Copy link

Hi,

I have plenty of errors due to Symfony Validor 👍

  Line   Validator\UserEmailValidator.php
 ------ --------------------------------------------------------------------------------------
  42     Access to an undefined property Symfony\Component\Validator\Constraint::$message.
         💡 Learn more: https://phpstan.org/blog/solving-phpstan-access-to-undefined-property
 ------ --------------------------------------------------------------------------------------

Seems that phpStan does not understand this...

Is there something to configure ?

Thanks,

@ondrejmirtes
Copy link
Member

Please show a piece of code where you're experiencing this error.

@wehostadm
Copy link
Author

@ondrejmirtes

Yes, the code of my custom validator

<?php

namespace App\Validator;

use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class UserEmailValidator extends ConstraintValidator
{
    private $entityManager;
    private $userRepository;

    public function __construct(EntityManagerInterface $entityManager, UserRepository $userRepository)
    {
        $this->entityManager = $entityManager;
        $this->userRepository = $userRepository;
    }

    public function validate($value, Constraint $constraint)
    {
        if (null === $value || '' === $value)
        {
            return;
        }

        // Get previous values
        $oldObject = $this->entityManager->getUnitOfWork()->getOriginalEntityData($this->context->getObject());

        $check = (is_array($oldObject) && !empty($oldObject) && $oldObject['email'] != $value) || empty($oldObject);
        if ($check)
        {
            $user = $this->userRepository->findOneBy(['email' => $value]);
            if (!$user)
            {
                return;
            }

            $this->context->buildViolation($constraint->message)
                ->setParameter('{{ value }}', $value)
                ->addViolation()
            ;
        }
    }
}

And the Symfony constraint

<?php

namespace App\Validator;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class UserEmail extends Constraint
{
    /*
     * Any public properties become valid options for the annotation.
     * Then, use these in your validator class.
     */
    public $message = 'L\'email {{ value }} est déjà utilisé';
}

Then when I run the PhpStan with the Symfony extension enabled, I got these errors for each custom validator

 Line   Validator\UserEmailValidator.php
 ------ --------------------------------------------------------------------------------------
  42     Access to an undefined property Symfony\Component\Validator\Constraint::$message.
         💡 Learn more: https://phpstan.org/blog/solving-phpstan-access-to-undefined-property
 ------ --------------------------------------------------------------------------------------

Thanks,

@Praesidiarius
Copy link

i have the same issue when i update phpstan/phpstan-symfony from 1.3.2 to 1.3.4

------ ----------------------------------------------------------------------------
  Line   src/Controller/Item/AvailabilityNotificationController.php
 ------ ----------------------------------------------------------------------------
  83     Call to an undefined method
         Symfony\Component\Validator\ConstraintViolationInterface::getConstraint().
 ------ ----------------------------------------------------------------------------

The corresponding code is:

78.    $error = $validator->validate($availabilityNotification);
79.
80.    $success = false;
81.
82.    if (count($error) > 0) {
83.      $first_constraint = $error[0]->getConstraint();
84.
85.      if ($first_constraint instanceof UniqueEntity) {
86.        $success = true;
87.      }
88.    }

$validator is autoinjected by ValidatorInterface $validator

My phpstan/phpstan version is 1.10.39

With phpstan/phpstan-symfony 1.3.2 i get no error, only when i update to 1.3.4

@siketyan
Copy link
Contributor

As explained in https://symfony.com/doc/current/validation/custom_constraint.html#creating-the-validator-itself, you should add a guard to ensure the constraint is the expected type:

if (!$constraint instanceof YourConstraint) {
    throw new UnexpectedTypeException($constraint, YourConstraint::class);
}

Now PHPStan should treat the constraint as your constraint class below the guard!

@ondrejmirtes
Copy link
Member

Situation could be improved with generics the same way security Voters work but that’s up to Symfony to decide.

Copy link

github-actions bot commented Dec 1, 2023

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants