Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7dc5554

Browse files
committed
Fix #28166
1 parent 5b08019 commit 7dc5554

File tree

4 files changed

+201
-0
lines changed

4 files changed

+201
-0
lines changed

src/Symfony/Component/Validator/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* made `ValidatorBuilder` final
1111
* marked `format` the default option in `DateTime` constraint
1212
* deprecated validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`.
13+
* validating a BIC based on a given IBAN
1314

1415
4.1.0
1516
-----

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
namespace Symfony\Component\Validator\Constraints;
1313

14+
use Symfony\Component\PropertyAccess\PropertyAccess;
1415
use Symfony\Component\Validator\Constraint;
16+
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
1517

1618
/**
1719
* @Annotation
@@ -26,6 +28,7 @@ class Bic extends Constraint
2628
const INVALID_BANK_CODE_ERROR = '00559357-6170-4f29-aebd-d19330aa19cf';
2729
const INVALID_COUNTRY_CODE_ERROR = '1ce76f8d-3c1f-451c-9e62-fe9c3ed486ae';
2830
const INVALID_CASE_ERROR = '11884038-3312-4ae5-9d04-699f782130c7';
31+
const INVALID_IBAN_COUNTRY_CODE_ERROR = '29a2c3bb-587b-4996-b6f5-53081364cea5';
2932

3033
protected static $errorNames = array(
3134
self::INVALID_LENGTH_ERROR => 'INVALID_LENGTH_ERROR',
@@ -36,4 +39,23 @@ class Bic extends Constraint
3639
);
3740

3841
public $message = 'This is not a valid Business Identifier Code (BIC).';
42+
43+
public $ibanMessage = 'This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.';
44+
45+
public $iban;
46+
47+
public $ibanPropertyPath;
48+
49+
public function __construct($options = null)
50+
{
51+
if (isset($options['iban']) && isset($options['ibanPropertyPath'])) {
52+
throw new ConstraintDefinitionException(sprintf('The "%s" constraint requires only one of the "iban" or "ibanPropertyPath" options to be set, not both.', \get_class($this)));
53+
}
54+
55+
if (isset($options['propertyPath']) && !class_exists(PropertyAccess::class)) {
56+
throw new ConstraintDefinitionException(sprintf('The "%s" constraint requires the Symfony PropertyAccess component to use the "ibanPropertyPath" option.', \get_class($this)));
57+
}
58+
59+
parent::__construct($options);
60+
}
3961
}

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@
1111

1212
namespace Symfony\Component\Validator\Constraints;
1313

14+
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
15+
use Symfony\Component\PropertyAccess\PropertyAccess;
16+
use Symfony\Component\PropertyAccess\PropertyAccessor;
1417
use Symfony\Component\Validator\Constraint;
1518
use Symfony\Component\Validator\ConstraintValidator;
19+
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
1620

1721
/**
1822
* @author Michael Hirschler <[email protected]>
@@ -21,6 +25,13 @@
2125
*/
2226
class BicValidator extends ConstraintValidator
2327
{
28+
private $propertyAccessor;
29+
30+
public function __construct(PropertyAccessor $propertyAccessor = null)
31+
{
32+
$this->propertyAccessor = $propertyAccessor;
33+
}
34+
2435
/**
2536
* {@inheritdoc}
2637
*/
@@ -81,5 +92,44 @@ public function validate($value, Constraint $constraint)
8192

8293
return;
8394
}
95+
96+
// check against an IBAN
97+
if($path = $constraint->ibanPropertyPath){
98+
if (null === $object = $this->context->getObject()) {
99+
return;
100+
}
101+
102+
try {
103+
$iban = $this->getPropertyAccessor()->getValue($object, $path);
104+
} catch (NoSuchPropertyException $e) {
105+
throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: %s', $path, \get_class($constraint), $e->getMessage()), 0, $e);
106+
}
107+
}
108+
else{
109+
$iban = $constraint->iban;
110+
}
111+
if($iban) {
112+
$ibanCountryCode = substr($iban, 0, 2);
113+
if(ctype_alpha($ibanCountryCode)){
114+
if(substr($canonicalize, 4, 2) !== $ibanCountryCode) {
115+
$this->context->buildViolation($constraint->ibanMessage)
116+
->setParameter('{{ value }}', $this->formatValue($value))
117+
->setParameter('{{ iban }}', $iban)
118+
->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
119+
->addViolation();
120+
121+
return;
122+
}
123+
}
124+
}
125+
}
126+
127+
private function getPropertyAccessor()
128+
{
129+
if (null === $this->propertyAccessor) {
130+
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
131+
}
132+
133+
return $this->propertyAccessor;
84134
}
85135
}

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

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,29 @@
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

19+
class BicComparisonTest_Class
20+
{
21+
protected $value;
22+
23+
public function __construct($value)
24+
{
25+
$this->value = $value;
26+
}
27+
28+
public function __toString()
29+
{
30+
return (string) $this->value;
31+
}
32+
33+
public function getValue()
34+
{
35+
return $this->value;
36+
}
37+
}
38+
1839
class BicValidatorTest extends ConstraintValidatorTestCase
1940
{
2041
protected function createValidator()
@@ -36,6 +57,113 @@ public function testEmptyStringIsValid()
3657
$this->assertNoViolation();
3758
}
3859

60+
public function testValidComparisonToPropertyPath()
61+
{
62+
$constraint = new Bic(array('ibanPropertyPath' => 'value'));
63+
64+
$object = new BicComparisonTest_Class('FR14 2004 1010 0505 0001 3M02 606');
65+
66+
$this->setObject($object);
67+
68+
$this->validator->validate('SOGEFRPP', $constraint);
69+
70+
$this->assertNoViolation();
71+
}
72+
73+
public function testValidComparisonToPropertyPathOnArray()
74+
{
75+
$constraint = new Bic(array('ibanPropertyPath' => '[root][value]'));
76+
77+
$this->setObject(array('root' => array('value' => 'FR14 2004 1010 0505 0001 3M02 606')));
78+
79+
$this->validator->validate('SOGEFRPP', $constraint);
80+
81+
$this->assertNoViolation();
82+
}
83+
84+
public function testInvalidComparisonToPropertyPath()
85+
{
86+
$constraint = new Bic(array('ibanPropertyPath' => 'value'));
87+
$constraint->ibanMessage = 'Constraint Message';
88+
89+
$object = new BicComparisonTest_Class('FR14 2004 1010 0505 0001 3M02 606');
90+
91+
$this->setObject($object);
92+
93+
$this->validator->validate('UNCRIT2B912', $constraint);
94+
95+
$this->buildViolation('Constraint Message')
96+
->setParameter('{{ value }}', '"UNCRIT2B912"')
97+
->setParameter('{{ iban }}', 'FR14 2004 1010 0505 0001 3M02 606')
98+
->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
99+
->assertRaised();
100+
}
101+
102+
public function testValidComparisonToValue()
103+
{
104+
$constraint = new Bic(array('iban' => 'FR14 2004 1010 0505 0001 3M02 606'));
105+
$constraint->ibanMessage = 'Constraint Message';
106+
107+
$this->validator->validate('SOGEFRPP', $constraint);
108+
109+
$this->assertNoViolation();
110+
}
111+
112+
public function testInvalidComparisonToValue()
113+
{
114+
$constraint = new Bic(array('iban' => 'FR14 2004 1010 0505 0001 3M02 606'));
115+
$constraint->ibanMessage = 'Constraint Message';
116+
117+
$this->validator->validate('UNCRIT2B912', $constraint);
118+
119+
$this->buildViolation('Constraint Message')
120+
->setParameter('{{ value }}', '"UNCRIT2B912"')
121+
->setParameter('{{ iban }}', 'FR14 2004 1010 0505 0001 3M02 606')
122+
->setCode(Bic::INVALID_IBAN_COUNTRY_CODE_ERROR)
123+
->assertRaised();
124+
}
125+
126+
public function testNoViolationOnNullObjectWithPropertyPath()
127+
{
128+
$constraint = new Bic(array('ibanPropertyPath' => 'propertyPath'));
129+
130+
$this->setObject(null);
131+
132+
$this->validator->validate('UNCRIT2B912', $constraint);
133+
134+
$this->assertNoViolation();
135+
}
136+
137+
/**
138+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
139+
* @expectedExceptionMessage requires only one of the "iban" or "ibanPropertyPath" options to be set, not both.
140+
*/
141+
public function testThrowsConstraintExceptionIfBothValueAndPropertyPath()
142+
{
143+
new Bic(array(
144+
'iban' => 'value',
145+
'ibanPropertyPath' => 'propertyPath',
146+
));
147+
}
148+
149+
public function testInvalidValuePath()
150+
{
151+
$constraint = new Bic(array('ibanPropertyPath' => 'foo'));
152+
153+
if (method_exists($this, 'expectException')) {
154+
$this->expectException(ConstraintDefinitionException::class);
155+
$this->expectExceptionMessage(sprintf('Invalid property path "foo" provided to "%s" constraint', \get_class($constraint)));
156+
} else {
157+
$this->setExpectedException(ConstraintDefinitionException::class, sprintf('Invalid property path "foo" provided to "%s" constraint', \get_class($constraint)));
158+
}
159+
160+
$object = new BicComparisonTest_Class(5);
161+
162+
$this->setObject($object);
163+
164+
$this->validator->validate('UNCRIT2B912', $constraint);
165+
}
166+
39167
/**
40168
* @dataProvider getValidBics
41169
*/

0 commit comments

Comments
 (0)