File indexing completed on 2024-12-22 05:37:12
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Validate 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * @see Zend_Validate_Abstract 0024 */ 0025 // require_once 'Zend/Validate/Abstract.php'; 0026 0027 /** 0028 * Validates IBAN Numbers (International Bank Account Numbers) 0029 * 0030 * @category Zend 0031 * @package Zend_Validate 0032 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0033 * @license http://framework.zend.com/license/new-bsd New BSD License 0034 */ 0035 class Zend_Validate_Iban extends Zend_Validate_Abstract 0036 { 0037 const NOTSUPPORTED = 'ibanNotSupported'; 0038 const FALSEFORMAT = 'ibanFalseFormat'; 0039 const CHECKFAILED = 'ibanCheckFailed'; 0040 0041 /** 0042 * Validation failure message template definitions 0043 * 0044 * @var array 0045 */ 0046 protected $_messageTemplates = array( 0047 self::NOTSUPPORTED => "Unknown country within the IBAN '%value%'", 0048 self::FALSEFORMAT => "'%value%' has a false IBAN format", 0049 self::CHECKFAILED => "'%value%' has failed the IBAN check", 0050 ); 0051 0052 /** 0053 * Optional locale 0054 * 0055 * @var string|Zend_Locale|null 0056 */ 0057 protected $_locale; 0058 0059 /** 0060 * IBAN regexes by region 0061 * 0062 * @var array 0063 */ 0064 protected $_ibanregex = array( 0065 'AD' => '/^AD[0-9]{2}[0-9]{8}[A-Z0-9]{12}$/', 0066 'AE' => '/^AE[0-9]{2}[0-9]{3}[0-9]{16}$/', 0067 'AL' => '/^AL[0-9]{2}[0-9]{8}[A-Z0-9]{16}$/', 0068 'AT' => '/^AT[0-9]{2}[0-9]{5}[0-9]{11}$/', 0069 'AZ' => '/^AZ[0-9]{2}[0-9]{4}[A-Z0-9]{20}$/', 0070 'BA' => '/^BA[0-9]{2}[0-9]{6}[0-9]{10}$/', 0071 'BE' => '/^BE[0-9]{2}[0-9]{3}[0-9]{9}$/', 0072 'BG' => '/^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$/', 0073 'BH' => '/^BH[0-9]{2}[A-Z]{4}[A-Z0-9]{14}$/', 0074 'BR' => '/^BR[0-9]{2}[0-9]{8}[0-9]{5}[0-9]{10}[A-Z]{1}[A-Z0-9]{1}$/', 0075 'CH' => '/^CH[0-9]{2}[0-9]{5}[A-Z0-9]{12}$/', 0076 'CR' => '/^CR[0-9]{2}[0-9]{3}[0-9]{14}$/', 0077 'CS' => '/^CS[0-9]{2}[0-9]{3}[0-9]{15}$/', 0078 'CY' => '/^CY[0-9]{2}[0-9]{8}[A-Z0-9]{16}$/', 0079 'CZ' => '/^CZ[0-9]{2}[0-9]{4}[0-9]{16}$/', 0080 'DE' => '/^DE[0-9]{2}[0-9]{8}[0-9]{10}$/', 0081 'DK' => '/^DK[0-9]{2}[0-9]{4}[0-9]{10}$/', 0082 'DO' => '/^DO[0-9]{2}[A-Z0-9]{4}[0-9]{20}$/', 0083 'EE' => '/^EE[0-9]{2}[0-9]{4}[0-9]{12}$/', 0084 'ES' => '/^ES[0-9]{2}[0-9]{8}[0-9]{12}$/', 0085 'FR' => '/^FR[0-9]{2}[0-9]{10}[A-Z0-9]{11}[0-9]{2}$/', 0086 'FI' => '/^FI[0-9]{2}[0-9]{6}[0-9]{8}$/', 0087 'FO' => '/^FO[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}$/', 0088 'GB' => '/^GB[0-9]{2}[A-Z]{4}[0-9]{14}$/', 0089 'GE' => '/^GE[0-9]{2}[A-Z]{2}[0-9]{16}$/', 0090 'GI' => '/^GI[0-9]{2}[A-Z]{4}[A-Z0-9]{15}$/', 0091 'GL' => '/^GL[0-9]{2}[0-9]{4}[0-9]{9}[0-9]{1}$/', 0092 'GR' => '/^GR[0-9]{2}[0-9]{7}[A-Z0-9]{16}$/', 0093 'GT' => '/^GT[0-9]{2}[A-Z0-9]{4}[A-Z0-9]{20}$/', 0094 'HR' => '/^HR[0-9]{2}[0-9]{7}[0-9]{10}$/', 0095 'HU' => '/^HU[0-9]{2}[0-9]{7}[0-9]{1}[0-9]{15}[0-9]{1}$/', 0096 'IE' => '/^IE[0-9]{2}[A-Z0-9]{4}[0-9]{6}[0-9]{8}$/', 0097 'IL' => '/^IL[0-9]{2}[0-9]{3}[0-9]{3}[0-9]{13}$/', 0098 'IS' => '/^IS[0-9]{2}[0-9]{4}[0-9]{18}$/', 0099 'IT' => '/^IT[0-9]{2}[A-Z]{1}[0-9]{10}[A-Z0-9]{12}$/', 0100 'KW' => '/^KW[0-9]{2}[A-Z]{4}[0-9]{3}[0-9]{22}$/', 0101 'KZ' => '/^KZ[A-Z]{2}[0-9]{2}[0-9]{3}[A-Z0-9]{13}$/', 0102 'LB' => '/^LB[0-9]{2}[0-9]{4}[A-Z0-9]{20}$/', 0103 'LI' => '/^LI[0-9]{2}[0-9]{5}[A-Z0-9]{12}$/', 0104 'LU' => '/^LU[0-9]{2}[0-9]{3}[A-Z0-9]{13}$/', 0105 'LT' => '/^LT[0-9]{2}[0-9]{5}[0-9]{11}$/', 0106 'LV' => '/^LV[0-9]{2}[A-Z]{4}[A-Z0-9]{13}$/', 0107 'MC' => '/^MC[0-9]{2}[0-9]{5}[0-9]{5}[A-Z0-9]{11}[0-9]{2}$/', 0108 'MD' => '/^MD[0-9]{2}[A-Z0-9]{20}$/', 0109 'ME' => '/^ME[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}$/', 0110 'MK' => '/^MK[0-9]{2}[0-9]{3}[A-Z0-9]{10}[0-9]{2}$/', 0111 'MR' => '/^MR13[0-9]{5}[0-9]{5}[0-9]{11}[0-9]{2}$/', 0112 'MU' => '/^MU[0-9]{2}[A-Z]{4}[0-9]{2}[0-9]{2}[0-9]{12}[0-9]{3}[A-Z]{2}$/', 0113 'MT' => '/^MT[0-9]{2}[A-Z]{4}[0-9]{5}[A-Z0-9]{18}$/', 0114 'NL' => '/^NL[0-9]{2}[A-Z]{4}[0-9]{10}$/', 0115 'NO' => '/^NO[0-9]{2}[0-9]{4}[0-9]{7}$/', 0116 'PK' => '/^PK[0-9]{2}[A-Z]{4}[0-9]{16}$/', 0117 'PL' => '/^PL[0-9]{2}[0-9]{8}[0-9]{16}$/', 0118 'PS' => '/^PS[0-9]{2}[A-Z]{4}[0-9]{21}$/', 0119 'PT' => '/^PT[0-9]{2}[0-9]{8}[0-9]{13}$/', 0120 'RO' => '/^RO[0-9]{2}[A-Z]{4}[A-Z0-9]{16}$/', 0121 'RS' => '/^RS[0-9]{2}[0-9]{3}[0-9]{13}[0-9]{2}$/', 0122 'SA' => '/^SA[0-9]{2}[0-9]{2}[A-Z0-9]{18}$/', 0123 'SE' => '/^SE[0-9]{2}[0-9]{3}[0-9]{17}$/', 0124 'SI' => '/^SI[0-9]{2}[0-9]{5}[0-9]{8}[0-9]{2}$/', 0125 'SK' => '/^SK[0-9]{2}[0-9]{4}[0-9]{16}$/', 0126 'SM' => '/^SM[0-9]{2}[A-Z]{1}[0-9]{5}[0-9]{5}[A-Z0-9]{12}$/', 0127 'TN' => '/^TN[0-9]{2}[0-9]{5}[0-9]{15}$/', 0128 'TR' => '/^TR[0-9]{2}[0-9]{5}[A-Z0-9]{17}$/', 0129 'VG' => '/^VG[0-9]{2}[A-Z]{4}[0-9]{16}$/' 0130 ); 0131 0132 /** 0133 * Sets validator options 0134 * 0135 * @param string|Zend_Config|Zend_Locale $locale OPTIONAL 0136 */ 0137 public function __construct($locale = null) 0138 { 0139 if ($locale instanceof Zend_Config) { 0140 $locale = $locale->toArray(); 0141 } 0142 0143 if (is_array($locale)) { 0144 if (array_key_exists('locale', $locale)) { 0145 $locale = $locale['locale']; 0146 } else { 0147 $locale = null; 0148 } 0149 } 0150 0151 if (empty($locale)) { 0152 // require_once 'Zend/Registry.php'; 0153 if (Zend_Registry::isRegistered('Zend_Locale')) { 0154 $locale = Zend_Registry::get('Zend_Locale'); 0155 } 0156 } 0157 0158 if ($locale !== null) { 0159 $this->setLocale($locale); 0160 } 0161 } 0162 0163 /** 0164 * Returns the locale option 0165 * 0166 * @return string|Zend_Locale|null 0167 */ 0168 public function getLocale() 0169 { 0170 return $this->_locale; 0171 } 0172 0173 /** 0174 * Sets the locale option 0175 * 0176 * @param string|Zend_Locale $locale 0177 * @throws Zend_Locale_Exception 0178 * @throws Zend_Validate_Exception 0179 * @return Zend_Validate_Date provides a fluent interface 0180 */ 0181 public function setLocale($locale = null) 0182 { 0183 if ($locale !== false) { 0184 // require_once 'Zend/Locale.php'; 0185 $locale = Zend_Locale::findLocale($locale); 0186 if (strlen($locale) < 4) { 0187 // require_once 'Zend/Validate/Exception.php'; 0188 throw new Zend_Validate_Exception('Region must be given for IBAN validation'); 0189 } 0190 } 0191 0192 $this->_locale = $locale; 0193 return $this; 0194 } 0195 0196 /** 0197 * Defined by Zend_Validate_Interface 0198 * 0199 * Returns true if $value is a valid IBAN 0200 * 0201 * @param string $value 0202 * @return boolean 0203 */ 0204 public function isValid($value) 0205 { 0206 $value = strtoupper($value); 0207 $this->_setValue($value); 0208 0209 if (empty($this->_locale)) { 0210 $region = substr($value, 0, 2); 0211 } else { 0212 $region = new Zend_Locale($this->_locale); 0213 $region = $region->getRegion(); 0214 } 0215 0216 if (!array_key_exists($region, $this->_ibanregex)) { 0217 $this->_setValue($region); 0218 $this->_error(self::NOTSUPPORTED); 0219 return false; 0220 } 0221 0222 if (!preg_match($this->_ibanregex[$region], $value)) { 0223 $this->_error(self::FALSEFORMAT); 0224 return false; 0225 } 0226 0227 $format = substr($value, 4) . substr($value, 0, 4); 0228 $format = str_replace( 0229 array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 0230 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'), 0231 array('10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', 0232 '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'), 0233 $format); 0234 0235 $temp = intval(substr($format, 0, 1)); 0236 $len = strlen($format); 0237 for ($x = 1; $x < $len; ++$x) { 0238 $temp *= 10; 0239 $temp += intval(substr($format, $x, 1)); 0240 $temp %= 97; 0241 } 0242 0243 if ($temp != 1) { 0244 $this->_error(self::CHECKFAILED); 0245 return false; 0246 } 0247 0248 return true; 0249 } 0250 }