feature #38499 [Validator] Upgraded constraints to enable named arguments and attributes (derrabus)
This PR was squashed before being merged into the 5.x branch.
Discussion
----------
[Validator] Upgraded constraints to enable named arguments and attributes
| Q | A
| ------------- | ---
| Branch? | 5.2
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | #38096
| License | MIT
| Doc PR | TODO with symfony/symfony-docs#14305
This PR enables all remaining atomic (!= composite) constraints to be used as attributes.
The only exception is `UniqueEntity` from Doctrine bridge because we don't have a Doctrine ORM release yet that supports PHP 8. So I could migrate that one as well, but I cannot really test it.
Commits
-------
fb99eb2052
[Validator] Upgraded constraints to enable named arguments and attributes
This commit is contained in:
commit
87920d266e
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Security\Core\Tests\Validator\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
class UserPasswordTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testValidatedByStandardValidator()
|
||||||
|
{
|
||||||
|
$constraint = new UserPassword();
|
||||||
|
|
||||||
|
self::assertSame('security.validator.user_password', $constraint->validatedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideServiceValidatedConstraints
|
||||||
|
*/
|
||||||
|
public function testValidatedByService(UserPassword $constraint)
|
||||||
|
{
|
||||||
|
self::assertSame('my_service', $constraint->validatedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideServiceValidatedConstraints(): iterable
|
||||||
|
{
|
||||||
|
yield 'Doctrine style' => [new UserPassword(['service' => 'my_service'])];
|
||||||
|
|
||||||
|
if (\PHP_VERSION_ID < 80000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield 'named arguments' => [eval('return new \Symfony\Component\Security\Core\Validator\Constraints\UserPassword(service: "my_service");')];
|
||||||
|
|
||||||
|
$metadata = new ClassMetadata(UserPasswordDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
yield 'attribute' => [$metadata->properties['b']->constraints[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(UserPasswordDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'UserPasswordDummy'], $bConstraint->groups);
|
||||||
|
self::assertNull($bConstraint->payload);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserPasswordDummy
|
||||||
|
{
|
||||||
|
#[UserPassword]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[UserPassword(service: 'my_service', message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[UserPassword(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -56,12 +56,11 @@ abstract class UserPasswordValidatorTest extends ConstraintValidatorTestCase
|
|||||||
parent::setUp();
|
parent::setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPasswordIsValid()
|
/**
|
||||||
|
* @dataProvider provideConstraints
|
||||||
|
*/
|
||||||
|
public function testPasswordIsValid(UserPassword $constraint)
|
||||||
{
|
{
|
||||||
$constraint = new UserPassword([
|
|
||||||
'message' => 'myMessage',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->encoder->expects($this->once())
|
$this->encoder->expects($this->once())
|
||||||
->method('isPasswordValid')
|
->method('isPasswordValid')
|
||||||
->with(static::PASSWORD, 'secret', static::SALT)
|
->with(static::PASSWORD, 'secret', static::SALT)
|
||||||
@ -72,12 +71,11 @@ abstract class UserPasswordValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPasswordIsNotValid()
|
/**
|
||||||
|
* @dataProvider provideConstraints
|
||||||
|
*/
|
||||||
|
public function testPasswordIsNotValid(UserPassword $constraint)
|
||||||
{
|
{
|
||||||
$constraint = new UserPassword([
|
|
||||||
'message' => 'myMessage',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->encoder->expects($this->once())
|
$this->encoder->expects($this->once())
|
||||||
->method('isPasswordValid')
|
->method('isPasswordValid')
|
||||||
->with(static::PASSWORD, 'secret', static::SALT)
|
->with(static::PASSWORD, 'secret', static::SALT)
|
||||||
@ -89,6 +87,15 @@ abstract class UserPasswordValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideConstraints(): iterable
|
||||||
|
{
|
||||||
|
yield 'Doctrine style' => [new UserPassword(['message' => 'myMessage'])];
|
||||||
|
|
||||||
|
if (\PHP_VERSION_ID >= 80000) {
|
||||||
|
yield 'named arguments' => [eval('return new \Symfony\Component\Security\Core\Validator\Constraints\UserPassword(message: "myMessage");')];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider emptyPasswordData
|
* @dataProvider emptyPasswordData
|
||||||
*/
|
*/
|
||||||
|
@ -17,11 +17,20 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
* @Annotation
|
* @Annotation
|
||||||
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
|
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class UserPassword extends Constraint
|
class UserPassword extends Constraint
|
||||||
{
|
{
|
||||||
public $message = 'This value should be the user\'s current password.';
|
public $message = 'This value should be the user\'s current password.';
|
||||||
public $service = 'security.validator.user_password';
|
public $service = 'security.validator.user_password';
|
||||||
|
|
||||||
|
public function __construct(array $options = null, string $message = null, string $service = null, array $groups = null, $payload = null)
|
||||||
|
{
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->service = $service ?? $this->service;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -28,13 +28,14 @@
|
|||||||
"symfony/expression-language": "^4.4|^5.0",
|
"symfony/expression-language": "^4.4|^5.0",
|
||||||
"symfony/http-foundation": "^4.4|^5.0",
|
"symfony/http-foundation": "^4.4|^5.0",
|
||||||
"symfony/ldap": "^4.4|^5.0",
|
"symfony/ldap": "^4.4|^5.0",
|
||||||
"symfony/validator": "^4.4|^5.0",
|
"symfony/validator": "^5.2",
|
||||||
"psr/log": "~1.0"
|
"psr/log": "~1.0"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"symfony/event-dispatcher": "<4.4",
|
"symfony/event-dispatcher": "<4.4",
|
||||||
"symfony/security-guard": "<4.4",
|
"symfony/security-guard": "<4.4",
|
||||||
"symfony/ldap": "<4.4"
|
"symfony/ldap": "<4.4",
|
||||||
|
"symfony/validator": "<5.2"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"psr/container-implementation": "To instantiate the Security class",
|
"psr/container-implementation": "To instantiate the Security class",
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Constraints;
|
|||||||
|
|
||||||
use Symfony\Component\Intl\Countries;
|
use Symfony\Component\Intl\Countries;
|
||||||
use Symfony\Component\PropertyAccess\PropertyAccess;
|
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyPathInterface;
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||||
use Symfony\Component\Validator\Exception\LogicException;
|
use Symfony\Component\Validator\Exception\LogicException;
|
||||||
@ -23,6 +24,7 @@ use Symfony\Component\Validator\Exception\LogicException;
|
|||||||
*
|
*
|
||||||
* @author Michael Hirschler <michael.vhirsch@gmail.com>
|
* @author Michael Hirschler <michael.vhirsch@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Bic extends Constraint
|
class Bic extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_LENGTH_ERROR = '66dad313-af0b-4214-8566-6c799be9789c';
|
const INVALID_LENGTH_ERROR = '66dad313-af0b-4214-8566-6c799be9789c';
|
||||||
@ -45,20 +47,33 @@ class Bic extends Constraint
|
|||||||
public $iban;
|
public $iban;
|
||||||
public $ibanPropertyPath;
|
public $ibanPropertyPath;
|
||||||
|
|
||||||
public function __construct($options = null)
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param string|PropertyPathInterface|null $ibanPropertyPath
|
||||||
|
*/
|
||||||
|
public function __construct(array $options = null, string $message = null, string $iban = null, $ibanPropertyPath = null, string $ibanMessage = null, array $groups = null, $payload = null)
|
||||||
{
|
{
|
||||||
if (!class_exists(Countries::class)) {
|
if (!class_exists(Countries::class)) {
|
||||||
throw new LogicException('The Intl component is required to use the Bic constraint. Try running "composer require symfony/intl".');
|
throw new LogicException('The Intl component is required to use the Bic constraint. Try running "composer require symfony/intl".');
|
||||||
}
|
}
|
||||||
|
if (null !== $ibanPropertyPath && !\is_string($ibanPropertyPath) && !$ibanPropertyPath instanceof PropertyPathInterface) {
|
||||||
|
throw new \TypeError(sprintf('"%s": Expected argument $ibanPropertyPath to be either null, a string or an instance of "%s", got "%s".', __METHOD__, PropertyPathInterface::class, get_debug_type($ibanPropertyPath)));
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($options['iban']) && isset($options['ibanPropertyPath'])) {
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->ibanMessage = $ibanMessage ?? $this->ibanMessage;
|
||||||
|
$this->iban = $iban ?? $this->iban;
|
||||||
|
$this->ibanPropertyPath = $ibanPropertyPath ?? $this->ibanPropertyPath;
|
||||||
|
|
||||||
|
if (null !== $this->iban && null !== $this->ibanPropertyPath) {
|
||||||
throw new ConstraintDefinitionException('The "iban" and "ibanPropertyPath" options of the Iban constraint cannot be used at the same time.');
|
throw new ConstraintDefinitionException('The "iban" and "ibanPropertyPath" options of the Iban constraint cannot be used at the same time.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($options['ibanPropertyPath']) && !class_exists(PropertyAccess::class)) {
|
if (null !== $this->ibanPropertyPath && !class_exists(PropertyAccess::class)) {
|
||||||
throw new LogicException(sprintf('The "symfony/property-access" component is required to use the "%s" constraint with the "ibanPropertyPath" option.', self::class));
|
throw new LogicException(sprintf('The "symfony/property-access" component is required to use the "%s" constraint with the "ibanPropertyPath" option.', self::class));
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,22 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
* @author Tim Nagel <t.nagel@infinite.net.au>
|
* @author Tim Nagel <t.nagel@infinite.net.au>
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class CardScheme extends Constraint
|
class CardScheme extends Constraint
|
||||||
{
|
{
|
||||||
|
const AMEX = 'AMEX';
|
||||||
|
const CHINA_UNIONPAY = 'CHINA_UNIONPAY';
|
||||||
|
const DINERS = 'DINERS';
|
||||||
|
const DISCOVER = 'DISCOVER';
|
||||||
|
const INSTAPAYMENT = 'INSTAPAYMENT';
|
||||||
|
const JCB = 'JCB';
|
||||||
|
const LASER = 'LASER';
|
||||||
|
const MAESTRO = 'MAESTRO';
|
||||||
|
const MASTERCARD = 'MASTERCARD';
|
||||||
|
const MIR = 'MIR';
|
||||||
|
const UATP = 'UATP';
|
||||||
|
const VISA = 'VISA';
|
||||||
|
|
||||||
const NOT_NUMERIC_ERROR = 'a2ad9231-e827-485f-8a1e-ef4d9a6d5c2e';
|
const NOT_NUMERIC_ERROR = 'a2ad9231-e827-485f-8a1e-ef4d9a6d5c2e';
|
||||||
const INVALID_FORMAT_ERROR = 'a8faedbf-1c2f-4695-8d22-55783be8efed';
|
const INVALID_FORMAT_ERROR = 'a8faedbf-1c2f-4695-8d22-55783be8efed';
|
||||||
|
|
||||||
@ -35,6 +49,24 @@ class CardScheme extends Constraint
|
|||||||
public $message = 'Unsupported card type or invalid card number.';
|
public $message = 'Unsupported card type or invalid card number.';
|
||||||
public $schemes;
|
public $schemes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param array|string $schemes The schemes to validate against or a set of options
|
||||||
|
*/
|
||||||
|
public function __construct($schemes, string $message = null, array $groups = null, $payload = null, array $options = [])
|
||||||
|
{
|
||||||
|
if (\is_array($schemes) && \is_string(key($schemes))) {
|
||||||
|
$options = array_merge($schemes, $options);
|
||||||
|
} else {
|
||||||
|
$options['value'] = $schemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
public function getDefaultOption()
|
public function getDefaultOption()
|
||||||
{
|
{
|
||||||
return 'schemes';
|
return 'schemes';
|
||||||
|
@ -28,44 +28,44 @@ class CardSchemeValidator extends ConstraintValidator
|
|||||||
{
|
{
|
||||||
protected $schemes = [
|
protected $schemes = [
|
||||||
// American Express card numbers start with 34 or 37 and have 15 digits.
|
// American Express card numbers start with 34 or 37 and have 15 digits.
|
||||||
'AMEX' => [
|
CardScheme::AMEX => [
|
||||||
'/^3[47][0-9]{13}$/',
|
'/^3[47][0-9]{13}$/',
|
||||||
],
|
],
|
||||||
// China UnionPay cards start with 62 and have between 16 and 19 digits.
|
// China UnionPay cards start with 62 and have between 16 and 19 digits.
|
||||||
// Please note that these cards do not follow Luhn Algorithm as a checksum.
|
// Please note that these cards do not follow Luhn Algorithm as a checksum.
|
||||||
'CHINA_UNIONPAY' => [
|
CardScheme::CHINA_UNIONPAY => [
|
||||||
'/^62[0-9]{14,17}$/',
|
'/^62[0-9]{14,17}$/',
|
||||||
],
|
],
|
||||||
// Diners Club card numbers begin with 300 through 305, 36 or 38. All have 14 digits.
|
// Diners Club card numbers begin with 300 through 305, 36 or 38. All have 14 digits.
|
||||||
// There are Diners Club cards that begin with 5 and have 16 digits.
|
// There are Diners Club cards that begin with 5 and have 16 digits.
|
||||||
// These are a joint venture between Diners Club and MasterCard, and should be processed like a MasterCard.
|
// These are a joint venture between Diners Club and MasterCard, and should be processed like a MasterCard.
|
||||||
'DINERS' => [
|
CardScheme::DINERS => [
|
||||||
'/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/',
|
'/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/',
|
||||||
],
|
],
|
||||||
// Discover card numbers begin with 6011, 622126 through 622925, 644 through 649 or 65.
|
// Discover card numbers begin with 6011, 622126 through 622925, 644 through 649 or 65.
|
||||||
// All have 16 digits.
|
// All have 16 digits.
|
||||||
'DISCOVER' => [
|
CardScheme::DISCOVER => [
|
||||||
'/^6011[0-9]{12}$/',
|
'/^6011[0-9]{12}$/',
|
||||||
'/^64[4-9][0-9]{13}$/',
|
'/^64[4-9][0-9]{13}$/',
|
||||||
'/^65[0-9]{14}$/',
|
'/^65[0-9]{14}$/',
|
||||||
'/^622(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|91[0-9]|92[0-5])[0-9]{10}$/',
|
'/^622(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|91[0-9]|92[0-5])[0-9]{10}$/',
|
||||||
],
|
],
|
||||||
// InstaPayment cards begin with 637 through 639 and have 16 digits.
|
// InstaPayment cards begin with 637 through 639 and have 16 digits.
|
||||||
'INSTAPAYMENT' => [
|
CardScheme::INSTAPAYMENT => [
|
||||||
'/^63[7-9][0-9]{13}$/',
|
'/^63[7-9][0-9]{13}$/',
|
||||||
],
|
],
|
||||||
// JCB cards beginning with 2131 or 1800 have 15 digits.
|
// JCB cards beginning with 2131 or 1800 have 15 digits.
|
||||||
// JCB cards beginning with 35 have 16 digits.
|
// JCB cards beginning with 35 have 16 digits.
|
||||||
'JCB' => [
|
CardScheme::JCB => [
|
||||||
'/^(?:2131|1800|35[0-9]{3})[0-9]{11}$/',
|
'/^(?:2131|1800|35[0-9]{3})[0-9]{11}$/',
|
||||||
],
|
],
|
||||||
// Laser cards begin with either 6304, 6706, 6709 or 6771 and have between 16 and 19 digits.
|
// Laser cards begin with either 6304, 6706, 6709 or 6771 and have between 16 and 19 digits.
|
||||||
'LASER' => [
|
CardScheme::LASER => [
|
||||||
'/^(6304|670[69]|6771)[0-9]{12,15}$/',
|
'/^(6304|670[69]|6771)[0-9]{12,15}$/',
|
||||||
],
|
],
|
||||||
// Maestro international cards begin with 675900..675999 and have between 12 and 19 digits.
|
// Maestro international cards begin with 675900..675999 and have between 12 and 19 digits.
|
||||||
// Maestro UK cards begin with either 500000..509999 or 560000..699999 and have between 12 and 19 digits.
|
// Maestro UK cards begin with either 500000..509999 or 560000..699999 and have between 12 and 19 digits.
|
||||||
'MAESTRO' => [
|
CardScheme::MAESTRO => [
|
||||||
'/^(6759[0-9]{2})[0-9]{6,13}$/',
|
'/^(6759[0-9]{2})[0-9]{6,13}$/',
|
||||||
'/^(50[0-9]{4})[0-9]{6,13}$/',
|
'/^(50[0-9]{4})[0-9]{6,13}$/',
|
||||||
'/^5[6-9][0-9]{10,17}$/',
|
'/^5[6-9][0-9]{10,17}$/',
|
||||||
@ -73,20 +73,20 @@ class CardSchemeValidator extends ConstraintValidator
|
|||||||
],
|
],
|
||||||
// All MasterCard numbers start with the numbers 51 through 55. All have 16 digits.
|
// All MasterCard numbers start with the numbers 51 through 55. All have 16 digits.
|
||||||
// October 2016 MasterCard numbers can also start with 222100 through 272099.
|
// October 2016 MasterCard numbers can also start with 222100 through 272099.
|
||||||
'MASTERCARD' => [
|
CardScheme::MASTERCARD => [
|
||||||
'/^5[1-5][0-9]{14}$/',
|
'/^5[1-5][0-9]{14}$/',
|
||||||
'/^2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12})$/',
|
'/^2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12})$/',
|
||||||
],
|
],
|
||||||
// Payment system MIR numbers start with 220, then 1 digit from 0 to 4, then 12 digits
|
// Payment system MIR numbers start with 220, then 1 digit from 0 to 4, then 12 digits
|
||||||
'MIR' => [
|
CardScheme::MIR => [
|
||||||
'/^220[0-4][0-9]{12}$/',
|
'/^220[0-4][0-9]{12}$/',
|
||||||
],
|
],
|
||||||
// All UATP card numbers start with a 1 and have a length of 15 digits.
|
// All UATP card numbers start with a 1 and have a length of 15 digits.
|
||||||
'UATP' => [
|
CardScheme::UATP => [
|
||||||
'/^1[0-9]{14}$/',
|
'/^1[0-9]{14}$/',
|
||||||
],
|
],
|
||||||
// All Visa card numbers start with a 4 and have a length of 13, 16, or 19 digits.
|
// All Visa card numbers start with a 4 and have a length of 13, 16, or 19 digits.
|
||||||
'VISA' => [
|
CardScheme::VISA => [
|
||||||
'/^4([0-9]{12}|[0-9]{15}|[0-9]{18})$/',
|
'/^4([0-9]{12}|[0-9]{15}|[0-9]{18})$/',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -20,9 +20,10 @@ use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
|||||||
*
|
*
|
||||||
* @author Jules Pietri <jules@heahprod.com>
|
* @author Jules Pietri <jules@heahprod.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS)]
|
||||||
class Cascade extends Constraint
|
class Cascade extends Constraint
|
||||||
{
|
{
|
||||||
public function __construct($options = null)
|
public function __construct(array $options = null)
|
||||||
{
|
{
|
||||||
if (\is_array($options) && \array_key_exists('groups', $options)) {
|
if (\is_array($options) && \array_key_exists('groups', $options)) {
|
||||||
throw new ConstraintDefinitionException(sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__));
|
throw new ConstraintDefinitionException(sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__));
|
||||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Validator\Exception\MissingOptionsException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Count extends Constraint
|
class Count extends Constraint
|
||||||
{
|
{
|
||||||
const TOO_FEW_ERROR = 'bef8e338-6ae5-4caf-b8e2-50e7b0579e69';
|
const TOO_FEW_ERROR = 'bef8e338-6ae5-4caf-b8e2-50e7b0579e69';
|
||||||
@ -40,19 +41,47 @@ class Count extends Constraint
|
|||||||
public $max;
|
public $max;
|
||||||
public $divisibleBy;
|
public $divisibleBy;
|
||||||
|
|
||||||
public function __construct($options = null)
|
/**
|
||||||
{
|
* {@inheritdoc}
|
||||||
if (null !== $options && !\is_array($options)) {
|
*
|
||||||
$options = [
|
* @param int|array|null $exactly The expected exact count or a set of options
|
||||||
'min' => $options,
|
*/
|
||||||
'max' => $options,
|
public function __construct(
|
||||||
];
|
$exactly = null,
|
||||||
} elseif (\is_array($options) && isset($options['value']) && !isset($options['min']) && !isset($options['max'])) {
|
int $min = null,
|
||||||
$options['min'] = $options['max'] = $options['value'];
|
int $max = null,
|
||||||
unset($options['value']);
|
int $divisibleBy = null,
|
||||||
|
string $exactMessage = null,
|
||||||
|
string $minMessage = null,
|
||||||
|
string $maxMessage = null,
|
||||||
|
string $divisibleByMessage = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null,
|
||||||
|
array $options = []
|
||||||
|
) {
|
||||||
|
if (\is_array($exactly)) {
|
||||||
|
$options = array_merge($exactly, $options);
|
||||||
|
$exactly = $options['value'] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
$min = $min ?? $options['min'] ?? null;
|
||||||
|
$max = $max ?? $options['max'] ?? null;
|
||||||
|
|
||||||
|
unset($options['value'], $options['min'], $options['max']);
|
||||||
|
|
||||||
|
if (null !== $exactly && null === $min && null === $max) {
|
||||||
|
$min = $max = $exactly;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->min = $min;
|
||||||
|
$this->max = $max;
|
||||||
|
$this->divisibleBy = $divisibleBy ?? $this->divisibleBy;
|
||||||
|
$this->exactMessage = $exactMessage ?? $this->exactMessage;
|
||||||
|
$this->minMessage = $minMessage ?? $this->minMessage;
|
||||||
|
$this->maxMessage = $maxMessage ?? $this->maxMessage;
|
||||||
|
$this->divisibleByMessage = $divisibleByMessage ?? $this->divisibleByMessage;
|
||||||
|
|
||||||
if (null === $this->min && null === $this->max && null === $this->divisibleBy) {
|
if (null === $this->min && null === $this->max && null === $this->divisibleBy) {
|
||||||
throw new MissingOptionsException(sprintf('Either option "min", "max" or "divisibleBy" must be given for constraint "%s".', __CLASS__), ['min', 'max', 'divisibleBy']);
|
throw new MissingOptionsException(sprintf('Either option "min", "max" or "divisibleBy" must be given for constraint "%s".', __CLASS__), ['min', 'max', 'divisibleBy']);
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Validator\Exception\LogicException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Country extends Constraint
|
class Country extends Constraint
|
||||||
{
|
{
|
||||||
const NO_SUCH_COUNTRY_ERROR = '8f900c12-61bd-455d-9398-996cd040f7f0';
|
const NO_SUCH_COUNTRY_ERROR = '8f900c12-61bd-455d-9398-996cd040f7f0';
|
||||||
@ -32,12 +33,20 @@ class Country extends Constraint
|
|||||||
public $message = 'This value is not a valid country.';
|
public $message = 'This value is not a valid country.';
|
||||||
public $alpha3 = false;
|
public $alpha3 = false;
|
||||||
|
|
||||||
public function __construct($options = null)
|
public function __construct(
|
||||||
{
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
bool $alpha3 = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
if (!class_exists(Countries::class)) {
|
if (!class_exists(Countries::class)) {
|
||||||
throw new LogicException('The Intl component is required to use the Country constraint. Try running "composer require symfony/intl".');
|
throw new LogicException('The Intl component is required to use the Country constraint. Try running "composer require symfony/intl".');
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->alpha3 = $alpha3 ?? $this->alpha3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ use Symfony\Component\Validator\Exception\LogicException;
|
|||||||
* @author Miha Vrhovnik <miha.vrhovnik@pagein.si>
|
* @author Miha Vrhovnik <miha.vrhovnik@pagein.si>
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Currency extends Constraint
|
class Currency extends Constraint
|
||||||
{
|
{
|
||||||
const NO_SUCH_CURRENCY_ERROR = '69945ac1-2db4-405f-bec7-d2772f73df52';
|
const NO_SUCH_CURRENCY_ERROR = '69945ac1-2db4-405f-bec7-d2772f73df52';
|
||||||
@ -32,12 +33,14 @@ class Currency extends Constraint
|
|||||||
|
|
||||||
public $message = 'This value is not a valid currency.';
|
public $message = 'This value is not a valid currency.';
|
||||||
|
|
||||||
public function __construct($options = null)
|
public function __construct(array $options = null, string $message = null, array $groups = null, $payload = null)
|
||||||
{
|
{
|
||||||
if (!class_exists(Currencies::class)) {
|
if (!class_exists(Currencies::class)) {
|
||||||
throw new LogicException('The Intl component is required to use the Currency constraint. Try running "composer require symfony/intl".');
|
throw new LogicException('The Intl component is required to use the Currency constraint. Try running "composer require symfony/intl".');
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Date extends Constraint
|
class Date extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_FORMAT_ERROR = '69819696-02ac-4a99-9ff0-14e127c4d1bc';
|
const INVALID_FORMAT_ERROR = '69819696-02ac-4a99-9ff0-14e127c4d1bc';
|
||||||
@ -30,4 +31,11 @@ class Date extends Constraint
|
|||||||
];
|
];
|
||||||
|
|
||||||
public $message = 'This value is not a valid date.';
|
public $message = 'This value is not a valid date.';
|
||||||
|
|
||||||
|
public function __construct(array $options = null, string $message = null, array $groups = null, $payload = null)
|
||||||
|
{
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class DateTime extends Constraint
|
class DateTime extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_FORMAT_ERROR = '1a9da513-2640-4f84-9b6a-4d99dcddc628';
|
const INVALID_FORMAT_ERROR = '1a9da513-2640-4f84-9b6a-4d99dcddc628';
|
||||||
@ -34,6 +35,24 @@ class DateTime extends Constraint
|
|||||||
public $format = 'Y-m-d H:i:s';
|
public $format = 'Y-m-d H:i:s';
|
||||||
public $message = 'This value is not a valid datetime.';
|
public $message = 'This value is not a valid datetime.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param string|array|null $format
|
||||||
|
*/
|
||||||
|
public function __construct($format = null, string $message = null, array $groups = null, $payload = null, array $options = [])
|
||||||
|
{
|
||||||
|
if (\is_array($format)) {
|
||||||
|
$options = array_merge($format, $options);
|
||||||
|
} elseif (null !== $format) {
|
||||||
|
$options['value'] = $format;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
public function getDefaultOption()
|
public function getDefaultOption()
|
||||||
{
|
{
|
||||||
return 'format';
|
return 'format';
|
||||||
|
@ -24,9 +24,10 @@ use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
|||||||
*
|
*
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
|
||||||
class DisableAutoMapping extends Constraint
|
class DisableAutoMapping extends Constraint
|
||||||
{
|
{
|
||||||
public function __construct($options = null)
|
public function __construct(array $options = null)
|
||||||
{
|
{
|
||||||
if (\is_array($options) && \array_key_exists('groups', $options)) {
|
if (\is_array($options) && \array_key_exists('groups', $options)) {
|
||||||
throw new ConstraintDefinitionException(sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__));
|
throw new ConstraintDefinitionException(sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__));
|
||||||
|
@ -22,6 +22,7 @@ use Symfony\Component\Validator\Exception\LogicException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Email extends Constraint
|
class Email extends Constraint
|
||||||
{
|
{
|
||||||
public const VALIDATION_MODE_HTML5 = 'html5';
|
public const VALIDATION_MODE_HTML5 = 'html5';
|
||||||
@ -49,13 +50,23 @@ class Email extends Constraint
|
|||||||
public $mode;
|
public $mode;
|
||||||
public $normalizer;
|
public $normalizer;
|
||||||
|
|
||||||
public function __construct($options = null)
|
public function __construct(
|
||||||
{
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
string $mode = null,
|
||||||
|
callable $normalizer = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
if (\is_array($options) && \array_key_exists('mode', $options) && !\in_array($options['mode'], self::$validationModes, true)) {
|
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.');
|
throw new InvalidArgumentException('The "mode" parameter value is not valid.');
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->mode = $mode ?? $this->mode;
|
||||||
|
$this->normalizer = $normalizer ?? $this->normalizer;
|
||||||
|
|
||||||
if (self::VALIDATION_MODE_STRICT === $this->mode && !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__));
|
throw new LogicException(sprintf('The "egulias/email-validator" component is required to use the "%s" constraint in strict mode.', __CLASS__));
|
||||||
|
@ -24,9 +24,10 @@ use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
|||||||
*
|
*
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
|
||||||
class EnableAutoMapping extends Constraint
|
class EnableAutoMapping extends Constraint
|
||||||
{
|
{
|
||||||
public function __construct($options = null)
|
public function __construct(array $options = null)
|
||||||
{
|
{
|
||||||
if (\is_array($options) && \array_key_exists('groups', $options)) {
|
if (\is_array($options) && \array_key_exists('groups', $options)) {
|
||||||
throw new ConstraintDefinitionException(sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__));
|
throw new ConstraintDefinitionException(sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__));
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Validator\Constraints;
|
namespace Symfony\Component\Validator\Constraints;
|
||||||
|
|
||||||
|
use Symfony\Component\ExpressionLanguage\Expression as ExpressionObject;
|
||||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
use Symfony\Component\Validator\Exception\LogicException;
|
use Symfony\Component\Validator\Exception\LogicException;
|
||||||
@ -22,6 +23,7 @@ use Symfony\Component\Validator\Exception\LogicException;
|
|||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
|
||||||
class Expression extends Constraint
|
class Expression extends Constraint
|
||||||
{
|
{
|
||||||
const EXPRESSION_FAILED_ERROR = '6b3befbc-2f01-4ddf-be21-b57898905284';
|
const EXPRESSION_FAILED_ERROR = '6b3befbc-2f01-4ddf-be21-b57898905284';
|
||||||
@ -34,13 +36,35 @@ class Expression extends Constraint
|
|||||||
public $expression;
|
public $expression;
|
||||||
public $values = [];
|
public $values = [];
|
||||||
|
|
||||||
public function __construct($options = null)
|
/**
|
||||||
{
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param string|ExpressionObject|array $expression The expression to evaluate or an array of options
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$expression,
|
||||||
|
string $message = null,
|
||||||
|
array $values = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null,
|
||||||
|
array $options = []
|
||||||
|
) {
|
||||||
if (!class_exists(ExpressionLanguage::class)) {
|
if (!class_exists(ExpressionLanguage::class)) {
|
||||||
throw new LogicException(sprintf('The "symfony/expression-language" component is required to use the "%s" constraint.', __CLASS__));
|
throw new LogicException(sprintf('The "symfony/expression-language" component is required to use the "%s" constraint.', __CLASS__));
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
if (\is_array($expression)) {
|
||||||
|
$options = array_merge($expression, $options);
|
||||||
|
} elseif (!\is_string($expression) && !$expression instanceof ExpressionObject) {
|
||||||
|
throw new \TypeError(sprintf('"%s": Expected argument $expression to be either a string, an instance of "%s" or an array, got "%s".', __METHOD__, ExpressionObject::class, get_debug_type($expression)));
|
||||||
|
} else {
|
||||||
|
$options['value'] = $expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->values = $values ?? $this->values;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Andrey Sevastianov <mrpkmail@gmail.com>
|
* @author Andrey Sevastianov <mrpkmail@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class ExpressionLanguageSyntax extends Constraint
|
class ExpressionLanguageSyntax extends Constraint
|
||||||
{
|
{
|
||||||
const EXPRESSION_LANGUAGE_SYNTAX_ERROR = '1766a3f3-ff03-40eb-b053-ab7aa23d988a';
|
const EXPRESSION_LANGUAGE_SYNTAX_ERROR = '1766a3f3-ff03-40eb-b053-ab7aa23d988a';
|
||||||
@ -29,7 +30,16 @@ class ExpressionLanguageSyntax extends Constraint
|
|||||||
|
|
||||||
public $message = 'This value should be a valid expression.';
|
public $message = 'This value should be a valid expression.';
|
||||||
public $service;
|
public $service;
|
||||||
public $allowedVariables = null;
|
public $allowedVariables;
|
||||||
|
|
||||||
|
public function __construct(array $options = null, string $message = null, string $service = null, array $allowedVariables = null, array $groups = null, $payload = null)
|
||||||
|
{
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->service = $service ?? $this->service;
|
||||||
|
$this->allowedVariables = $allowedVariables ?? $this->allowedVariables;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Dmitrii Poddubnyi <dpoddubny@gmail.com>
|
* @author Dmitrii Poddubnyi <dpoddubny@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Hostname extends Constraint
|
class Hostname extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_HOSTNAME_ERROR = '7057ffdb-0af4-4f7e-bd5e-e9acfa6d7a2d';
|
const INVALID_HOSTNAME_ERROR = '7057ffdb-0af4-4f7e-bd5e-e9acfa6d7a2d';
|
||||||
@ -29,4 +30,17 @@ class Hostname extends Constraint
|
|||||||
|
|
||||||
public $message = 'This value is not a valid hostname.';
|
public $message = 'This value is not a valid hostname.';
|
||||||
public $requireTld = true;
|
public $requireTld = true;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
bool $requireTld = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->requireTld = $requireTld ?? $this->requireTld;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
* @author Michael Schummel
|
* @author Michael Schummel
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Iban extends Constraint
|
class Iban extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_COUNTRY_CODE_ERROR = 'de78ee2c-bd50-44e2-aec8-3d8228aeadb9';
|
const INVALID_COUNTRY_CODE_ERROR = 'de78ee2c-bd50-44e2-aec8-3d8228aeadb9';
|
||||||
@ -38,4 +39,11 @@ class Iban extends Constraint
|
|||||||
];
|
];
|
||||||
|
|
||||||
public $message = 'This is not a valid International Bank Account Number (IBAN).';
|
public $message = 'This is not a valid International Bank Account Number (IBAN).';
|
||||||
|
|
||||||
|
public function __construct(array $options = null, string $message = null, array $groups = null, $payload = null)
|
||||||
|
{
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
|||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
* @author Joseph Bielawski <stloyd@gmail.com>
|
* @author Joseph Bielawski <stloyd@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Ip extends Constraint
|
class Ip extends Constraint
|
||||||
{
|
{
|
||||||
const V4 = '4';
|
const V4 = '4';
|
||||||
@ -78,9 +79,19 @@ class Ip extends Constraint
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function __construct($options = null)
|
public function __construct(
|
||||||
{
|
array $options = null,
|
||||||
parent::__construct($options);
|
string $version = null,
|
||||||
|
string $message = null,
|
||||||
|
callable $normalizer = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->version = $version ?? $this->version;
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->normalizer = $normalizer ?? $this->normalizer;
|
||||||
|
|
||||||
if (!\in_array($this->version, self::$versions)) {
|
if (!\in_array($this->version, self::$versions)) {
|
||||||
throw new ConstraintDefinitionException(sprintf('The option "version" must be one of "%s".', implode('", "', self::$versions)));
|
throw new ConstraintDefinitionException(sprintf('The option "version" must be one of "%s".', implode('", "', self::$versions)));
|
||||||
|
@ -21,8 +21,12 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
* @author Manuel Reinhard <manu@sprain.ch>
|
* @author Manuel Reinhard <manu@sprain.ch>
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Isbn extends Constraint
|
class Isbn extends Constraint
|
||||||
{
|
{
|
||||||
|
const ISBN_10 = 'isbn10';
|
||||||
|
const ISBN_13 = 'isbn13';
|
||||||
|
|
||||||
const TOO_SHORT_ERROR = '949acbb0-8ef5-43ed-a0e9-032dfd08ae45';
|
const TOO_SHORT_ERROR = '949acbb0-8ef5-43ed-a0e9-032dfd08ae45';
|
||||||
const TOO_LONG_ERROR = '3171387d-f80a-47b3-bd6e-60598545316a';
|
const TOO_LONG_ERROR = '3171387d-f80a-47b3-bd6e-60598545316a';
|
||||||
const INVALID_CHARACTERS_ERROR = '23d21cea-da99-453d-98b1-a7d916fbb339';
|
const INVALID_CHARACTERS_ERROR = '23d21cea-da99-453d-98b1-a7d916fbb339';
|
||||||
@ -43,6 +47,35 @@ class Isbn extends Constraint
|
|||||||
public $type;
|
public $type;
|
||||||
public $message;
|
public $message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param string|array|null $type The ISBN standard to validate or a set of options
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$type = null,
|
||||||
|
string $message = null,
|
||||||
|
string $isbn10Message = null,
|
||||||
|
string $isbn13Message = null,
|
||||||
|
string $bothIsbnMessage = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null,
|
||||||
|
array $options = []
|
||||||
|
) {
|
||||||
|
if (\is_array($type)) {
|
||||||
|
$options = array_merge($type, $options);
|
||||||
|
} elseif (null !== $type) {
|
||||||
|
$options['value'] = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->isbn10Message = $isbn10Message ?? $this->isbn10Message;
|
||||||
|
$this->isbn13Message = $isbn13Message ?? $this->isbn13Message;
|
||||||
|
$this->bothIsbnMessage = $bothIsbnMessage ?? $this->bothIsbnMessage;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -48,7 +48,7 @@ class IsbnValidator extends ConstraintValidator
|
|||||||
$canonical = str_replace('-', '', $value);
|
$canonical = str_replace('-', '', $value);
|
||||||
|
|
||||||
// Explicitly validate against ISBN-10
|
// Explicitly validate against ISBN-10
|
||||||
if ('isbn10' === $constraint->type) {
|
if (Isbn::ISBN_10 === $constraint->type) {
|
||||||
if (true !== ($code = $this->validateIsbn10($canonical))) {
|
if (true !== ($code = $this->validateIsbn10($canonical))) {
|
||||||
$this->context->buildViolation($this->getMessage($constraint, $constraint->type))
|
$this->context->buildViolation($this->getMessage($constraint, $constraint->type))
|
||||||
->setParameter('{{ value }}', $this->formatValue($value))
|
->setParameter('{{ value }}', $this->formatValue($value))
|
||||||
@ -60,7 +60,7 @@ class IsbnValidator extends ConstraintValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Explicitly validate against ISBN-13
|
// Explicitly validate against ISBN-13
|
||||||
if ('isbn13' === $constraint->type) {
|
if (Isbn::ISBN_13 === $constraint->type) {
|
||||||
if (true !== ($code = $this->validateIsbn13($canonical))) {
|
if (true !== ($code = $this->validateIsbn13($canonical))) {
|
||||||
$this->context->buildViolation($this->getMessage($constraint, $constraint->type))
|
$this->context->buildViolation($this->getMessage($constraint, $constraint->type))
|
||||||
->setParameter('{{ value }}', $this->formatValue($value))
|
->setParameter('{{ value }}', $this->formatValue($value))
|
||||||
@ -174,9 +174,9 @@ class IsbnValidator extends ConstraintValidator
|
|||||||
{
|
{
|
||||||
if (null !== $constraint->message) {
|
if (null !== $constraint->message) {
|
||||||
return $constraint->message;
|
return $constraint->message;
|
||||||
} elseif ('isbn10' === $type) {
|
} elseif (Isbn::ISBN_10 === $type) {
|
||||||
return $constraint->isbn10Message;
|
return $constraint->isbn10Message;
|
||||||
} elseif ('isbn13' === $type) {
|
} elseif (Isbn::ISBN_13 === $type) {
|
||||||
return $constraint->isbn13Message;
|
return $constraint->isbn13Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Laurent Masforné <l.masforne@gmail.com>
|
* @author Laurent Masforné <l.masforne@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Isin extends Constraint
|
class Isin extends Constraint
|
||||||
{
|
{
|
||||||
const VALIDATION_LENGTH = 12;
|
const VALIDATION_LENGTH = 12;
|
||||||
@ -35,4 +36,11 @@ class Isin extends Constraint
|
|||||||
];
|
];
|
||||||
|
|
||||||
public $message = 'This is not a valid International Securities Identification Number (ISIN).';
|
public $message = 'This is not a valid International Securities Identification Number (ISIN).';
|
||||||
|
|
||||||
|
public function __construct(array $options = null, string $message = null, array $groups = null, $payload = null)
|
||||||
|
{
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
* @author Antonio J. García Lagar <aj@garcialagar.es>
|
* @author Antonio J. García Lagar <aj@garcialagar.es>
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Issn extends Constraint
|
class Issn extends Constraint
|
||||||
{
|
{
|
||||||
const TOO_SHORT_ERROR = '6a20dd3d-f463-4460-8e7b-18a1b98abbfb';
|
const TOO_SHORT_ERROR = '6a20dd3d-f463-4460-8e7b-18a1b98abbfb';
|
||||||
@ -41,4 +42,19 @@ class Issn extends Constraint
|
|||||||
public $message = 'This value is not a valid ISSN.';
|
public $message = 'This value is not a valid ISSN.';
|
||||||
public $caseSensitive = false;
|
public $caseSensitive = false;
|
||||||
public $requireHyphen = false;
|
public $requireHyphen = false;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
bool $caseSensitive = null,
|
||||||
|
bool $requireHyphen = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->caseSensitive = $caseSensitive ?? $this->caseSensitive;
|
||||||
|
$this->requireHyphen = $requireHyphen ?? $this->requireHyphen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Imad ZAIRIG <imadzairig@gmail.com>
|
* @author Imad ZAIRIG <imadzairig@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Json extends Constraint
|
class Json extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_JSON_ERROR = '0789c8ad-2d2b-49a4-8356-e2ce63998504';
|
const INVALID_JSON_ERROR = '0789c8ad-2d2b-49a4-8356-e2ce63998504';
|
||||||
@ -28,4 +29,11 @@ class Json extends Constraint
|
|||||||
];
|
];
|
||||||
|
|
||||||
public $message = 'This value should be valid JSON.';
|
public $message = 'This value should be valid JSON.';
|
||||||
|
|
||||||
|
public function __construct(array $options = null, string $message = null, array $groups = null, $payload = null)
|
||||||
|
{
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Validator\Exception\LogicException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Language extends Constraint
|
class Language extends Constraint
|
||||||
{
|
{
|
||||||
const NO_SUCH_LANGUAGE_ERROR = 'ee65fec4-9a20-4202-9f39-ca558cd7bdf7';
|
const NO_SUCH_LANGUAGE_ERROR = 'ee65fec4-9a20-4202-9f39-ca558cd7bdf7';
|
||||||
@ -32,12 +33,20 @@ class Language extends Constraint
|
|||||||
public $message = 'This value is not a valid language.';
|
public $message = 'This value is not a valid language.';
|
||||||
public $alpha3 = false;
|
public $alpha3 = false;
|
||||||
|
|
||||||
public function __construct($options = null)
|
public function __construct(
|
||||||
{
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
bool $alpha3 = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
if (!class_exists(Languages::class)) {
|
if (!class_exists(Languages::class)) {
|
||||||
throw new LogicException('The Intl component is required to use the Language constraint. Try running "composer require symfony/intl".');
|
throw new LogicException('The Intl component is required to use the Language constraint. Try running "composer require symfony/intl".');
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->alpha3 = $alpha3 ?? $this->alpha3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Validator\Exception\MissingOptionsException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Length extends Constraint
|
class Length extends Constraint
|
||||||
{
|
{
|
||||||
const TOO_SHORT_ERROR = '9ff3fdc4-b214-49db-8718-39c315e33d45';
|
const TOO_SHORT_ERROR = '9ff3fdc4-b214-49db-8718-39c315e33d45';
|
||||||
@ -43,19 +44,49 @@ class Length extends Constraint
|
|||||||
public $normalizer;
|
public $normalizer;
|
||||||
public $allowEmptyString = false;
|
public $allowEmptyString = false;
|
||||||
|
|
||||||
public function __construct($options = null)
|
/**
|
||||||
{
|
* {@inheritdoc}
|
||||||
if (null !== $options && !\is_array($options)) {
|
*
|
||||||
$options = [
|
* @param int|array|null $exactly The expected exact length or a set of options
|
||||||
'min' => $options,
|
*/
|
||||||
'max' => $options,
|
public function __construct(
|
||||||
];
|
$exactly = null,
|
||||||
} elseif (\is_array($options) && isset($options['value']) && !isset($options['min']) && !isset($options['max'])) {
|
int $min = null,
|
||||||
$options['min'] = $options['max'] = $options['value'];
|
int $max = null,
|
||||||
unset($options['value']);
|
string $charset = null,
|
||||||
|
callable $normalizer = null,
|
||||||
|
string $exactMessage = null,
|
||||||
|
string $minMessage = null,
|
||||||
|
string $maxMessage = null,
|
||||||
|
string $charsetMessage = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null,
|
||||||
|
array $options = []
|
||||||
|
) {
|
||||||
|
if (\is_array($exactly)) {
|
||||||
|
$options = array_merge($exactly, $options);
|
||||||
|
$exactly = $options['value'] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
$min = $min ?? $options['min'] ?? null;
|
||||||
|
$max = $max ?? $options['max'] ?? null;
|
||||||
|
|
||||||
|
unset($options['value'], $options['min'], $options['max']);
|
||||||
|
|
||||||
|
if (null !== $exactly && null === $min && null === $max) {
|
||||||
|
$min = $max = $exactly;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->min = $min;
|
||||||
|
$this->max = $max;
|
||||||
|
$this->charset = $charset ?? $this->charset;
|
||||||
|
$this->normalizer = $normalizer ?? $this->normalizer;
|
||||||
|
$this->exactMessage = $exactMessage ?? $this->exactMessage;
|
||||||
|
$this->minMessage = $minMessage ?? $this->minMessage;
|
||||||
|
$this->maxMessage = $maxMessage ?? $this->maxMessage;
|
||||||
|
$this->charsetMessage = $charsetMessage ?? $this->charsetMessage;
|
||||||
|
|
||||||
if (null === $this->min && null === $this->max) {
|
if (null === $this->min && null === $this->max) {
|
||||||
throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint "%s".', __CLASS__), ['min', 'max']);
|
throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint "%s".', __CLASS__), ['min', 'max']);
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Validator\Exception\LogicException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Locale extends Constraint
|
class Locale extends Constraint
|
||||||
{
|
{
|
||||||
const NO_SUCH_LOCALE_ERROR = 'a0af4293-1f1a-4a1c-a328-979cba6182a2';
|
const NO_SUCH_LOCALE_ERROR = 'a0af4293-1f1a-4a1c-a328-979cba6182a2';
|
||||||
@ -32,12 +33,20 @@ class Locale extends Constraint
|
|||||||
public $message = 'This value is not a valid locale.';
|
public $message = 'This value is not a valid locale.';
|
||||||
public $canonicalize = true;
|
public $canonicalize = true;
|
||||||
|
|
||||||
public function __construct($options = null)
|
public function __construct(
|
||||||
{
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
bool $canonicalize = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
if (!class_exists(Locales::class)) {
|
if (!class_exists(Locales::class)) {
|
||||||
throw new LogicException('The Intl component is required to use the Locale constraint. Try running "composer require symfony/intl".');
|
throw new LogicException('The Intl component is required to use the Locale constraint. Try running "composer require symfony/intl".');
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->canonicalize = $canonicalize ?? $this->canonicalize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
* @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/
|
* @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Luhn extends Constraint
|
class Luhn extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_CHARACTERS_ERROR = 'dfad6d23-1b74-4374-929b-5cbb56fc0d9e';
|
const INVALID_CHARACTERS_ERROR = 'dfad6d23-1b74-4374-929b-5cbb56fc0d9e';
|
||||||
@ -34,4 +35,15 @@ class Luhn extends Constraint
|
|||||||
];
|
];
|
||||||
|
|
||||||
public $message = 'Invalid card number.';
|
public $message = 'Invalid card number.';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class NotCompromisedPassword extends Constraint
|
class NotCompromisedPassword extends Constraint
|
||||||
{
|
{
|
||||||
const COMPROMISED_PASSWORD_ERROR = 'd9bcdbfe-a9d6-4bfa-a8ff-da5fd93e0f6d';
|
const COMPROMISED_PASSWORD_ERROR = 'd9bcdbfe-a9d6-4bfa-a8ff-da5fd93e0f6d';
|
||||||
@ -30,4 +31,19 @@ class NotCompromisedPassword extends Constraint
|
|||||||
public $message = 'This password has been leaked in a data breach, it must not be used. Please use another password.';
|
public $message = 'This password has been leaked in a data breach, it must not be used. Please use another password.';
|
||||||
public $threshold = 1;
|
public $threshold = 1;
|
||||||
public $skipOnError = false;
|
public $skipOnError = false;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
int $threshold = null,
|
||||||
|
bool $skipOnError = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->threshold = $threshold ?? $this->threshold;
|
||||||
|
$this->skipOnError = $skipOnError ?? $this->skipOnError;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Regex extends Constraint
|
class Regex extends Constraint
|
||||||
{
|
{
|
||||||
const REGEX_FAILED_ERROR = 'de1e3db3-5ed4-4941-aae4-59f3667cc3a3';
|
const REGEX_FAILED_ERROR = 'de1e3db3-5ed4-4941-aae4-59f3667cc3a3';
|
||||||
@ -34,9 +35,33 @@ class Regex extends Constraint
|
|||||||
public $match = true;
|
public $match = true;
|
||||||
public $normalizer;
|
public $normalizer;
|
||||||
|
|
||||||
public function __construct($options = null)
|
/**
|
||||||
{
|
* {@inheritdoc}
|
||||||
parent::__construct($options);
|
*
|
||||||
|
* @param string|array $pattern The pattern to evaluate or an array of options.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$pattern,
|
||||||
|
string $message = null,
|
||||||
|
string $htmlPattern = null,
|
||||||
|
bool $match = null,
|
||||||
|
callable $normalizer = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null,
|
||||||
|
array $options = []
|
||||||
|
) {
|
||||||
|
if (\is_array($pattern)) {
|
||||||
|
$options = array_merge($pattern, $options);
|
||||||
|
} elseif (null !== $pattern) {
|
||||||
|
$options['value'] = $pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->htmlPattern = $htmlPattern ?? $this->htmlPattern;
|
||||||
|
$this->match = $match ?? $this->match;
|
||||||
|
$this->normalizer = $normalizer ?? $this->normalizer;
|
||||||
|
|
||||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer)));
|
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer)));
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Time extends Constraint
|
class Time extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_FORMAT_ERROR = '9d27b2bb-f755-4fbf-b725-39b1edbdebdf';
|
const INVALID_FORMAT_ERROR = '9d27b2bb-f755-4fbf-b725-39b1edbdebdf';
|
||||||
@ -30,4 +31,15 @@ class Time extends Constraint
|
|||||||
];
|
];
|
||||||
|
|
||||||
public $message = 'This value is not a valid time.';
|
public $message = 'This value is not a valid time.';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
|||||||
* @author Javier Spagnoletti <phansys@gmail.com>
|
* @author Javier Spagnoletti <phansys@gmail.com>
|
||||||
* @author Hugo Hamon <hugohamon@neuf.fr>
|
* @author Hugo Hamon <hugohamon@neuf.fr>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Timezone extends Constraint
|
class Timezone extends Constraint
|
||||||
{
|
{
|
||||||
public const TIMEZONE_IDENTIFIER_ERROR = '5ce113e6-5e64-4ea2-90fe-d2233956db13';
|
public const TIMEZONE_IDENTIFIER_ERROR = '5ce113e6-5e64-4ea2-90fe-d2233956db13';
|
||||||
@ -42,10 +43,29 @@ class Timezone extends Constraint
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param int|array|null $zone A combination of {@see \DateTimeZone} class constants or a set of options.
|
||||||
*/
|
*/
|
||||||
public function __construct($options = null)
|
public function __construct(
|
||||||
{
|
$zone = null,
|
||||||
parent::__construct($options);
|
string $message = null,
|
||||||
|
string $countryCode = null,
|
||||||
|
bool $intlCompatible = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null,
|
||||||
|
array $options = []
|
||||||
|
) {
|
||||||
|
if (\is_array($zone)) {
|
||||||
|
$options = array_merge($zone, $options);
|
||||||
|
} elseif (null !== $zone) {
|
||||||
|
$options['value'] = $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->countryCode = $countryCode ?? $this->countryCode;
|
||||||
|
$this->intlCompatible = $intlCompatible ?? $this->intlCompatible;
|
||||||
|
|
||||||
if (null === $this->countryCode) {
|
if (null === $this->countryCode) {
|
||||||
if (0 >= $this->zone || \DateTimeZone::ALL_WITH_BC < $this->zone) {
|
if (0 >= $this->zone || \DateTimeZone::ALL_WITH_BC < $this->zone) {
|
||||||
|
@ -19,17 +19,21 @@ use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS)]
|
||||||
class Traverse extends Constraint
|
class Traverse extends Constraint
|
||||||
{
|
{
|
||||||
public $traverse = true;
|
public $traverse = true;
|
||||||
|
|
||||||
public function __construct($options = null)
|
/**
|
||||||
|
* @param bool|array|null $traverse
|
||||||
|
*/
|
||||||
|
public function __construct($traverse = null)
|
||||||
{
|
{
|
||||||
if (\is_array($options) && \array_key_exists('groups', $options)) {
|
if (\is_array($traverse) && \array_key_exists('groups', $traverse)) {
|
||||||
throw new ConstraintDefinitionException(sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__));
|
throw new ConstraintDefinitionException(sprintf('The option "groups" is not supported by the constraint "%s".', __CLASS__));
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($options);
|
parent::__construct($traverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Type extends Constraint
|
class Type extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_TYPE_ERROR = 'ba785a8c-82cb-4283-967c-3cf342181b40';
|
const INVALID_TYPE_ERROR = 'ba785a8c-82cb-4283-967c-3cf342181b40';
|
||||||
@ -30,6 +31,24 @@ class Type extends Constraint
|
|||||||
public $message = 'This value should be of type {{ type }}.';
|
public $message = 'This value should be of type {{ type }}.';
|
||||||
public $type;
|
public $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @param string|array $type One ore multiple types to validate against or a set of options.
|
||||||
|
*/
|
||||||
|
public function __construct($type, string $message = null, array $groups = null, $payload = null, array $options = [])
|
||||||
|
{
|
||||||
|
if (\is_array($type) && \is_string(key($type))) {
|
||||||
|
$options = array_merge($type, $options);
|
||||||
|
} elseif (null !== $type) {
|
||||||
|
$options['value'] = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Laurent Clouet <laurent35240@gmail.com>
|
* @author Laurent Clouet <laurent35240@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Ulid extends Constraint
|
class Ulid extends Constraint
|
||||||
{
|
{
|
||||||
const TOO_SHORT_ERROR = '7b44804e-37d5-4df4-9bdd-b738d4a45bb4';
|
const TOO_SHORT_ERROR = '7b44804e-37d5-4df4-9bdd-b738d4a45bb4';
|
||||||
@ -33,4 +34,15 @@ class Ulid extends Constraint
|
|||||||
];
|
];
|
||||||
|
|
||||||
public $message = 'This is not a valid ULID.';
|
public $message = 'This is not a valid ULID.';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*
|
*
|
||||||
* @author Yevgeniy Zholkevskiy <zhenya.zholkevskiy@gmail.com>
|
* @author Yevgeniy Zholkevskiy <zhenya.zholkevskiy@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Unique extends Constraint
|
class Unique extends Constraint
|
||||||
{
|
{
|
||||||
public const IS_NOT_UNIQUE = '7911c98d-b845-4da0-94b7-a8dac36bc55a';
|
public const IS_NOT_UNIQUE = '7911c98d-b845-4da0-94b7-a8dac36bc55a';
|
||||||
@ -28,4 +29,15 @@ class Unique extends Constraint
|
|||||||
];
|
];
|
||||||
|
|
||||||
public $message = 'This collection should contain only unique elements.';
|
public $message = 'This collection should contain only unique elements.';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
|||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Url extends Constraint
|
class Url extends Constraint
|
||||||
{
|
{
|
||||||
const INVALID_URL_ERROR = '57c2f299-1154-4870-89bb-ef3b1f5ad229';
|
const INVALID_URL_ERROR = '57c2f299-1154-4870-89bb-ef3b1f5ad229';
|
||||||
@ -33,9 +34,21 @@ class Url extends Constraint
|
|||||||
public $relativeProtocol = false;
|
public $relativeProtocol = false;
|
||||||
public $normalizer;
|
public $normalizer;
|
||||||
|
|
||||||
public function __construct($options = null)
|
public function __construct(
|
||||||
{
|
array $options = null,
|
||||||
parent::__construct($options);
|
string $message = null,
|
||||||
|
array $protocols = null,
|
||||||
|
bool $relativeProtocol = null,
|
||||||
|
callable $normalizer = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->protocols = $protocols ?? $this->protocols;
|
||||||
|
$this->relativeProtocol = $relativeProtocol ?? $this->relativeProtocol;
|
||||||
|
$this->normalizer = $normalizer ?? $this->normalizer;
|
||||||
|
|
||||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer)));
|
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer)));
|
||||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Validator\Exception\InvalidArgumentException;
|
|||||||
* @author Colin O'Dell <colinodell@gmail.com>
|
* @author Colin O'Dell <colinodell@gmail.com>
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
class Uuid extends Constraint
|
class Uuid extends Constraint
|
||||||
{
|
{
|
||||||
const TOO_SHORT_ERROR = 'aa314679-dac9-4f54-bf97-b2049df8f2a3';
|
const TOO_SHORT_ERROR = 'aa314679-dac9-4f54-bf97-b2049df8f2a3';
|
||||||
@ -46,6 +47,15 @@ class Uuid extends Constraint
|
|||||||
const V5_SHA1 = 5;
|
const V5_SHA1 = 5;
|
||||||
const V6_SORTABLE = 6;
|
const V6_SORTABLE = 6;
|
||||||
|
|
||||||
|
const ALL_VERSIONS = [
|
||||||
|
self::V1_MAC,
|
||||||
|
self::V2_DCE,
|
||||||
|
self::V3_MD5,
|
||||||
|
self::V4_RANDOM,
|
||||||
|
self::V5_SHA1,
|
||||||
|
self::V6_SORTABLE,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message to display when validation fails.
|
* Message to display when validation fails.
|
||||||
*
|
*
|
||||||
@ -69,20 +79,30 @@ class Uuid extends Constraint
|
|||||||
*
|
*
|
||||||
* @var int[]
|
* @var int[]
|
||||||
*/
|
*/
|
||||||
public $versions = [
|
public $versions = self::ALL_VERSIONS;
|
||||||
self::V1_MAC,
|
|
||||||
self::V2_DCE,
|
|
||||||
self::V3_MD5,
|
|
||||||
self::V4_RANDOM,
|
|
||||||
self::V5_SHA1,
|
|
||||||
self::V6_SORTABLE,
|
|
||||||
];
|
|
||||||
|
|
||||||
public $normalizer;
|
public $normalizer;
|
||||||
|
|
||||||
public function __construct($options = null)
|
/**
|
||||||
{
|
* {@inheritdoc}
|
||||||
parent::__construct($options);
|
*
|
||||||
|
* @param int[]|null $versions
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
array $options = null,
|
||||||
|
string $message = null,
|
||||||
|
array $versions = null,
|
||||||
|
bool $strict = null,
|
||||||
|
callable $normalizer = null,
|
||||||
|
array $groups = null,
|
||||||
|
$payload = null
|
||||||
|
) {
|
||||||
|
parent::__construct($options, $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
$this->versions = $versions ?? $this->versions;
|
||||||
|
$this->strict = $strict ?? $this->strict;
|
||||||
|
$this->normalizer = $normalizer ?? $this->normalizer;
|
||||||
|
|
||||||
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
if (null !== $this->normalizer && !\is_callable($this->normalizer)) {
|
||||||
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer)));
|
throw new InvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).', get_debug_type($this->normalizer)));
|
||||||
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
use Symfony\Component\Validator\Constraints\Bic;
|
use Symfony\Component\Validator\Constraints\Bic;
|
||||||
use Symfony\Component\Validator\Constraints\BicValidator;
|
use Symfony\Component\Validator\Constraints\BicValidator;
|
||||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
|
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
|
||||||
|
|
||||||
class BicValidatorTest extends ConstraintValidatorTestCase
|
class BicValidatorTest extends ConstraintValidatorTestCase
|
||||||
@ -68,6 +70,27 @@ class BicValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidComparisonToPropertyPathFromAttribute()
|
||||||
|
{
|
||||||
|
$classMetadata = new ClassMetadata(BicDummy::class);
|
||||||
|
(new AnnotationLoader())->loadClassMetadata($classMetadata);
|
||||||
|
|
||||||
|
[$constraint] = $classMetadata->properties['bic1']->constraints;
|
||||||
|
|
||||||
|
$this->setObject(new BicDummy());
|
||||||
|
|
||||||
|
$this->validator->validate('UNCRIT2B912', $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('Constraint Message')
|
||||||
|
->setParameter('{{ value }}', '"UNCRIT2B912"')
|
||||||
|
->setParameter('{{ iban }}', 'FR14 2004 1010 0505 0001 3M02 606')
|
||||||
|
->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidComparisonToValue()
|
public function testValidComparisonToValue()
|
||||||
{
|
{
|
||||||
$constraint = new Bic(['iban' => 'FR14 2004 1010 0505 0001 3M02 606']);
|
$constraint = new Bic(['iban' => 'FR14 2004 1010 0505 0001 3M02 606']);
|
||||||
@ -92,6 +115,25 @@ class BicValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidComparisonToValueFromAttribute()
|
||||||
|
{
|
||||||
|
$classMetadata = new ClassMetadata(BicDummy::class);
|
||||||
|
(new AnnotationLoader())->loadClassMetadata($classMetadata);
|
||||||
|
|
||||||
|
[$constraint] = $classMetadata->properties['bic1']->constraints;
|
||||||
|
|
||||||
|
$this->validator->validate('UNCRIT2B912', $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('Constraint Message')
|
||||||
|
->setParameter('{{ value }}', '"UNCRIT2B912"')
|
||||||
|
->setParameter('{{ iban }}', 'FR14 2004 1010 0505 0001 3M02 606')
|
||||||
|
->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function testNoViolationOnNullObjectWithPropertyPath()
|
public function testNoViolationOnNullObjectWithPropertyPath()
|
||||||
{
|
{
|
||||||
$constraint = new Bic(['ibanPropertyPath' => 'propertyPath']);
|
$constraint = new Bic(['ibanPropertyPath' => 'propertyPath']);
|
||||||
@ -113,6 +155,17 @@ class BicValidatorTest extends ConstraintValidatorTestCase
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testThrowsConstraintExceptionIfBothValueAndPropertyPathNamed()
|
||||||
|
{
|
||||||
|
$this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
|
||||||
|
$this->expectExceptionMessage('The "iban" and "ibanPropertyPath" options of the Iban constraint cannot be used at the same time');
|
||||||
|
|
||||||
|
eval('new \Symfony\Component\Validator\Constraints\Bic(iban: "value", ibanPropertyPath: "propertyPath");');
|
||||||
|
}
|
||||||
|
|
||||||
public function testInvalidValuePath()
|
public function testInvalidValuePath()
|
||||||
{
|
{
|
||||||
$constraint = new Bic(['ibanPropertyPath' => 'foo']);
|
$constraint = new Bic(['ibanPropertyPath' => 'foo']);
|
||||||
@ -173,6 +226,22 @@ class BicValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getInvalidBics
|
||||||
|
*/
|
||||||
|
public function testInvalidBicsNamed($bic, $code)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Bic(message: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($bic, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"'.$bic.'"')
|
||||||
|
->setCode($code)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function getInvalidBics()
|
public function getInvalidBics()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -258,3 +327,13 @@ class BicComparisonTestClass
|
|||||||
return $this->value;
|
return $this->value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BicDummy
|
||||||
|
{
|
||||||
|
#[Bic(iban: 'FR14 2004 1010 0505 0001 3M02 606', ibanMessage: 'Constraint Message')]
|
||||||
|
private $bic1;
|
||||||
|
#[Bic(ibanPropertyPath: 'iban', ibanMessage: 'Constraint Message')]
|
||||||
|
private $bic2;
|
||||||
|
|
||||||
|
private $iban = 'FR14 2004 1010 0505 0001 3M02 606';
|
||||||
|
}
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\CardScheme;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class CardSchemeTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(CardSchemeDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame([CardScheme::MASTERCARD, CardScheme::VISA], $aConstraint->schemes);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame([CardScheme::AMEX], $bConstraint->schemes);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'CardSchemeDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame([CardScheme::DINERS], $cConstraint->schemes);
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CardSchemeDummy
|
||||||
|
{
|
||||||
|
#[CardScheme([CardScheme::MASTERCARD, CardScheme::VISA])]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[CardScheme(schemes: [CardScheme::AMEX], message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[CardScheme(schemes: [CardScheme::DINERS], groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -46,6 +46,16 @@ class CardSchemeValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testValidNumberWithOrderedArguments()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'5555555555554444',
|
||||||
|
new CardScheme([CardScheme::MASTERCARD, CardScheme::VISA])
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getInvalidNumbers
|
* @dataProvider getInvalidNumbers
|
||||||
*/
|
*/
|
||||||
@ -64,6 +74,22 @@ class CardSchemeValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidNumberNamedArguments()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'2721001234567890',
|
||||||
|
eval('use Symfony\Component\Validator\Constraints\CardScheme; return new CardScheme(schemes: [CardScheme::MASTERCARD, CardScheme::VISA], message: "myMessage");')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"2721001234567890"')
|
||||||
|
->setCode(CardScheme::INVALID_FORMAT_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function getValidNumbers()
|
public function getValidNumbers()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Cascade;
|
||||||
|
use Symfony\Component\Validator\Mapping\CascadingStrategy;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class CascadeTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testCascadeAttribute()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(CascadeDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertSame(CascadingStrategy::NONE, $metadata->getCascadingStrategy());
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
self::assertSame(CascadingStrategy::CASCADE, $metadata->getCascadingStrategy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Cascade]
|
||||||
|
class CascadeDummy
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Count;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class CountTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(CountDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame(42, $aConstraint->min);
|
||||||
|
self::assertSame(42, $aConstraint->max);
|
||||||
|
self::assertNull($aConstraint->divisibleBy);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame(1, $bConstraint->min);
|
||||||
|
self::assertSame(4711, $bConstraint->max);
|
||||||
|
self::assertNull($bConstraint->divisibleBy);
|
||||||
|
self::assertSame('myMinMessage', $bConstraint->minMessage);
|
||||||
|
self::assertSame('myMaxMessage', $bConstraint->maxMessage);
|
||||||
|
self::assertSame(['Default', 'CountDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertNull($cConstraint->min);
|
||||||
|
self::assertNull($cConstraint->max);
|
||||||
|
self::assertSame(10, $cConstraint->divisibleBy);
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CountDummy
|
||||||
|
{
|
||||||
|
#[Count(exactly: 42)]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Count(min: 1, max: 4711, minMessage: 'myMinMessage', maxMessage: 'myMaxMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Count(divisibleBy: 10, groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -79,6 +79,18 @@ abstract class CountValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getThreeOrLessElements
|
||||||
|
*/
|
||||||
|
public function testValidValuesMaxNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Count(max: 3);');
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getFiveOrMoreElements
|
* @dataProvider getFiveOrMoreElements
|
||||||
*/
|
*/
|
||||||
@ -90,6 +102,18 @@ abstract class CountValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getFiveOrMoreElements
|
||||||
|
*/
|
||||||
|
public function testValidValuesMinNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Count(min: 5);');
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getFourElements
|
* @dataProvider getFourElements
|
||||||
*/
|
*/
|
||||||
@ -101,6 +125,18 @@ abstract class CountValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getFourElements
|
||||||
|
*/
|
||||||
|
public function testValidValuesExactNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Count(exactly: 4);');
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getFiveOrMoreElements
|
* @dataProvider getFiveOrMoreElements
|
||||||
*/
|
*/
|
||||||
@ -122,6 +158,25 @@ abstract class CountValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getFiveOrMoreElements
|
||||||
|
*/
|
||||||
|
public function testTooManyValuesNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Count(max: 4, maxMessage: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ count }}', \count($value))
|
||||||
|
->setParameter('{{ limit }}', 4)
|
||||||
|
->setInvalidValue($value)
|
||||||
|
->setPlural(4)
|
||||||
|
->setCode(Count::TOO_MANY_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getThreeOrLessElements
|
* @dataProvider getThreeOrLessElements
|
||||||
*/
|
*/
|
||||||
@ -143,6 +198,25 @@ abstract class CountValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getThreeOrLessElements
|
||||||
|
*/
|
||||||
|
public function testTooFewValuesNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Count(min: 4, minMessage: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ count }}', \count($value))
|
||||||
|
->setParameter('{{ limit }}', 4)
|
||||||
|
->setInvalidValue($value)
|
||||||
|
->setPlural(4)
|
||||||
|
->setCode(Count::TOO_FEW_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getFiveOrMoreElements
|
* @dataProvider getFiveOrMoreElements
|
||||||
*/
|
*/
|
||||||
@ -165,6 +239,25 @@ abstract class CountValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getFiveOrMoreElements
|
||||||
|
*/
|
||||||
|
public function testTooManyValuesExactNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Count(exactly: 4, exactMessage: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ count }}', \count($value))
|
||||||
|
->setParameter('{{ limit }}', 4)
|
||||||
|
->setInvalidValue($value)
|
||||||
|
->setPlural(4)
|
||||||
|
->setCode(Count::TOO_MANY_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getThreeOrLessElements
|
* @dataProvider getThreeOrLessElements
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Country;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class CountryTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(CountryDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertFalse($aConstraint->alpha3);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertTrue($bConstraint->alpha3);
|
||||||
|
self::assertSame(['Default', 'CountryDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CountryDummy
|
||||||
|
{
|
||||||
|
#[Country]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Country(message: 'myMessage', alpha3: true)]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Country(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -152,6 +152,22 @@ class CountryValidatorTest extends ConstraintValidatorTestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidAlpha3CountryNamed()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'DE',
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Country(alpha3: true, message: "myMessage");')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"DE"')
|
||||||
|
->setCode(Country::NO_SUCH_COUNTRY_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidateUsingCountrySpecificLocale()
|
public function testValidateUsingCountrySpecificLocale()
|
||||||
{
|
{
|
||||||
// in order to test with "en_GB"
|
// in order to test with "en_GB"
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Currency;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class CurrencyTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(CurrencyDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'CurrencyDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CurrencyDummy
|
||||||
|
{
|
||||||
|
#[Currency]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Currency(message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Currency(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -111,6 +111,22 @@ class CurrencyValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getInvalidCurrencies
|
||||||
|
*/
|
||||||
|
public function testInvalidCurrenciesNamed($currency)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Currency(message: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($currency, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"'.$currency.'"')
|
||||||
|
->setCode(Currency::NO_SUCH_CURRENCY_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function getInvalidCurrencies()
|
public function getInvalidCurrencies()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Date;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class DateTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(DateDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'DateDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DateDummy
|
||||||
|
{
|
||||||
|
#[Date]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Date(message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Date(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\DateTime;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class DateTimeTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(DateTimeDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame('Y-m-d H:i:s', $aConstraint->format);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('d.m.Y', $bConstraint->format);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'DateTimeDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame('m/d/Y', $cConstraint->format);
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DateTimeDummy
|
||||||
|
{
|
||||||
|
#[DateTime]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[DateTime(format: 'd.m.Y', message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[DateTime('m/d/Y', groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -115,6 +115,21 @@ class DateTimeValidatorTest extends ConstraintValidatorTestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidDateTimeNamed()
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\DateTime(message: "myMessage", format: "Y-m-d");');
|
||||||
|
|
||||||
|
$this->validator->validate('2010-01-01 00:00:00', $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"2010-01-01 00:00:00"')
|
||||||
|
->setCode(DateTime::INVALID_FORMAT_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function testDateTimeWithTrailingData()
|
public function testDateTimeWithTrailingData()
|
||||||
{
|
{
|
||||||
$this->validator->validate('1995-05-10 00:00:00', new DateTime([
|
$this->validator->validate('1995-05-10 00:00:00', new DateTime([
|
||||||
|
@ -78,6 +78,21 @@ class DateValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidDateNamed()
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Date(message: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate('foobar', $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"foobar"')
|
||||||
|
->setCode(Date::INVALID_FORMAT_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function getInvalidDates()
|
public function getInvalidDates()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -14,6 +14,9 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\DisableAutoMapping;
|
use Symfony\Component\Validator\Constraints\DisableAutoMapping;
|
||||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||||
|
use Symfony\Component\Validator\Mapping\AutoMappingStrategy;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
@ -27,4 +30,21 @@ class DisableAutoMappingTest extends TestCase
|
|||||||
|
|
||||||
new DisableAutoMapping(['groups' => 'foo']);
|
new DisableAutoMapping(['groups' => 'foo']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testDisableAutoMappingAttribute()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(DisableAutoMappingDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertSame(AutoMappingStrategy::NONE, $metadata->getAutoMappingStrategy());
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
self::assertSame(AutoMappingStrategy::DISABLED, $metadata->getAutoMappingStrategy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[DisableAutoMapping]
|
||||||
|
class DisableAutoMappingDummy
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\Email;
|
use Symfony\Component\Validator\Constraints\Email;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
class EmailTest extends TestCase
|
class EmailTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -50,4 +52,38 @@ class EmailTest extends TestCase
|
|||||||
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
||||||
new Email(['normalizer' => new \stdClass()]);
|
new Email(['normalizer' => new \stdClass()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttribute()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(EmailDummy::class);
|
||||||
|
(new AnnotationLoader())->loadClassMetadata($metadata);
|
||||||
|
|
||||||
|
[$aConstraint] = $metadata->properties['a']->constraints;
|
||||||
|
self::assertNull($aConstraint->mode);
|
||||||
|
self::assertNull($aConstraint->normalizer);
|
||||||
|
|
||||||
|
[$bConstraint] = $metadata->properties['b']->constraints;
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(Email::VALIDATION_MODE_HTML5, $bConstraint->mode);
|
||||||
|
self::assertSame('trim', $bConstraint->normalizer);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmailDummy
|
||||||
|
{
|
||||||
|
#[Email]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Email(message: 'myMessage', mode: Email::VALIDATION_MODE_HTML5, normalizer: 'trim')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Email(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\EnableAutoMapping;
|
use Symfony\Component\Validator\Constraints\EnableAutoMapping;
|
||||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||||
|
use Symfony\Component\Validator\Mapping\AutoMappingStrategy;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
@ -27,4 +30,21 @@ class EnableAutoMappingTest extends TestCase
|
|||||||
|
|
||||||
new EnableAutoMapping(['groups' => 'foo']);
|
new EnableAutoMapping(['groups' => 'foo']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testDisableAutoMappingAttribute()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(EnableAutoMappingDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertSame(AutoMappingStrategy::NONE, $metadata->getAutoMappingStrategy());
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
self::assertSame(AutoMappingStrategy::ENABLED, $metadata->getAutoMappingStrategy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[EnableAutoMapping]
|
||||||
|
class EnableAutoMappingDummy
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\ExpressionLanguageSyntax;
|
||||||
|
use Symfony\Component\Validator\Constraints\ExpressionLanguageSyntaxValidator;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
class ExpressionLanguageSyntaxTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testValidatedByStandardValidator()
|
||||||
|
{
|
||||||
|
$constraint = new ExpressionLanguageSyntax();
|
||||||
|
|
||||||
|
self::assertSame(ExpressionLanguageSyntaxValidator::class, $constraint->validatedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideServiceValidatedConstraints
|
||||||
|
*/
|
||||||
|
public function testValidatedByService(ExpressionLanguageSyntax $constraint)
|
||||||
|
{
|
||||||
|
self::assertSame('my_service', $constraint->validatedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideServiceValidatedConstraints(): iterable
|
||||||
|
{
|
||||||
|
yield 'Doctrine style' => [new ExpressionLanguageSyntax(['service' => 'my_service'])];
|
||||||
|
|
||||||
|
if (\PHP_VERSION_ID < 80000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield 'named arguments' => [eval('return new \Symfony\Component\Validator\Constraints\ExpressionLanguageSyntax(service: "my_service");')];
|
||||||
|
|
||||||
|
$metadata = new ClassMetadata(ExpressionLanguageSyntaxDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
yield 'attribute' => [$metadata->properties['b']->constraints[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(ExpressionLanguageSyntaxDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertNull($aConstraint->service);
|
||||||
|
self::assertNull($aConstraint->allowedVariables);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('my_service', $bConstraint->service);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'ExpressionLanguageSyntaxDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['foo', 'bar'], $cConstraint->allowedVariables);
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExpressionLanguageSyntaxDummy
|
||||||
|
{
|
||||||
|
#[ExpressionLanguageSyntax]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[ExpressionLanguageSyntax(service: 'my_service', message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[ExpressionLanguageSyntax(allowedVariables: ['foo', 'bar'], groups: ['my_group'])]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Expression;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class ExpressionTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(ExpressionDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame('value == "1"', $aConstraint->expression);
|
||||||
|
self::assertSame([], $aConstraint->values);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('value == "1"', $bConstraint->expression);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'ExpressionDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame('value == someVariable', $cConstraint->expression);
|
||||||
|
self::assertSame(['someVariable' => 42], $cConstraint->values);
|
||||||
|
self::assertSame(['foo'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExpressionDummy
|
||||||
|
{
|
||||||
|
#[Expression('value == "1"')]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Expression(expression: 'value == "1"', message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Expression(expression: 'value == someVariable', values: ['someVariable' => 42], groups: ['foo'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Hostname;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class HostnameTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(HostnameDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertTrue($aConstraint->requireTld);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertFalse($bConstraint->requireTld);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'HostnameDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HostnameDummy
|
||||||
|
{
|
||||||
|
#[Hostname]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Hostname(message: "myMessage", requireTld: false)]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Hostname(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -157,6 +157,22 @@ class HostnameValidatorTest extends ConstraintValidatorTestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testReservedDomainsRaiseViolationIfTldRequiredNamed()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'example',
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Hostname(message: "myMessage", requireTld: true);')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"example"')
|
||||||
|
->setCode(Hostname::INVALID_HOSTNAME_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getTopLevelDomains
|
* @dataProvider getTopLevelDomains
|
||||||
*/
|
*/
|
||||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
|
|
||||||
use Symfony\Component\Validator\Constraints\Iban;
|
use Symfony\Component\Validator\Constraints\Iban;
|
||||||
use Symfony\Component\Validator\Constraints\IbanValidator;
|
use Symfony\Component\Validator\Constraints\IbanValidator;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
|
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
|
||||||
|
|
||||||
class IbanValidatorTest extends ConstraintValidatorTestCase
|
class IbanValidatorTest extends ConstraintValidatorTestCase
|
||||||
@ -423,6 +425,24 @@ class IbanValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertViolationRaised($iban, Iban::INVALID_COUNTRY_CODE_ERROR);
|
$this->assertViolationRaised($iban, Iban::INVALID_COUNTRY_CODE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testLoadFromAttribute()
|
||||||
|
{
|
||||||
|
$classMetadata = new ClassMetadata(IbanDummy::class);
|
||||||
|
(new AnnotationLoader())->loadClassMetadata($classMetadata);
|
||||||
|
|
||||||
|
[$constraint] = $classMetadata->properties['iban']->constraints;
|
||||||
|
|
||||||
|
$this->validator->validate('DE89 3704 0044 0532 0130 01', $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"DE89 3704 0044 0532 0130 01"')
|
||||||
|
->setCode(Iban::CHECKSUM_FAILED_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function getIbansWithInvalidCountryCode()
|
public function getIbansWithInvalidCountryCode()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -446,3 +466,9 @@ class IbanValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IbanDummy
|
||||||
|
{
|
||||||
|
#[Iban(message: 'myMessage')]
|
||||||
|
private $iban;
|
||||||
|
}
|
||||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\Ip;
|
use Symfony\Component\Validator\Constraints\Ip;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Renan Taranto <renantaranto@gmail.com>
|
* @author Renan Taranto <renantaranto@gmail.com>
|
||||||
@ -39,4 +41,39 @@ class IpTest extends TestCase
|
|||||||
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
||||||
new Ip(['normalizer' => new \stdClass()]);
|
new Ip(['normalizer' => new \stdClass()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(IpDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame(Ip::V4, $aConstraint->version);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame(Ip::V6, $bConstraint->version);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame('trim', $bConstraint->normalizer);
|
||||||
|
self::assertSame(['Default', 'IpDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IpDummy
|
||||||
|
{
|
||||||
|
#[Ip]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Ip(version: Ip::V6, message: "myMessage", normalizer: 'trim')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Ip(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,19 @@ class IpValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testValidIpV6WithWhitespacesNamed()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
"\n\t2001:0db8:85a3:0000:0000:8a2e:0370:7334\r\n",
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Ip(version: \Symfony\Component\Validator\Constraints\Ip::V6, normalizer: "trim");')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
public function getValidIpsV4WithWhitespaces()
|
public function getValidIpsV4WithWhitespaces()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Isbn;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class IsbnTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(IsbnDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertNull($aConstraint->type);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame(Isbn::ISBN_13, $bConstraint->type);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'IsbnDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IsbnDummy
|
||||||
|
{
|
||||||
|
#[Isbn]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Isbn(message: "myMessage", type: Isbn::ISBN_13)]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Isbn(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -176,6 +176,22 @@ class IsbnValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidIsbn10Named()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'978-2723442282',
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Isbn(type: \Symfony\Component\Validator\Constraints\Isbn::ISBN_10, isbn10Message: "myMessage");')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"978-2723442282"')
|
||||||
|
->setCode(Isbn::TOO_LONG_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getValidIsbn13
|
* @dataProvider getValidIsbn13
|
||||||
*/
|
*/
|
||||||
@ -206,6 +222,22 @@ class IsbnValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidIsbn13Named()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'2723442284',
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Isbn(type: \Symfony\Component\Validator\Constraints\Isbn::ISBN_13, isbn13Message: "myMessage");')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"2723442284"')
|
||||||
|
->setCode(Isbn::TOO_SHORT_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getValidIsbn
|
* @dataProvider getValidIsbn
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Isin;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class IsinTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(IsinDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'IsinDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IsinDummy
|
||||||
|
{
|
||||||
|
#[Isin]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Isin(message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Isin(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Issn;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class IssnTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(IssnDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertFalse($aConstraint->caseSensitive);
|
||||||
|
self::assertFalse($aConstraint->requireHyphen);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertTrue($bConstraint->caseSensitive);
|
||||||
|
self::assertTrue($bConstraint->requireHyphen);
|
||||||
|
self::assertSame(['Default', 'IssnDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IssnDummy
|
||||||
|
{
|
||||||
|
#[Issn]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Issn(message: 'myMessage', caseSensitive: true, requireHyphen: true)]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Issn(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -177,4 +177,20 @@ class IssnValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->setCode($code)
|
->setCode($code)
|
||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testNamedArguments()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'2162321x',
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Issn(message: "myMessage", caseSensitive: true, requireHyphen: true);')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"2162321x"')
|
||||||
|
->setCode(Issn::MISSING_HYPHEN_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Json;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class JsonTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(JsonDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'JsonDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JsonDummy
|
||||||
|
{
|
||||||
|
#[Json]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Json(message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Json(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Language;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class LanguageTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(LanguageDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertFalse($aConstraint->alpha3);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertTrue($bConstraint->alpha3);
|
||||||
|
self::assertSame(['Default', 'LanguageDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LanguageDummy
|
||||||
|
{
|
||||||
|
#[Language]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Language(message: 'myMessage', alpha3: true)]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Language(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -151,6 +151,23 @@ class LanguageValidatorTest extends ConstraintValidatorTestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidAlpha3LanguageNamed()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'DE',
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Language(alpha3: true, message: "myMessage");')
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"DE"')
|
||||||
|
->setCode(Language::NO_SUCH_LANGUAGE_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidateUsingCountrySpecificLocale()
|
public function testValidateUsingCountrySpecificLocale()
|
||||||
{
|
{
|
||||||
IntlTestHelper::requireFullIntl($this, false);
|
IntlTestHelper::requireFullIntl($this, false);
|
||||||
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||||
use Symfony\Component\Validator\Constraints\Length;
|
use Symfony\Component\Validator\Constraints\Length;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Renan Taranto <renantaranto@gmail.com>
|
* @author Renan Taranto <renantaranto@gmail.com>
|
||||||
@ -61,4 +63,60 @@ class LengthTest extends TestCase
|
|||||||
[false],
|
[false],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testConstraintDefaultOption()
|
||||||
|
{
|
||||||
|
$constraint = new Length(5);
|
||||||
|
|
||||||
|
self::assertEquals(5, $constraint->min);
|
||||||
|
self::assertEquals(5, $constraint->max);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstraintAnnotationDefaultOption()
|
||||||
|
{
|
||||||
|
$constraint = new Length(['value' => 5, 'exactMessage' => 'message']);
|
||||||
|
|
||||||
|
self::assertEquals(5, $constraint->min);
|
||||||
|
self::assertEquals(5, $constraint->max);
|
||||||
|
self::assertEquals('message', $constraint->exactMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(LengthDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame(42, $aConstraint->min);
|
||||||
|
self::assertSame(42, $aConstraint->max);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame(1, $bConstraint->min);
|
||||||
|
self::assertSame(4711, $bConstraint->max);
|
||||||
|
self::assertSame('myMinMessage', $bConstraint->minMessage);
|
||||||
|
self::assertSame('myMaxMessage', $bConstraint->maxMessage);
|
||||||
|
self::assertSame('trim', $bConstraint->normalizer);
|
||||||
|
self::assertSame('ISO-8859-15', $bConstraint->charset);
|
||||||
|
self::assertSame(['Default', 'LengthDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LengthDummy
|
||||||
|
{
|
||||||
|
#[Length(exactly: 42)]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Length(min: 1, max: 4711, minMessage: 'myMinMessage', maxMessage: 'myMaxMessage', normalizer: 'trim', charset: 'ISO-8859-15')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Length(exactly: 10, groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,25 @@ class LengthValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getThreeOrLessCharacters
|
||||||
|
*/
|
||||||
|
public function testInvalidValuesMinNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Length(min: 4, minMessage: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"'.$value.'"')
|
||||||
|
->setParameter('{{ limit }}', 4)
|
||||||
|
->setInvalidValue($value)
|
||||||
|
->setPlural(4)
|
||||||
|
->setCode(Length::TOO_SHORT_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getFiveOrMoreCharacters
|
* @dataProvider getFiveOrMoreCharacters
|
||||||
*/
|
*/
|
||||||
@ -207,6 +226,25 @@ class LengthValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getFiveOrMoreCharacters
|
||||||
|
*/
|
||||||
|
public function testInvalidValuesMaxNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Length(max: 4, maxMessage: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"'.$value.'"')
|
||||||
|
->setParameter('{{ limit }}', 4)
|
||||||
|
->setInvalidValue($value)
|
||||||
|
->setPlural(4)
|
||||||
|
->setCode(Length::TOO_LONG_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getThreeOrLessCharacters
|
* @dataProvider getThreeOrLessCharacters
|
||||||
*/
|
*/
|
||||||
@ -229,6 +267,25 @@ class LengthValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getThreeOrLessCharacters
|
||||||
|
*/
|
||||||
|
public function testInvalidValuesExactLessThanFourNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Length(exactly: 4, exactMessage: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"'.$value.'"')
|
||||||
|
->setParameter('{{ limit }}', 4)
|
||||||
|
->setInvalidValue($value)
|
||||||
|
->setPlural(4)
|
||||||
|
->setCode(Length::TOO_SHORT_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getFiveOrMoreCharacters
|
* @dataProvider getFiveOrMoreCharacters
|
||||||
*/
|
*/
|
||||||
@ -276,21 +333,4 @@ class LengthValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConstraintDefaultOption()
|
|
||||||
{
|
|
||||||
$constraint = new Length(5);
|
|
||||||
|
|
||||||
$this->assertEquals(5, $constraint->min);
|
|
||||||
$this->assertEquals(5, $constraint->max);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testConstraintAnnotationDefaultOption()
|
|
||||||
{
|
|
||||||
$constraint = new Length(['value' => 5, 'exactMessage' => 'message']);
|
|
||||||
|
|
||||||
$this->assertEquals(5, $constraint->min);
|
|
||||||
$this->assertEquals(5, $constraint->max);
|
|
||||||
$this->assertEquals('message', $constraint->exactMessage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Locale;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class LocaleTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(LocaleDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertTrue($aConstraint->canonicalize);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertFalse($bConstraint->canonicalize);
|
||||||
|
self::assertSame(['Default', 'LocaleDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocaleDummy
|
||||||
|
{
|
||||||
|
#[Locale]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Locale(message: 'myMessage', canonicalize: false)]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Locale(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -104,6 +104,55 @@ class LocaleValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidLocales
|
||||||
|
*/
|
||||||
|
public function testValidLocalesWithoutCanonicalization(string $locale)
|
||||||
|
{
|
||||||
|
$constraint = new Locale([
|
||||||
|
'message' => 'myMessage',
|
||||||
|
'canonicalize' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->validator->validate($locale, $constraint);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getUncanonicalizedLocales
|
||||||
|
*/
|
||||||
|
public function testInvalidLocalesWithoutCanonicalization(string $locale)
|
||||||
|
{
|
||||||
|
$constraint = new Locale([
|
||||||
|
'message' => 'myMessage',
|
||||||
|
'canonicalize' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->validator->validate($locale, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"'.$locale.'"')
|
||||||
|
->setCode(Locale::NO_SUCH_LOCALE_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidLocaleWithoutCanonicalizationNamed()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'en-US',
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Locale(message: "myMessage", canonicalize: false);')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"en-US"')
|
||||||
|
->setCode(Locale::NO_SUCH_LOCALE_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function getUncanonicalizedLocales(): iterable
|
public function getUncanonicalizedLocales(): iterable
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Luhn;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class LuhnTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(LuhnDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'LuhnDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LuhnDummy
|
||||||
|
{
|
||||||
|
#[Luhn]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Luhn(message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Luhn(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\NotCompromisedPassword;
|
use Symfony\Component\Validator\Constraints\NotCompromisedPassword;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
@ -25,4 +27,40 @@ class NotCompromisedPasswordTest extends TestCase
|
|||||||
$this->assertSame(1, $constraint->threshold);
|
$this->assertSame(1, $constraint->threshold);
|
||||||
$this->assertFalse($constraint->skipOnError);
|
$this->assertFalse($constraint->skipOnError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(NotCompromisedPasswordDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame(1, $aConstraint->threshold);
|
||||||
|
self::assertFalse($aConstraint->skipOnError);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(42, $bConstraint->threshold);
|
||||||
|
self::assertTrue($bConstraint->skipOnError);
|
||||||
|
self::assertSame(['Default', 'NotCompromisedPasswordDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotCompromisedPasswordDummy
|
||||||
|
{
|
||||||
|
#[NotCompromisedPassword]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[NotCompromisedPassword(message: 'myMessage', threshold: 42, skipOnError: true)]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[NotCompromisedPassword(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
}
|
}
|
||||||
|
@ -91,13 +91,25 @@ class NotCompromisedPasswordValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThresholdNotReached()
|
/**
|
||||||
|
* @dataProvider provideConstraintsWithThreshold
|
||||||
|
*/
|
||||||
|
public function testThresholdNotReached(NotCompromisedPassword $constraint)
|
||||||
{
|
{
|
||||||
$this->validator->validate(self::PASSWORD_LEAKED, new NotCompromisedPassword(['threshold' => 10]));
|
$this->validator->validate(self::PASSWORD_LEAKED, $constraint);
|
||||||
|
|
||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideConstraintsWithThreshold(): iterable
|
||||||
|
{
|
||||||
|
yield 'Doctrine style' => [new NotCompromisedPassword(['threshold' => 10])];
|
||||||
|
|
||||||
|
if (\PHP_VERSION_ID >= 80000) {
|
||||||
|
yield 'named arguments' => [eval('return new \Symfony\Component\Validator\Constraints\NotCompromisedPassword(threshold: 10);')];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidPassword()
|
public function testValidPassword()
|
||||||
{
|
{
|
||||||
$this->validator->validate(self::PASSWORD_NOT_LEAKED, new NotCompromisedPassword());
|
$this->validator->validate(self::PASSWORD_NOT_LEAKED, new NotCompromisedPassword());
|
||||||
@ -170,12 +182,24 @@ class NotCompromisedPasswordValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->validator->validate(self::PASSWORD_TRIGGERING_AN_ERROR, new NotCompromisedPassword());
|
$this->validator->validate(self::PASSWORD_TRIGGERING_AN_ERROR, new NotCompromisedPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testApiErrorSkipped()
|
/**
|
||||||
|
* @dataProvider provideErrorSkippingConstraints
|
||||||
|
*/
|
||||||
|
public function testApiErrorSkipped(NotCompromisedPassword $constraint)
|
||||||
{
|
{
|
||||||
$this->validator->validate(self::PASSWORD_TRIGGERING_AN_ERROR, new NotCompromisedPassword(['skipOnError' => true]));
|
$this->validator->validate(self::PASSWORD_TRIGGERING_AN_ERROR, $constraint);
|
||||||
$this->assertTrue(true); // No exception have been thrown
|
$this->assertTrue(true); // No exception have been thrown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideErrorSkippingConstraints(): iterable
|
||||||
|
{
|
||||||
|
yield 'Doctrine style' => [new NotCompromisedPassword(['skipOnError' => true])];
|
||||||
|
|
||||||
|
if (\PHP_VERSION_ID >= 80000) {
|
||||||
|
yield 'named arguments' => [eval('return new \Symfony\Component\Validator\Constraints\NotCompromisedPassword(skipOnError: true);')];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function createHttpClientStub(): HttpClientInterface
|
private function createHttpClientStub(): HttpClientInterface
|
||||||
{
|
{
|
||||||
$httpClientStub = $this->createMock(HttpClientInterface::class);
|
$httpClientStub = $this->createMock(HttpClientInterface::class);
|
||||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\Regex;
|
use Symfony\Component\Validator\Constraints\Regex;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
@ -106,4 +108,42 @@ class RegexTest extends TestCase
|
|||||||
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
||||||
new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => new \stdClass()]);
|
new Regex(['pattern' => '/^[0-9]+$/', 'normalizer' => new \stdClass()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(RegexDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame('/^[0-9]+$/', $aConstraint->pattern);
|
||||||
|
self::assertTrue($aConstraint->match);
|
||||||
|
self::assertNull($aConstraint->normalizer);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame('/^[0-9]+$/', $bConstraint->pattern);
|
||||||
|
self::assertSame('[0-9]+', $bConstraint->htmlPattern);
|
||||||
|
self::assertFalse($bConstraint->match);
|
||||||
|
self::assertSame(['Default', 'RegexDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegexDummy
|
||||||
|
{
|
||||||
|
#[Regex('/^[0-9]+$/')]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Regex(message: 'myMessage', pattern: '/^[0-9]+$/', htmlPattern: '[0-9]+', match: false, normalizer: 'trim')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Regex('/^[0-9]+$/', groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,18 @@ class RegexValidatorTest extends ConstraintValidatorTestCase
|
|||||||
$this->assertNoViolation();
|
$this->assertNoViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getValidValuesWithWhitespaces
|
||||||
|
*/
|
||||||
|
public function testValidValuesWithWhitespacesNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Regex(pattern: "/^[0-9]+\$/", normalizer: "trim");');
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
public function getValidValues()
|
public function getValidValues()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -110,6 +122,22 @@ class RegexValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
* @dataProvider getInvalidValues
|
||||||
|
*/
|
||||||
|
public function testInvalidValuesNamed($value)
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Regex(pattern: "/^[0-9]+\$/", message: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate($value, $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"'.$value.'"')
|
||||||
|
->setCode(Regex::REGEX_FAILED_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
public function getInvalidValues()
|
public function getInvalidValues()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Time;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class TimeTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(TimeDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'TimeDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeDummy
|
||||||
|
{
|
||||||
|
#[Time]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Time(message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Time(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\Timezone;
|
use Symfony\Component\Validator\Constraints\Timezone;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Javier Spagnoletti <phansys@gmail.com>
|
* @author Javier Spagnoletti <phansys@gmail.com>
|
||||||
@ -62,4 +64,38 @@ class TimezoneTest extends TestCase
|
|||||||
yield [0];
|
yield [0];
|
||||||
yield [\DateTimeZone::ALL_WITH_BC + 1];
|
yield [\DateTimeZone::ALL_WITH_BC + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(TimezoneDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame(\DateTimeZone::ALL, $aConstraint->zone);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame(\DateTimeZone::PER_COUNTRY, $bConstraint->zone);
|
||||||
|
self::assertSame('DE', $bConstraint->countryCode);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'TimezoneDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimezoneDummy
|
||||||
|
{
|
||||||
|
#[Timezone]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Timezone(zone: \DateTimeZone::PER_COUNTRY, countryCode: 'DE', message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Timezone(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,21 @@ class TimezoneValidatorTest extends ConstraintValidatorTestCase
|
|||||||
yield ['Etc/UTC', \DateTimeZone::EUROPE];
|
yield ['Etc/UTC', \DateTimeZone::EUROPE];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidGroupedTimezoneNamed()
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Timezone(zone: \DateTimeZone::AMERICA, message: "myMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate('Europe/Berlin', $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"Europe/Berlin"')
|
||||||
|
->setCode(Timezone::TIMEZONE_IDENTIFIER_IN_ZONE_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getValidGroupedTimezonesByCountry
|
* @dataProvider getValidGroupedTimezonesByCountry
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Traverse;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
use Symfony\Component\Validator\Mapping\TraversalStrategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class TraverseTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testPositiveAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(TraverseDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
self::assertSame(TraversalStrategy::TRAVERSE, $metadata->getTraversalStrategy());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNegativeAttribute()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(DoNotTraverseMe::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
self::assertSame(TraversalStrategy::NONE, $metadata->getTraversalStrategy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Traverse]
|
||||||
|
class TraverseDummy
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Traverse(false)]
|
||||||
|
class DoNotTraverseMe
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Type;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class TypeTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(TypeDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame('integer', $aConstraint->type);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame(\DateTime::class, $bConstraint->type);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'TypeDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['string', 'array'], $cConstraint->type);
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeDummy
|
||||||
|
{
|
||||||
|
#[Type('integer')]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Type(type: \DateTime::class, message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Type(type: ['string', 'array'], groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -184,29 +184,29 @@ class TypeValidatorTest extends ConstraintValidatorTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getInvalidValuesMultipleTypes
|
* @dataProvider provideConstraintsWithMultipleTypes
|
||||||
*/
|
*/
|
||||||
public function testInvalidValuesMultipleTypes($value, $types, $valueAsString)
|
public function testInvalidValuesMultipleTypes(Type $constraint)
|
||||||
{
|
{
|
||||||
$constraint = new Type([
|
$this->validator->validate('12345', $constraint);
|
||||||
'type' => $types,
|
|
||||||
'message' => 'myMessage',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->validator->validate($value, $constraint);
|
|
||||||
|
|
||||||
$this->buildViolation('myMessage')
|
$this->buildViolation('myMessage')
|
||||||
->setParameter('{{ value }}', $valueAsString)
|
->setParameter('{{ value }}', '"12345"')
|
||||||
->setParameter('{{ type }}', implode('|', $types))
|
->setParameter('{{ type }}', implode('|', ['boolean', 'array']))
|
||||||
->setCode(Type::INVALID_TYPE_ERROR)
|
->setCode(Type::INVALID_TYPE_ERROR)
|
||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInvalidValuesMultipleTypes()
|
public function provideConstraintsWithMultipleTypes()
|
||||||
{
|
{
|
||||||
return [
|
yield 'Doctrine style' => [new Type([
|
||||||
['12345', ['boolean', 'array'], '"12345"'],
|
'type' => ['boolean', 'array'],
|
||||||
];
|
'message' => 'myMessage',
|
||||||
|
])];
|
||||||
|
|
||||||
|
if (\PHP_VERSION_ID >= 80000) {
|
||||||
|
yield 'named arguments' => [eval('return new \Symfony\Component\Validator\Constraints\Type(type: ["boolean", "array"], message: "myMessage");')];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createFile()
|
protected function createFile()
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Ulid;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class UlidTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(UlidDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'UlidDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UlidDummy
|
||||||
|
{
|
||||||
|
#[Ulid]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Ulid(message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Ulid(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -80,4 +80,19 @@ class UlidValidatorTest extends ConstraintValidatorTestCase
|
|||||||
['Z1ARZ3NDEKTSV4RRFFQ69G5FAV', Ulid::TOO_LARGE_ERROR],
|
['Z1ARZ3NDEKTSV4RRFFQ69G5FAV', Ulid::TOO_LARGE_ERROR],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidUlidNamed()
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Ulid(message: "testMessage");');
|
||||||
|
|
||||||
|
$this->validator->validate('01ARZ3NDEKTSV4RRFFQ69G5FA', $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('testMessage')
|
||||||
|
->setParameter('{{ value }}', '"01ARZ3NDEKTSV4RRFFQ69G5FA"')
|
||||||
|
->setCode(Ulid::TOO_SHORT_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Constraints\Unique;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
class UniqueTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(UniqueDummy::class);
|
||||||
|
$loader = new AnnotationLoader();
|
||||||
|
self::assertTrue($loader->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'UniqueDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UniqueDummy
|
||||||
|
{
|
||||||
|
#[Unique]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Unique(message: 'myMessage')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Unique(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
|
}
|
@ -84,4 +84,18 @@ class UniqueValidatorTest extends ConstraintValidatorTestCase
|
|||||||
yield 'not unique objects' => [[$object, $object]],
|
yield 'not unique objects' => [[$object, $object]],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidValueNamed()
|
||||||
|
{
|
||||||
|
$constraint = eval('return new \Symfony\Component\Validator\Constraints\Unique(message: "myMessage");');
|
||||||
|
$this->validator->validate([1, 2, 3, 3], $constraint);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', 'array')
|
||||||
|
->setCode(Unique::IS_NOT_UNIQUE)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\Url;
|
use Symfony\Component\Validator\Constraints\Url;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Renan Taranto <renantaranto@gmail.com>
|
* @author Renan Taranto <renantaranto@gmail.com>
|
||||||
@ -39,4 +41,41 @@ class UrlTest extends TestCase
|
|||||||
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
||||||
new Url(['normalizer' => new \stdClass()]);
|
new Url(['normalizer' => new \stdClass()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(UrlDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame(['http', 'https'], $aConstraint->protocols);
|
||||||
|
self::assertFalse($aConstraint->relativeProtocol);
|
||||||
|
self::assertNull($aConstraint->normalizer);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame(['ftp', 'gopher'], $bConstraint->protocols);
|
||||||
|
self::assertSame('trim', $bConstraint->normalizer);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'UrlDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertTrue($cConstraint->relativeProtocol);
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UrlDummy
|
||||||
|
{
|
||||||
|
#[Url]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Url(message: 'myMessage', protocols: ['ftp', 'gopher'], normalizer: 'trim')]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Url(relativeProtocol: true, groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Validator\Tests\Constraints;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Validator\Constraints\Uuid;
|
use Symfony\Component\Validator\Constraints\Uuid;
|
||||||
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
|
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Renan Taranto <renantaranto@gmail.com>
|
* @author Renan Taranto <renantaranto@gmail.com>
|
||||||
@ -39,4 +41,41 @@ class UuidTest extends TestCase
|
|||||||
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
$this->expectExceptionMessage('The "normalizer" option must be a valid callable ("stdClass" given).');
|
||||||
new Uuid(['normalizer' => new \stdClass()]);
|
new Uuid(['normalizer' => new \stdClass()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testAttributes()
|
||||||
|
{
|
||||||
|
$metadata = new ClassMetadata(UuidDummy::class);
|
||||||
|
self::assertTrue((new AnnotationLoader())->loadClassMetadata($metadata));
|
||||||
|
|
||||||
|
list($aConstraint) = $metadata->properties['a']->getConstraints();
|
||||||
|
self::assertSame(Uuid::ALL_VERSIONS, $aConstraint->versions);
|
||||||
|
self::assertTrue($aConstraint->strict);
|
||||||
|
self::assertNull($aConstraint->normalizer);
|
||||||
|
|
||||||
|
list($bConstraint) = $metadata->properties['b']->getConstraints();
|
||||||
|
self::assertSame([Uuid::V4_RANDOM, Uuid::V6_SORTABLE], $bConstraint->versions);
|
||||||
|
self::assertFalse($bConstraint->strict);
|
||||||
|
self::assertSame('trim', $bConstraint->normalizer);
|
||||||
|
self::assertSame('myMessage', $bConstraint->message);
|
||||||
|
self::assertSame(['Default', 'UuidDummy'], $bConstraint->groups);
|
||||||
|
|
||||||
|
list($cConstraint) = $metadata->properties['c']->getConstraints();
|
||||||
|
self::assertSame(['my_group'], $cConstraint->groups);
|
||||||
|
self::assertSame('some attached data', $cConstraint->payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UuidDummy
|
||||||
|
{
|
||||||
|
#[Uuid]
|
||||||
|
private $a;
|
||||||
|
|
||||||
|
#[Uuid(message: 'myMessage', versions: [Uuid::V4_RANDOM, Uuid::V6_SORTABLE], normalizer: 'trim', strict: false)]
|
||||||
|
private $b;
|
||||||
|
|
||||||
|
#[Uuid(groups: ['my_group'], payload: 'some attached data')]
|
||||||
|
private $c;
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,19 @@ class UuidValidatorTest extends ConstraintValidatorTestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testValidStrictUuidWithWhitespacesNamed()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
"\x09\x09216fff40-98d9-11e3-a5e2-0800200c9a66",
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Uuid(normalizer: "trim", versions: [\Symfony\Component\Validator\Constraints\Uuid::V1_MAC]);')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertNoViolation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getInvalidStrictUuids
|
* @dataProvider getInvalidStrictUuids
|
||||||
*/
|
*/
|
||||||
@ -237,4 +250,20 @@ class UuidValidatorTest extends ConstraintValidatorTestCase
|
|||||||
['216fff40-98d9-11e3-a5e2-0800200c9a666', Uuid::TOO_LONG_ERROR],
|
['216fff40-98d9-11e3-a5e2-0800200c9a666', Uuid::TOO_LONG_ERROR],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testInvalidNonStrictUuidNamed()
|
||||||
|
{
|
||||||
|
$this->validator->validate(
|
||||||
|
'216fff40-98d9-11e3-a5e2_0800200c9a66',
|
||||||
|
eval('return new \Symfony\Component\Validator\Constraints\Uuid(strict: false, message: "myMessage");')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->buildViolation('myMessage')
|
||||||
|
->setParameter('{{ value }}', '"216fff40-98d9-11e3-a5e2_0800200c9a66"')
|
||||||
|
->setCode(Uuid::INVALID_CHARACTERS_ERROR)
|
||||||
|
->assertRaised();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user