Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cc0be40

Browse filesBrowse files
feature #28479 [Validator] Checking a BIC along with an IBAN (sylfabre)
This PR was merged into the 4.3-dev branch. Discussion ---------- [Validator] Checking a BIC along with an IBAN | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #28166 | License | MIT | Doc PR | symfony/symfony-docs#10349 A BIC comes usually with an IBAN so it's better to check that they are associated. This PR provides an `iban` option to `Symfony\Component\Validator\Constraints\Bic` to check the BIC against an IBAN. It also provides an `ibanPropertyPath` to retrieves the IBAN using the property accessor like with comparison constraints. Commits ------- bb6be15 [Validator] Checking a BIC along with an IBAN Fix #28166
2 parents e695449 + bb6be15 commit cc0be40
Copy full SHA for cc0be40

File tree

6 files changed

+200
-0
lines changed
Filter options

6 files changed

+200
-0
lines changed

‎src/Symfony/Component/Validator/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
4.3.0
5+
-----
6+
7+
* added options `iban` and `ibanPropertyPath` to Bic constraint
8+
49
4.2.0
510
-----
611

‎src/Symfony/Component/Validator/Constraints/Bic.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Constraints/Bic.php
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
namespace Symfony\Component\Validator\Constraints;
1313

1414
use Symfony\Component\Intl\Intl;
15+
use Symfony\Component\PropertyAccess\PropertyAccess;
1516
use Symfony\Component\Validator\Constraint;
17+
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
1618
use Symfony\Component\Validator\Exception\LogicException;
1719

1820
/**
@@ -28,6 +30,7 @@ class Bic extends Constraint
2830
const INVALID_BANK_CODE_ERROR = '00559357-6170-4f29-aebd-d19330aa19cf';
2931
const INVALID_COUNTRY_CODE_ERROR = '1ce76f8d-3c1f-451c-9e62-fe9c3ed486ae';
3032
const INVALID_CASE_ERROR = '11884038-3312-4ae5-9d04-699f782130c7';
33+
const INVALID_IBAN_COUNTRY_CODE_ERROR = '29a2c3bb-587b-4996-b6f5-53081364cea5';
3134

3235
protected static $errorNames = array(
3336
self::INVALID_LENGTH_ERROR => 'INVALID_LENGTH_ERROR',
@@ -38,6 +41,9 @@ class Bic extends Constraint
3841
);
3942

4043
public $message = 'This is not a valid Business Identifier Code (BIC).';
44+
public $ibanMessage = 'This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.';
45+
public $iban;
46+
public $ibanPropertyPath;
4147

4248
public function __construct($options = null)
4349
{
@@ -46,6 +52,14 @@ public function __construct($options = null)
4652
@trigger_error(sprintf('Using the "%s" constraint without the "symfony/intl" component installed is deprecated since Symfony 4.2.', __CLASS__), E_USER_DEPRECATED);
4753
}
4854

55+
if (isset($options['iban']) && isset($options['ibanPropertyPath'])) {
56+
throw new ConstraintDefinitionException(sprintf('The "iban" and "ibanPropertyPath" options of the Iban constraint cannot be used at the same time.', self::class));
57+
}
58+
59+
if (isset($options['ibanPropertyPath']) && !class_exists(PropertyAccess::class)) {
60+
throw new LogicException(sprintf('The "symfony/property-access" component is required to use the "%s" constraint with the "ibanPropertyPath" option.', self::class));
61+
}
62+
4963
parent::__construct($options);
5064
}
5165
}

‎src/Symfony/Component/Validator/Constraints/BicValidator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Constraints/BicValidator.php
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@
1212
namespace Symfony\Component\Validator\Constraints;
1313

1414
use Symfony\Component\Intl\Intl;
15+
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
16+
use Symfony\Component\PropertyAccess\PropertyAccess;
17+
use Symfony\Component\PropertyAccess\PropertyAccessor;
1518
use Symfony\Component\Validator\Constraint;
1619
use Symfony\Component\Validator\ConstraintValidator;
20+
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
1721
use Symfony\Component\Validator\Exception\LogicException;
1822
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
1923
use Symfony\Component\Validator\Exception\UnexpectedValueException;
@@ -25,6 +29,13 @@
2529
*/
2630
class BicValidator extends ConstraintValidator
2731
{
32+
private $propertyAccessor;
33+
34+
public function __construct(PropertyAccessor $propertyAccessor = null)
35+
{
36+
$this->propertyAccessor = $propertyAccessor;
37+
}
38+
2839
/**
2940
* {@inheritdoc}
3041
*/
@@ -100,5 +111,39 @@ public function validate($value, Constraint $constraint)
100111

101112
return;
102113
}
114+
115+
// check against an IBAN
116+
$iban = $constraint->iban;
117+
$path = $constraint->ibanPropertyPath;
118+
if ($path && null !== $object = $this->context->getObject()) {
119+
try {
120+
$iban = $this->getPropertyAccessor()->getValue($object, $path);
121+
} catch (NoSuchPropertyException $e) {
122+
throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: %s', $path, \get_class($constraint), $e->getMessage()), 0, $e);
123+
}
124+
}
125+
if (!$iban) {
126+
return;
127+
}
128+
$ibanCountryCode = substr($iban, 0, 2);
129+
if (ctype_alpha($ibanCountryCode) && substr($canonicalize, 4, 2) !== $ibanCountryCode) {
130+
$this->context->buildViolation($constraint->ibanMessage)
131+
->setParameter('{{ value }}', $this->formatValue($value))
132+
->setParameter('{{ iban }}', $iban)
133+
->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
134+
->addViolation();
135+
}
136+
}
137+
138+
private function getPropertyAccessor(): PropertyAccessor
139+
{
140+
if (null === $this->propertyAccessor) {
141+
if (!class_exists(PropertyAccess::class)) {
142+
throw new LogicException('Unable to use property path as the Symfony PropertyAccess component is not installed.');
143+
}
144+
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
145+
}
146+
147+
return $this->propertyAccessor;
103148
}
104149
}

‎src/Symfony/Component/Validator/Resources/translations/validators.en.xlf

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,10 @@
326326
<source>This value should be a multiple of {{ compared_value }}.</source>
327327
<target>This value should be a multiple of {{ compared_value }}.</target>
328328
</trans-unit>
329+
<trans-unit id="85">
330+
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
331+
<target>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</target>
332+
</trans-unit>
329333
</body>
330334
</file>
331335
</xliff>

‎src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,10 @@
326326
<source>This value should be a multiple of {{ compared_value }}.</source>
327327
<target>Cette valeur doit être un multiple de {{ compared_value }}.</target>
328328
</trans-unit>
329+
<trans-unit id="85">
330+
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
331+
<target>Ce BIC n'est pas associé à l'IBAN {{ iban }}.</target>
332+
</trans-unit>
329333
</body>
330334
</file>
331335
</xliff>

‎src/Symfony/Component/Validator/Tests/Constraints/BicValidatorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Tests/Constraints/BicValidatorTest.php
+128Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Validator\Constraints\Bic;
1515
use Symfony\Component\Validator\Constraints\BicValidator;
16+
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
1617
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
1718

1819
class BicValidatorTest extends ConstraintValidatorTestCase
@@ -36,6 +37,113 @@ public function testEmptyStringIsValid()
3637
$this->assertNoViolation();
3738
}
3839

40+
public function testValidComparisonToPropertyPath()
41+
{
42+
$constraint = new Bic(array('ibanPropertyPath' => 'value'));
43+
44+
$object = new BicComparisonTestClass('FR14 2004 1010 0505 0001 3M02 606');
45+
46+
$this->setObject($object);
47+
48+
$this->validator->validate('SOGEFRPP', $constraint);
49+
50+
$this->assertNoViolation();
51+
}
52+
53+
public function testValidComparisonToPropertyPathOnArray()
54+
{
55+
$constraint = new Bic(array('ibanPropertyPath' => '[root][value]'));
56+
57+
$this->setObject(array('root' => array('value' => 'FR14 2004 1010 0505 0001 3M02 606')));
58+
59+
$this->validator->validate('SOGEFRPP', $constraint);
60+
61+
$this->assertNoViolation();
62+
}
63+
64+
public function testInvalidComparisonToPropertyPath()
65+
{
66+
$constraint = new Bic(array('ibanPropertyPath' => 'value'));
67+
$constraint->ibanMessage = 'Constraint Message';
68+
69+
$object = new BicComparisonTestClass('FR14 2004 1010 0505 0001 3M02 606');
70+
71+
$this->setObject($object);
72+
73+
$this->validator->validate('UNCRIT2B912', $constraint);
74+
75+
$this->buildViolation('Constraint Message')
76+
->setParameter('{{ value }}', '"UNCRIT2B912"')
77+
->setParameter('{{ iban }}', 'FR14 2004 1010 0505 0001 3M02 606')
78+
->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
79+
->assertRaised();
80+
}
81+
82+
public function testValidComparisonToValue()
83+
{
84+
$constraint = new Bic(array('iban' => 'FR14 2004 1010 0505 0001 3M02 606'));
85+
$constraint->ibanMessage = 'Constraint Message';
86+
87+
$this->validator->validate('SOGEFRPP', $constraint);
88+
89+
$this->assertNoViolation();
90+
}
91+
92+
public function testInvalidComparisonToValue()
93+
{
94+
$constraint = new Bic(array('iban' => 'FR14 2004 1010 0505 0001 3M02 606'));
95+
$constraint->ibanMessage = 'Constraint Message';
96+
97+
$this->validator->validate('UNCRIT2B912', $constraint);
98+
99+
$this->buildViolation('Constraint Message')
100+
->setParameter('{{ value }}', '"UNCRIT2B912"')
101+
->setParameter('{{ iban }}', 'FR14 2004 1010 0505 0001 3M02 606')
102+
->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
103+
->assertRaised();
104+
}
105+
106+
public function testNoViolationOnNullObjectWithPropertyPath()
107+
{
108+
$constraint = new Bic(array('ibanPropertyPath' => 'propertyPath'));
109+
110+
$this->setObject(null);
111+
112+
$this->validator->validate('UNCRIT2B912', $constraint);
113+
114+
$this->assertNoViolation();
115+
}
116+
117+
/**
118+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
119+
* @expectedExceptionMessage The "iban" and "ibanPropertyPath" options of the Iban constraint cannot be used at the same time
120+
*/
121+
public function testThrowsConstraintExceptionIfBothValueAndPropertyPath()
122+
{
123+
new Bic(array(
124+
'iban' => 'value',
125+
'ibanPropertyPath' => 'propertyPath',
126+
));
127+
}
128+
129+
public function testInvalidValuePath()
130+
{
131+
$constraint = new Bic(array('ibanPropertyPath' => 'foo'));
132+
133+
if (method_exists($this, 'expectException')) {
134+
$this->expectException(ConstraintDefinitionException::class);
135+
$this->expectExceptionMessage(sprintf('Invalid property path "foo" provided to "%s" constraint', \get_class($constraint)));
136+
} else {
137+
$this->setExpectedException(ConstraintDefinitionException::class, sprintf('Invalid property path "foo" provided to "%s" constraint', \get_class($constraint)));
138+
}
139+
140+
$object = new BicComparisonTestClass(5);
141+
142+
$this->setObject($object);
143+
144+
$this->validator->validate('UNCRIT2B912', $constraint);
145+
}
146+
39147
/**
40148
* @expectedException \Symfony\Component\Validator\Exception\UnexpectedValueException
41149
*/
@@ -114,3 +222,23 @@ public function getInvalidBics()
114222
);
115223
}
116224
}
225+
226+
class BicComparisonTestClass
227+
{
228+
protected $value;
229+
230+
public function __construct($value)
231+
{
232+
$this->value = $value;
233+
}
234+
235+
public function __toString()
236+
{
237+
return (string) $this->value;
238+
}
239+
240+
public function getValue()
241+
{
242+
return $this->value;
243+
}
244+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.