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

[Validator] remove deprecated code paths #31898

Merged
merged 1 commit into from Jun 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Symfony/Component/Validator/CHANGELOG.md
Expand Up @@ -5,10 +5,13 @@ CHANGELOG
-----

* removed the `checkDNS` and `dnsMessage` options of the `Url` constraint
* removed the `checkMX`, `checkHost` and `strict` options of the `Email` constraint
* removed support for validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`
* removed support for using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints without `symfony/intl`
* removed support for using the `Email` constraint without `egulias/email-validator`
* removed support for using the `Expression` constraint without `symfony/expression-language`
* changed default value of `canonicalize` option of `Locale` constraint to `true`
* removed `ValidatorBuilderInterface`

4.4.0
-----
Expand Down
41 changes: 1 addition & 40 deletions src/Symfony/Component/Validator/Constraints/Email.php
Expand Up @@ -30,20 +30,8 @@ class Email extends Constraint

const INVALID_FORMAT_ERROR = 'bd79c0ab-ddba-46cc-a703-a7a4b08de310';

/**
* @deprecated since Symfony 4.2.
*/
const MX_CHECK_FAILED_ERROR = 'bf447c1c-0266-4e10-9c6c-573df282e413';

/**
* @deprecated since Symfony 4.2.
*/
const HOST_CHECK_FAILED_ERROR = '7da53a8b-56f3-4288-bb3e-ee9ede4ef9a1';

protected static $errorNames = [
self::INVALID_FORMAT_ERROR => 'STRICT_CHECK_FAILED_ERROR',
self::MX_CHECK_FAILED_ERROR => 'MX_CHECK_FAILED_ERROR',
self::HOST_CHECK_FAILED_ERROR => 'HOST_CHECK_FAILED_ERROR',
];

/**
Expand All @@ -58,45 +46,18 @@ class Email extends Constraint
];

public $message = 'This value is not a valid email address.';

/**
* @deprecated since Symfony 4.2.
*/
public $checkMX = false;

/**
* @deprecated since Symfony 4.2.
*/
public $checkHost = false;

/**
* @deprecated since Symfony 4.1, set mode to "strict" instead.
*/
public $strict;
public $mode;
public $normalizer;

public function __construct($options = null)
{
if (\is_array($options) && \array_key_exists('strict', $options)) {
@trigger_error(sprintf('The "strict" property is deprecated since Symfony 4.1. Use "mode"=>"%s" instead.', self::VALIDATION_MODE_STRICT), E_USER_DEPRECATED);
}

if (\is_array($options) && \array_key_exists('checkMX', $options)) {
@trigger_error('The "checkMX" option is deprecated since Symfony 4.2.', E_USER_DEPRECATED);
}

if (\is_array($options) && \array_key_exists('checkHost', $options)) {
@trigger_error('The "checkHost" option is deprecated since Symfony 4.2.', E_USER_DEPRECATED);
}

if (\is_array($options) && \array_key_exists('mode', $options) && !\in_array($options['mode'], self::$validationModes, true)) {
throw new InvalidArgumentException('The "mode" parameter value is not valid.');
}

parent::__construct($options);

if ((self::VALIDATION_MODE_STRICT === $this->mode || true === $this->strict) && !class_exists(StrictEmailValidator::class)) {
if (self::VALIDATION_MODE_STRICT === $this->mode && !class_exists(StrictEmailValidator::class)) {
throw new LogicException(sprintf('The "egulias/email-validator" component is required to use the "%s" constraint in strict mode.', __CLASS__));
}

Expand Down
72 changes: 3 additions & 69 deletions src/Symfony/Component/Validator/Constraints/EmailValidator.php
Expand Up @@ -23,37 +23,18 @@
*/
class EmailValidator extends ConstraintValidator
{
/**
* @internal
*/
const PATTERN_HTML5 = '/^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/';

/**
* @internal
*/
const PATTERN_LOOSE = '/^.+\@\S+\.\S+$/';
private const PATTERN_HTML5 = '/^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/';
private const PATTERN_LOOSE = '/^.+\@\S+\.\S+$/';

private static $emailPatterns = [
Email::VALIDATION_MODE_LOOSE => self::PATTERN_LOOSE,
Email::VALIDATION_MODE_HTML5 => self::PATTERN_HTML5,
];

/**
* @var string
*/
private $defaultMode;

/**
* @param string $defaultMode
*/
public function __construct($defaultMode = Email::VALIDATION_MODE_LOOSE)
public function __construct(string $defaultMode = Email::VALIDATION_MODE_LOOSE)
{
if (\is_bool($defaultMode)) {
@trigger_error(sprintf('Calling `new %s(%s)` is deprecated since Symfony 4.1, use `new %s("%s")` instead.', self::class, $defaultMode ? 'true' : 'false', self::class, $defaultMode ? Email::VALIDATION_MODE_STRICT : Email::VALIDATION_MODE_LOOSE), E_USER_DEPRECATED);

$defaultMode = $defaultMode ? Email::VALIDATION_MODE_STRICT : Email::VALIDATION_MODE_LOOSE;
}

if (!\in_array($defaultMode, Email::$validationModes, true)) {
throw new \InvalidArgumentException('The "defaultMode" parameter value is not valid.');
}
Expand Down Expand Up @@ -84,16 +65,6 @@ public function validate($value, Constraint $constraint)
$value = ($constraint->normalizer)($value);
}

if (null !== $constraint->strict) {
@trigger_error(sprintf('The %s::$strict property is deprecated since Symfony 4.1. Use %s::mode="%s" instead.', Email::class, Email::class, Email::VALIDATION_MODE_STRICT), E_USER_DEPRECATED);

if ($constraint->strict) {
$constraint->mode = Email::VALIDATION_MODE_STRICT;
} else {
$constraint->mode = Email::VALIDATION_MODE_LOOSE;
}
}

if (null === $constraint->mode) {
$constraint->mode = $this->defaultMode;
}
Expand Down Expand Up @@ -128,42 +99,5 @@ public function validate($value, Constraint $constraint)

return;
}

$host = (string) substr($value, strrpos($value, '@') + 1);

// Check for host DNS resource records
if ($constraint->checkMX) {
if (!$this->checkMX($host)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->setCode(Email::MX_CHECK_FAILED_ERROR)
->addViolation();
}

return;
}

if ($constraint->checkHost && !$this->checkHost($host)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->setCode(Email::HOST_CHECK_FAILED_ERROR)
->addViolation();
}
}

/**
* Check DNS Records for MX type.
*/
private function checkMX(string $host): bool
{
return '' !== $host && checkdnsrr($host, 'MX');
}

/**
* Check if one of MX, A or AAAA DNS RR exists.
*/
private function checkHost(string $host): bool
{
return '' !== $host && ($this->checkMX($host) || (checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA')));
}
}
6 changes: 1 addition & 5 deletions src/Symfony/Component/Validator/Constraints/Locale.php
Expand Up @@ -30,14 +30,10 @@ class Locale extends Constraint
];

public $message = 'This value is not a valid locale.';
public $canonicalize = false;
public $canonicalize = true;

public function __construct($options = null)
{
if (!($options['canonicalize'] ?? false)) {
@trigger_error('The "canonicalize" option with value "false" is deprecated since Symfony 4.1, set it to "true" instead.', E_USER_DEPRECATED);
}

if (!class_exists(Locales::class)) {
throw new LogicException('The Intl component is required to use the Locale constraint. Try running "composer require symfony/intl".');
}
Expand Down
19 changes: 3 additions & 16 deletions src/Symfony/Component/Validator/Context/ExecutionContext.php
Expand Up @@ -11,7 +11,6 @@

namespace Symfony\Component\Validator\Context;

use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
Expand Down Expand Up @@ -128,24 +127,12 @@ class ExecutionContext implements ExecutionContextInterface
private $initializedObjects;

/**
* Creates a new execution context.
* @param mixed $root The root value of the validated object graph
*
* @param ValidatorInterface $validator The validator
* @param mixed $root The root value of the
* validated object graph
* @param TranslatorInterface $translator The translator
* @param string|null $translationDomain The translation domain to
* use for translating
* violation messages
*
* @internal Called by {@link ExecutionContextFactory}. Should not be used
* in user code.
* @internal Called by {@link ExecutionContextFactory}. Should not be used in user code.
*/
public function __construct(ValidatorInterface $validator, $root, $translator, string $translationDomain = null)
public function __construct(ValidatorInterface $validator, $root, TranslatorInterface $translator, string $translationDomain = null)
{
if (!$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) {
throw new \TypeError(sprintf('Argument 3 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
}
$this->validator = $validator;
$this->root = $root;
$this->translator = $translator;
Expand Down
Expand Up @@ -11,7 +11,6 @@

namespace Symfony\Component\Validator\Context;

use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

Expand All @@ -27,20 +26,8 @@ class ExecutionContextFactory implements ExecutionContextFactoryInterface
private $translator;
private $translationDomain;

/**
* Creates a new context factory.
*
* @param TranslatorInterface $translator The translator
* @param string|null $translationDomain The translation domain to
* use for translating
* violation messages
*/
public function __construct($translator, string $translationDomain = null)
public function __construct(TranslatorInterface $translator, string $translationDomain = null)
{
if (!$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) {
throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
}

$this->translator = $translator;
$this->translationDomain = $translationDomain;
}
Expand Down
Expand Up @@ -11,13 +11,9 @@

namespace Symfony\Component\Validator\DependencyInjection;

use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
use Symfony\Component\Validator\Util\LegacyTranslatorProxy;

/**
* @author Fabien Potencier <fabien@symfony.com>
Expand Down Expand Up @@ -46,33 +42,5 @@ public function process(ContainerBuilder $container)
}

$container->getDefinition($this->builderService)->addMethodCall('addObjectInitializers', [$initializers]);

// @deprecated logic, to be removed in Symfony 5.0
$builder = $container->getDefinition($this->builderService);
$calls = [];

foreach ($builder->getMethodCalls() as list($method, $arguments)) {
if ('setTranslator' === $method) {
if (!$arguments[0] instanceof Reference) {
$translator = $arguments[0];
} elseif ($container->has($arguments[0])) {
$translator = $container->findDefinition($arguments[0]);
} else {
continue;
}

while (!($class = $translator->getClass()) && $translator instanceof ChildDefinition) {
$translator = $container->findDefinition($translator->getParent());
}

if (!is_subclass_of($class, LegacyTranslatorInterface::class)) {
$arguments[0] = (new Definition(LegacyTranslatorProxy::class))->addArgument($arguments[0]);
}
}

$calls[] = [$method, $arguments];
}

$builder->setMethodCalls($calls);
}
}
11 changes: 0 additions & 11 deletions src/Symfony/Component/Validator/Tests/Constraints/EmailTest.php
Expand Up @@ -16,17 +16,6 @@

class EmailTest extends TestCase
{
/**
* @expectedDeprecation The "strict" property is deprecated since Symfony 4.1. Use "mode"=>"strict" instead.
* @group legacy
*/
public function testLegacyConstructorStrict()
{
$subject = new Email(['strict' => true]);

$this->assertTrue($subject->strict);
}

public function testConstructorStrict()
{
$subject = new Email(['mode' => Email::VALIDATION_MODE_STRICT]);
Expand Down