29
29
*/
30
30
class BicValidator extends ConstraintValidator
31
31
{
32
+ private const BIC_COUNTRY_TO_IBAN_COUNTRY_MAP = array (
33
+ // Reference: https://www.ecbs.org/iban/france-bank-account-number.html
34
+ 'GF ' => 'FR ' , // French Guiana
35
+ 'PF ' => 'FR ' , // French Polynesia
36
+ 'TF ' => 'FR ' , // French Southern Territories
37
+ 'GP ' => 'FR ' , // Guadeloupe
38
+ 'MQ ' => 'FR ' , // Martinique
39
+ 'YT ' => 'FR ' , // Mayotte
40
+ 'NC ' => 'FR ' , // New Caledonia
41
+ 'RE ' => 'FR ' , // Reunion
42
+ 'PM ' => 'FR ' , // Saint Pierre and Miquelon
43
+ 'WF ' => 'FR ' , // Wallis and Futuna Islands
44
+ // Reference: https://www.ecbs.org/iban/united-kingdom-uk-bank-account-number.html
45
+ 'JE ' => 'GB ' , // Jersey
46
+ 'IM ' => 'GB ' , // Isle of Man
47
+ 'GG ' => 'GB ' , // Guernsey
48
+ 'VG ' => 'GB ' , // British Virgin Islands
49
+ );
50
+
32
51
private $ propertyAccessor ;
33
52
34
53
public function __construct (PropertyAccessor $ propertyAccessor = null )
@@ -126,7 +145,7 @@ public function validate($value, Constraint $constraint)
126
145
return ;
127
146
}
128
147
$ ibanCountryCode = substr ($ iban , 0 , 2 );
129
- if (ctype_alpha ($ ibanCountryCode ) && substr ($ canonicalize , 4 , 2 ) !== $ ibanCountryCode ) {
148
+ if (ctype_alpha ($ ibanCountryCode ) && ! $ this -> bicAndIbanCountriesMatch ( substr ($ canonicalize , 4 , 2 ), $ ibanCountryCode) ) {
130
149
$ this ->context ->buildViolation ($ constraint ->ibanMessage )
131
150
->setParameter ('{{ value }} ' , $ this ->formatValue ($ value ))
132
151
->setParameter ('{{ iban }} ' , $ iban )
@@ -146,4 +165,9 @@ private function getPropertyAccessor(): PropertyAccessor
146
165
147
166
return $ this ->propertyAccessor ;
148
167
}
168
+
169
+ private function bicAndIbanCountriesMatch (string $ bicCountryCode , string $ ibanCountryCode ): bool
170
+ {
171
+ return $ ibanCountryCode === $ bicCountryCode || $ ibanCountryCode === (self ::BIC_COUNTRY_TO_IBAN_COUNTRY_MAP [$ bicCountryCode ] ?? null );
172
+ }
149
173
}
0 commit comments