Skip to content

Instantly share code, notes, and snippets.

@vudaltsov
Last active September 22, 2021 15:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vudaltsov/8e652c122e2344ce8574635b5514a975 to your computer and use it in GitHub Desktop.
Save vudaltsov/8e652c122e2344ce8574635b5514a975 to your computer and use it in GitHub Desktop.
Conditional validator
<?php
declare(strict_types=1);
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraints\Composite;
/**
* @Annotation()
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*/
final class Condition extends Composite
{
public $expression;
public $constraints = [];
/**
* {@inheritdoc}
*/
public function getDefaultOption()
{
return 'expression';
}
/**
* {@inheritdoc}
*/
public function getRequiredOptions()
{
return [
'expression',
];
}
/**
* {@inheritdoc}
*/
protected function getCompositeOption()
{
return 'constraints';
}
}
<?php
declare(strict_types=1);
namespace App\Validator\Constraints;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
final class ConditionValidator extends ConstraintValidator
{
private $expressionLanguage;
public function __construct(?ExpressionLanguage $expressionLanguage = null)
{
$this->expressionLanguage = $expressionLanguage ?? new ExpressionLanguage();
}
/**
* {@inheritdoc}
*/
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof Condition) {
throw new UnexpectedTypeException($constraint, Condition::class);
}
$condition = $this->expressionLanguage->evaluate($constraint->expression, [
'value' => $value,
'this' => $this->context->getObject(),
]);
if ($condition) {
$this->context->getValidator()
->inContext($this->context)
->validate($value, $constraint->constraints);
}
}
}
<?php
declare(strict_types=1);
namespace App\Dto;
use App\Validator\Constraints\Condition;
use Symfony\Component\Validator\Constraints as Assert;
final class Passport
{
public $country;
/**
* @Condition("'ru' === this.country", {
* @Assert\NotNull(),
* })
*/
public $series;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment