From 59d9d278a42071ae633ad50ab2a1d535709b729d Mon Sep 17 00:00:00 2001 From: Manuel Reinhard Date: Wed, 19 Mar 2014 12:36:45 +0100 Subject: [PATCH] Fix IBAN validator --- .../Component/Validator/Constraints/Iban.php | 1 + .../Validator/Constraints/IbanValidator.php | 12 ++- .../Tests/Constraints/IbanValidatorTest.php | 101 +++++++++++++++--- 3 files changed, 94 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/Iban.php b/src/Symfony/Component/Validator/Constraints/Iban.php index b1621959c91cd..f2f8c634cbe07 100644 --- a/src/Symfony/Component/Validator/Constraints/Iban.php +++ b/src/Symfony/Component/Validator/Constraints/Iban.php @@ -19,4 +19,5 @@ class Iban extends Constraint { public $message = 'This is not a valid International Bank Account Number (IBAN).'; + public $acceptLowercase = false; } diff --git a/src/Symfony/Component/Validator/Constraints/IbanValidator.php b/src/Symfony/Component/Validator/Constraints/IbanValidator.php index 3ec4c6ea7a79a..9cc25d8102995 100644 --- a/src/Symfony/Component/Validator/Constraints/IbanValidator.php +++ b/src/Symfony/Component/Validator/Constraints/IbanValidator.php @@ -30,14 +30,20 @@ public function validate($value, Constraint $constraint) return; } + if ($constraint->acceptLowercase) { + $valueToCheck = strtoupper($value); + } else { + $valueToCheck = $value; + } + // An IBAN without a country code is not an IBAN. - if (0 === preg_match('/[A-Za-z]/', $value)) { + if (0 === preg_match('/[A-Z]/', $valueToCheck)) { $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return; } - $teststring = preg_replace('/\s+/', '', $value); + $teststring = preg_replace('/\s+/', '', $valueToCheck); if (strlen($teststring) < 4) { $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); @@ -50,7 +56,7 @@ public function validate($value, Constraint $constraint) .strval(ord($teststring{1}) - 55) .substr($teststring, 2, 2); - $teststring = preg_replace_callback('/[A-Za-z]/', function ($letter) { + $teststring = preg_replace_callback('/[A-Z]/', function ($letter) { return intval(ord(strtolower($letter[0])) - 87); }, $teststring); diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php index d4add7930c67a..2ac7d6c6fc182 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php @@ -41,16 +41,62 @@ public function testEmptyStringIsValid() } /** - * @dataProvider getValidIbans + * @dataProvider getValidIbansUppercase */ - public function testValidIbans($iban) + public function testValidIbansUppercaseOnly($iban) { $this->context->expects($this->never())->method('addViolation'); $this->validator->validate($iban, new Iban()); } - public function getValidIbans() + /** + * @dataProvider getValidIbansUpperAndLowercase + */ + public function testValidIbansUpperAndLowercase($iban) + { + $this->context->expects($this->never())->method('addViolation'); + + $this->validator->validate($iban, new Iban(array('acceptLowercase' => true))); + } + + /** + * @dataProvider getInvalidIbansWhenUppercaseOnly + */ + public function testInvalidIbansWhenUppercaseOnly($iban) + { + $constraint = new Iban(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $iban, + )); + + $this->validator->validate($iban, $constraint); + } + + /** + * @dataProvider getInvalidIbansWhenUpperAndLowercase + */ + public function testInvalidIbansWhenUpperAndLowercase($iban) + { + $constraint = new Iban(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $iban, + )); + + $this->validator->validate($iban, $constraint); + } + + public function getValidIbansUppercase() { return array( array('CH9300762011623852957'), // Switzerland without spaces @@ -151,25 +197,24 @@ public function getValidIbans() ); } - /** - * @dataProvider getInvalidIbans - */ - public function testInvalidIbans($iban) + public function getValidIbansLowercase() { - $constraint = new Iban(array( - 'message' => 'myMessage' - )); + $validIbansLowercase = array(); - $this->context->expects($this->once()) - ->method('addViolation') - ->with('myMessage', array( - '{{ value }}' => $iban, - )); + foreach ($this->getValidIbansUppercase() as $iban) { + $iban[0] = strtolower($iban[0]); + $validIbansLowercase[] = $iban; + } - $this->validator->validate($iban, $constraint); + return $validIbansLowercase; + } + + public function getValidIbansUpperAndLowercase() + { + return $this->getValidIbansUppercase() + $this->getValidIbansLowercase(); } - public function getInvalidIbans() + public function getInvalidIbansUppercase() { return array( array('CH93 0076 2011 6238 5295'), @@ -184,4 +229,26 @@ public function getInvalidIbans() array('0750447346'), ); } + + public function getInvalidIbansLowercase() + { + $invalidIbansLowercase = array(); + + foreach ($this->getInvalidIbansUppercase() as $iban) { + $iban[0] = strtolower($iban[0]); + $invalidIbansLowercase[] = $iban; + } + + return $invalidIbansLowercase; + } + + public function getInvalidIbansWhenUppercaseOnly() + { + return $this->getInvalidIbansUppercase() + $this->getValidIbansLowercase(); + } + + public function getInvalidIbansWhenUpperAndLowercase() + { + return $this->getInvalidIbansUppercase() + $this->getInvalidIbansLowercase(); + } }