7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
16 * @package Zend_Validate
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
18 * @license http://framework.zend.com/license/new-bsd New BSD License
23 * @see Zend_Validate_Abstract
25 require_once 'Zend/Validate/Abstract.php';
28 * Validates IBAN Numbers (International Bank Account Numbers)
31 * @package Zend_Validate
32 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
33 * @license http://framework.zend.com/license/new-bsd New BSD License
35 class Zend_Validate_Iban
extends Zend_Validate_Abstract
37 const NOTSUPPORTED
= 'ibanNotSupported';
38 const FALSEFORMAT
= 'ibanFalseFormat';
39 const CHECKFAILED
= 'ibanCheckFailed';
42 * Validation failure message template definitions
46 protected $_messageTemplates = array(
47 self
::NOTSUPPORTED
=> "Unknown country within the IBAN '%value%'",
48 self
::FALSEFORMAT
=> "'%value%' has a false IBAN format",
49 self
::CHECKFAILED
=> "'%value%' has failed the IBAN check",
55 * @var string|Zend_Locale|null
60 * IBAN regexes by region
64 protected $_ibanregex = array(
65 'AD' => '/^AD[0-9]{2}[0-9]{8}[A-Z0-9]{12}$/',
66 'AT' => '/^AT[0-9]{2}[0-9]{5}[0-9]{11}$/',
67 'BA' => '/^BA[0-9]{2}[0-9]{6}[0-9]{10}$/',
68 'BE' => '/^BE[0-9]{2}[0-9]{3}[0-9]{9}$/',
69 'BG' => '/^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$/',
70 'CH' => '/^CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}$/',
71 'CS' => '/^CS[0-9]{2}[0-9]{3}[0-9]{15}$/',
72 'CY' => '/^CY[0-9]{2}[0-9]{8}[A-Z0-9]{16}$/',
73 'CZ' => '/^CZ[0-9]{2}[0-9]{4}[0-9]{16}$/',
74 'DE' => '/^DE[0-9]{2}[0-9]{8}[0-9]{10}$/',
75 'DK' => '/^DK[0-9]{2}[0-9]{4}[0-9]{10}$/',
76 'EE' => '/^EE[0-9]{2}[0-9]{4}[0-9]{12}$/',
77 'ES' => '/^ES[0-9]{2}[0-9]{8}[0-9]{12}$/',
78 'FR' => '/^FR[0-9]{2}[0-9]{10}[A-Z0-9]{13}$/',
79 'FI' => '/^FI[0-9]{2}[0-9]{6}[0-9]{8}$/',
80 'GB' => '/^GB[0-9]{2}[A-Z]{4}[0-9]{14}$/',
81 'GI' => '/^GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}$/',
82 'GR' => '/^GR[0-9]{2}[0-9]{7}[A-Z0-9]{16}$/',
83 'HR' => '/^HR[0-9]{2}[0-9]{7}[0-9]{10}$/',
84 'HU' => '/^HU[0-9]{2}[0-9]{7}[0-9]{1}[0-9]{15}[0-9]{1}$/',
85 'IE' => '/^IE[0-9]{2}[A-Z0-9]{4}[0-9]{6}[0-9]{8}$/',
86 'IS' => '/^IS[0-9]{2}[0-9]{4}[0-9]{18}$/',
87 'IT' => '/^IT[0-9]{2}[A-Z]{1}[0-9]{10}[A-Z0-9]{12}$/',
88 'LI' => '/^LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}$/',
89 'LU' => '/^LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}$/',
90 'LT' => '/^LT[0-9]{2}[0-9]{5}[0-9]{11}$/',
91 'LV' => '/^LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}$/',
92 'MK' => '/^MK[0-9]{2}[A-Z]{3}[A-Z0-9]{10}[0-9]{2}$/',
93 'MT' => '/^MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}$/',
94 'NL' => '/^NL[0-9]{2}[A-Z]{4}[0-9]{10}$/',
95 'NO' => '/^NO[0-9]{2}[0-9]{4}[0-9]{7}$/',
96 'PL' => '/^PL[0-9]{2}[0-9]{8}[0-9]{16}$/',
97 'PT' => '/^PT[0-9]{2}[0-9]{8}[0-9]{13}$/',
98 'RO' => '/^RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}$/',
99 'SE' => '/^SE[0-9]{2}[0-9]{3}[0-9]{17}$/',
100 'SI' => '/^SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}$/',
101 'SK' => '/^SK[0-9]{2}[0-9]{4}[0-9]{16}$/',
102 'TN' => '/^TN[0-9]{2}[0-9]{5}[0-9]{15}$/',
103 'TR' => '/^TR[0-9]{2}[0-9]{5}[A-Z0-9]{17}$/'
107 * Sets validator options
109 * @param string|Zend_Config|Zend_Locale $locale OPTIONAL
112 public function __construct($locale = null)
114 if ($locale instanceof Zend_Config
) {
115 $locale = $locale->toArray();
118 if (is_array($locale)) {
119 if (array_key_exists('locale', $locale)) {
120 $locale = $locale['locale'];
126 if (empty($locale)) {
127 require_once 'Zend/Registry.php';
128 if (Zend_Registry
::isRegistered('Zend_Locale')) {
129 $locale = Zend_Registry
::get('Zend_Locale');
133 if ($locale !== null) {
134 $this->setLocale($locale);
139 * Returns the locale option
141 * @return string|Zend_Locale|null
143 public function getLocale()
145 return $this->_locale
;
149 * Sets the locale option
151 * @param string|Zend_Locale $locale
152 * @return Zend_Validate_Date provides a fluent interface
154 public function setLocale($locale = null)
156 if ($locale !== false) {
157 require_once 'Zend/Locale.php';
158 $locale = Zend_Locale
::findLocale($locale);
159 if (strlen($locale) < 4) {
160 require_once 'Zend/Validate/Exception.php';
161 throw new Zend_Validate_Exception('Region must be given for IBAN validation');
165 $this->_locale
= $locale;
170 * Defined by Zend_Validate_Interface
172 * Returns true if $value is a valid IBAN
174 * @param string $value
177 public function isValid($value)
179 $value = strtoupper($value);
180 $this->_setValue($value);
182 if (empty($this->_locale
)) {
183 $region = substr($value, 0, 2);
185 $region = new Zend_Locale($this->_locale
);
186 $region = $region->getRegion();
189 if (!array_key_exists($region, $this->_ibanregex
)) {
190 $this->_setValue($region);
191 $this->_error(self
::NOTSUPPORTED
);
195 if (!preg_match($this->_ibanregex
[$region], $value)) {
196 $this->_error(self
::FALSEFORMAT
);
200 $format = substr($value, 4) . substr($value, 0, 4);
201 $format = str_replace(
202 array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
203 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'),
204 array('10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22',
205 '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'),
208 $temp = intval(substr($format, 0, 1));
209 $len = strlen($format);
210 for ($x = 1; $x < $len; ++
$x) {
212 $temp +
= intval(substr($format, $x, 1));
217 $this->_error(self
::CHECKFAILED
);