Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Validator] Standardize constraint validators #28645

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/Symfony/Component/Validator/ConstraintValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Validator;

use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

/**
* Base class for constraint validators.
Expand Down Expand Up @@ -44,6 +45,40 @@ public function initialize(ExecutionContextInterface $context)
$this->context = $context;
}

/**
* Test a constraint class for the current validator.
*
* @throws UnexpectedTypeException
*/
final protected static function testConstraint(Constraint $constraint, string $expectedClass)
Copy link
Member

@nicolas-grekas nicolas-grekas Oct 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this? I feel like this removes some info for static analysis + increases the stack traces of exception for little practical benefit, don't you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran a little investigation:

  1. PHPStorm doesn't understand this
  2. Psalm does https://getpsalm.org/r/acd72ab0ab cc @muglug
  3. PHPStan doesn't https://phpstan.org/r/be6b68a728fc1d24fb27069640f46701 cc @ondrejmirtes

Anyway Validator is full of this piece of code, so I think it's worth it. SA tools which don't support it is problem of the tool itself, not the code. And we can help them by specifying @param alongside @inheritDoc (works for PHPStorm and Psalm, PHPStan is stubborn like usual).

Extraction of common pieces of code is important for keeping consistency. Also, if this was done in the first place, there would be no need to manually touch so many places in #27917

But, this should be renamed. testConstraint is odd one. assertInstanceOf?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not really a common piece of logic - that's an "if"...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't mention "logic", I mentioned "piece of code". Anyway "if" contains some logic. This "if" is in almost all validators. Devs keep producing highly repetitive code instead of extracting it to function. This is like no. 1 rule of programming. Programs are good at repeating, not humans.

And here is another advantage of having such thing there in the first place - if it was already there, all custom validators using such function would be automatically compatible with #27917. Since it's not there (because such function is too simple right?), every custom constraint will now have to change this piece of code within it. But it's too late for #27917. Maybe another time there will be need to change the message or exception type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that, but I don't agree: designing the code to make such changes easy is not a target at all to me. Software architecture should be built around things that change, not those that don't (#27917 is not a change that should be centralized to me.)

{
if (!$constraint instanceof $expectedClass) {
throw new UnexpectedTypeException($constraint, $expectedClass);
}
}

/**
* Get a string value.
*
* @throws UnexpectedTypeException
*/
final protected static function toString($value): ?string
{
if (null === $value) {
return null;
}

if (!is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string or null');
}

if ('' === $value = (string) $value) {
return null;
}

return $value;
}

/**
* Returns a string representation of the type of the value.
*
Expand Down
12 changes: 6 additions & 6 deletions src/Symfony/Component/Validator/Constraints/BicValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
* file that was distributed with this source code.
*/

use Symfony\Component\Validator\Constraints\Bic;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use statement should be below the namespace


namespace Symfony\Component\Validator\Constraints;

use Symfony\Component\Intl\Intl;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

/**
* @author Michael Hirschler <[email protected]>
Expand All @@ -28,12 +29,11 @@ class BicValidator extends ConstraintValidator
*/
public function validate($value, Constraint $constraint)
{
if (null === $value || '' === $value) {
return;
}
/* @var Bic $constraint */
self::testConstraint($constraint, Bic::class);

if (!is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
if (null === $value = self::toString($value)) {
return;
}

$canonicalize = str_replace(' ', '', $value);
Expand Down