diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md
index 3863b5717a1f..e2dfc921e40b 100644
--- a/src/Symfony/Component/Validator/CHANGELOG.md
+++ b/src/Symfony/Component/Validator/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+4.3.0
+-----
+
+ * added options `iban` and `ibanPropertyPath` to Bic constraint
+
4.2.0
-----
diff --git a/src/Symfony/Component/Validator/Constraints/Bic.php b/src/Symfony/Component/Validator/Constraints/Bic.php
index 9af23c8ddb89..2e1fa68df123 100644
--- a/src/Symfony/Component/Validator/Constraints/Bic.php
+++ b/src/Symfony/Component/Validator/Constraints/Bic.php
@@ -12,7 +12,9 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Intl\Intl;
+use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\LogicException;
/**
@@ -28,6 +30,7 @@ class Bic extends Constraint
const INVALID_BANK_CODE_ERROR = '00559357-6170-4f29-aebd-d19330aa19cf';
const INVALID_COUNTRY_CODE_ERROR = '1ce76f8d-3c1f-451c-9e62-fe9c3ed486ae';
const INVALID_CASE_ERROR = '11884038-3312-4ae5-9d04-699f782130c7';
+ const INVALID_IBAN_COUNTRY_CODE_ERROR = '29a2c3bb-587b-4996-b6f5-53081364cea5';
protected static $errorNames = array(
self::INVALID_LENGTH_ERROR => 'INVALID_LENGTH_ERROR',
@@ -38,6 +41,9 @@ class Bic extends Constraint
);
public $message = 'This is not a valid Business Identifier Code (BIC).';
+ public $ibanMessage = 'This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.';
+ public $iban;
+ public $ibanPropertyPath;
public function __construct($options = null)
{
@@ -46,6 +52,14 @@ public function __construct($options = null)
@trigger_error(sprintf('Using the "%s" constraint without the "symfony/intl" component installed is deprecated since Symfony 4.2.', __CLASS__), E_USER_DEPRECATED);
}
+ if (isset($options['iban']) && isset($options['ibanPropertyPath'])) {
+ throw new ConstraintDefinitionException(sprintf('The "iban" and "ibanPropertyPath" options of the Iban constraint cannot be used at the same time.', self::class));
+ }
+
+ if (isset($options['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));
+ }
+
parent::__construct($options);
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/BicValidator.php b/src/Symfony/Component/Validator/Constraints/BicValidator.php
index 7daf9a9c250d..6d077b6d0920 100644
--- a/src/Symfony/Component/Validator/Constraints/BicValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/BicValidator.php
@@ -12,8 +12,12 @@
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Intl\Intl;
+use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+use Symfony\Component\PropertyAccess\PropertyAccessor;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\LogicException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;
@@ -24,6 +28,13 @@
*/
class BicValidator extends ConstraintValidator
{
+ private $propertyAccessor;
+
+ public function __construct(PropertyAccessor $propertyAccessor = null)
+ {
+ $this->propertyAccessor = $propertyAccessor;
+ }
+
/**
* {@inheritdoc}
*/
@@ -95,5 +106,39 @@ public function validate($value, Constraint $constraint)
return;
}
+
+ // check against an IBAN
+ $iban = $constraint->iban;
+ $path = $constraint->ibanPropertyPath;
+ if ($path && null !== $object = $this->context->getObject()) {
+ try {
+ $iban = $this->getPropertyAccessor()->getValue($object, $path);
+ } catch (NoSuchPropertyException $e) {
+ throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: %s', $path, \get_class($constraint), $e->getMessage()), 0, $e);
+ }
+ }
+ if (!$iban) {
+ return;
+ }
+ $ibanCountryCode = substr($iban, 0, 2);
+ if (ctype_alpha($ibanCountryCode) && substr($canonicalize, 4, 2) !== $ibanCountryCode) {
+ $this->context->buildViolation($constraint->ibanMessage)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setParameter('{{ iban }}', $iban)
+ ->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
+ ->addViolation();
+ }
+ }
+
+ private function getPropertyAccessor(): PropertyAccessor
+ {
+ if (null === $this->propertyAccessor) {
+ if (!class_exists(PropertyAccess::class)) {
+ throw new LogicException('Unable to use property path as the Symfony PropertyAccess component is not installed.');
+ }
+ $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
+ }
+
+ return $this->propertyAccessor;
}
}
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
index 4bb2760b418e..30e6804c7b83 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
@@ -326,6 +326,10 @@
This value should be a multiple of {{ compared_value }}.
+
+
+ This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.
+