openstamanager/modules/banche/src/IBAN.php

528 lines
14 KiB
PHP
Raw Normal View History

<?php
namespace Modules\Banche;
use UnexpectedValueException;
/**
* Format:
* b = National bank code (Codice ABI)
* s = Bank/branch code (sort code, or CAB Codice d'Avviamento Bancario)
* c = Account number
* d = Account type
* i = National identification number
* k = IBAN check digits
* x = National check digits (CIN).
*/
class IBAN
{
public static $countries = [
'AL' => [
'length' => 28,
'pattern' => '8n 16c',
'structure' => 'ALkk bbbs sssx cccc cccc cccc cccc',
],
'AD' => [
'length' => 24,
'pattern' => '8n 12c',
'structure' => 'ADkk bbbb ssss cccc cccc cccc',
],
'AT' => [
'length' => 20,
'pattern' => '16n',
'structure' => 'ATkk bbbb bccc cccc cccc',
],
'AZ' => [
'length' => 28,
'pattern' => '4c 20n',
'structure' => 'AZkk bbbb cccc cccc cccc cccc cccc',
],
'BH' => [
'length' => 22,
'pattern' => '4a 14c',
'structure' => 'BHkk bbbb cccc cccc cccc cc',
],
'BE' => [
'length' => 16,
'pattern' => '12n',
'structure' => 'BEkk bbbc cccc ccxx',
],
'BA' => [
'length' => 20,
'pattern' => '16n',
'structure' => 'BA39 bbbs sscc cccc ccxx',
],
'BR' => [
'length' => 29,
'pattern' => '23n 1a 1c',
'structure' => 'BR39 bbbb bbbb ssss sccc cccc cccc c',
],
'BG' => [
'length' => 22,
'pattern' => '4a 6n 8c',
'structure' => 'BGkk bbbb ssss ddcc cccc cc',
],
'CR' => [
'length' => 21,
'pattern' => '17n',
'structure' => 'CRkk bbbc cccc cccc cccc c',
],
'HR' => [
'length' => 21,
'pattern' => '17n',
'structure' => 'HRkk bbbb bbbc cccc cccc c',
],
'CY' => [
'length' => 28,
'pattern' => '8n 16c',
'structure' => 'CYkk bbbs ssss cccc cccc cccc cccc',
],
'CZ' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'CZkk bbbb ssss sscc cccc cccc',
],
'DK' => [
'length' => 18,
'pattern' => '14n',
'structure' => 'DKkk bbbb cccc cccc cc',
],
'DO' => [
'length' => 28,
'pattern' => '4a 20n',
'structure' => 'DOkk bbbb cccc cccc cccc cccc cccc',
],
'EE' => [
'length' => 20,
'pattern' => '16n',
'structure' => 'EEkk bbss cccc cccc cccx',
],
'FO' => [
'length' => 18,
'pattern' => '14n',
'structure' => 'FOkk bbbb cccc cccc cx',
],
'FI' => [
'length' => 18,
'pattern' => '14n',
'structure' => 'FIkk bbbb bbcc cccc cx',
],
'FR' => [
'length' => 27,
'pattern' => '10n 11c 2n',
'structure' => 'FRkk bbbb bggg ggcc cccc cccc cxx',
],
'GE' => [
'length' => 22,
'pattern' => '2c 16n',
'structure' => 'GEkk bbcc cccc cccc cccc cc',
],
'DE' => [
'length' => 22,
'pattern' => '18n',
'structure' => 'DEkk bbbb bbbb cccc cccc cc',
],
'GI' => [
'length' => 23,
'pattern' => '4a 15c',
'structure' => 'GIkk bbbb cccc cccc cccc ccc',
],
'GR' => [
'length' => 27,
'pattern' => '7n 16c',
'structure' => 'GRkk bbbs sssc cccc cccc cccc ccc',
],
'GL' => [
'length' => 18,
'pattern' => '14n',
'structure' => 'GLkk bbbb cccc cccc cc',
],
'GT' => [
'length' => 28,
'pattern' => '4c 20c',
'structure' => 'GTkk bbbb cccc cccc cccc cccc cccc',
],
'HU' => [
'length' => 28,
'pattern' => '24n',
'structure' => 'HUkk bbbs sssk cccc cccc cccc cccx',
],
'IS' => [
'length' => 26,
'pattern' => '22n',
'structure' => 'ISkk bbbb sscc cccc iiii iiii ii',
],
'IE' => [
'length' => 22,
'pattern' => '4c 14n',
'structure' => 'IEkk aaaa bbbb bbcc cccc cc',
],
'IL' => [
'length' => 23,
'pattern' => '19n',
'structure' => 'ILkk bbbn nncc cccc cccc ccc',
],
'IT' => [
'length' => 27,
'pattern' => '1a 10n 12c',
'structure' => 'ITkk xbbb bbss sssc cccc cccc ccc',
],
'KZ' => [
'length' => 20,
'pattern' => '3n 13c',
'structure' => 'KZkk bbbc cccc cccc cccc',
],
'KW' => [
'length' => 30,
'pattern' => '4a 22c',
'structure' => 'KWkk bbbb cccc cccc cccc cccc cccc cc',
],
'LV' => [
'length' => 21,
'pattern' => '4a 13c',
'structure' => 'LVkk bbbb cccc cccc cccc c',
],
'LB' => [
'length' => 28,
'pattern' => '4n 20c',
'structure' => 'LBkk bbbb cccc cccc cccc cccc cccc',
],
'LI' => [
'length' => 21,
'pattern' => '5n 12c',
'structure' => 'LIkk bbbb bccc cccc cccc c',
],
'LT' => [
'length' => 20,
'pattern' => '16n',
'structure' => 'LTkk bbbb bccc cccc cccc',
],
'LU' => [
'length' => 20,
'pattern' => '3n 13c',
'structure' => 'LUkk bbbc cccc cccc cccc',
],
'MK' => [
'length' => 19,
'pattern' => '3n 10c 2n',
'structure' => 'MK07 bbbc cccc cccc cxx',
],
'MT' => [
'length' => 31,
'pattern' => '4a 5n 18c',
'structure' => 'MTkk bbbb ssss sccc cccc cccc cccc ccc',
],
'MR' => [
'length' => 27,
'pattern' => '23n',
'structure' => 'MRkk bbbb bsss sscc cccc cccc cxx',
],
'MU' => [
'length' => 30,
'pattern' => '4a 19n 3a',
'structure' => 'MUkk bbbb bbss cccc cccc cccc cccc cc',
],
'MC' => [
'length' => 27,
'pattern' => '10n 11c 2n',
'structure' => 'MCkk bbbb bsss sscc cccc cccc cxx',
],
'MD' => [
'length' => 24,
'pattern' => '2c 18n',
'structure' => 'MDkk bbcc cccc cccc cccc cccc',
],
'ME' => [
'length' => 22,
'pattern' => '18n',
'structure' => 'ME25 bbbc cccc cccc cccc xx',
],
'NL' => [
'length' => 18,
'pattern' => '4a 10n',
'structure' => 'NLkk bbbb cccc cccc cc',
],
'NO' => [
'length' => 15,
'pattern' => '11n',
'structure' => 'NOkk bbbb cccc ccx',
],
'PK' => [
'length' => 24,
'pattern' => '4c 16n',
'structure' => 'PKkk bbbb cccc cccc cccc cccc',
],
'PS' => [
'length' => 29,
'pattern' => '4c 21n',
'structure' => 'PSkk bbbb zzzz zzzz zccc cccc cccc c',
],
'PL' => [
'length' => 28,
'pattern' => '24n',
'structure' => 'PLkk bbbs sssx cccc cccc cccc cccc',
],
'PT' => [
'length' => 25,
'pattern' => '21n',
'structure' => 'PT50 bbbb ssss cccc cccc cccx x',
],
'RO' => [
'length' => 24,
'pattern' => '4a 16c',
'structure' => 'ROkk bbbb cccc cccc cccc cccc',
],
'SM' => [
'length' => 27,
'pattern' => '1a 10n 12c',
'structure' => 'SMkk xbbb bbss sssc cccc cccc ccc',
],
'SA' => [
'length' => 24,
'pattern' => '2n 18c',
'structure' => 'SAkk bbcc cccc cccc cccc cccc',
],
'RS' => [
'length' => 22,
'pattern' => '18n',
'structure' => 'RSkk bbbc cccc cccc cccc aa',
],
'SK' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'SKkk bbbb ssss sscc cccc cccc',
],
'SI' => [
'length' => 19,
'pattern' => '15n',
'structure' => 'SI56 bbss sccc cccc cxx',
],
'ES' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'ESkk bbbb ssss xxcc cccc cccc',
],
'SE' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'SEkk bbbc cccc cccc cccc cccc',
],
'CH' => [
'length' => 21,
'pattern' => '5n 12c',
'structure' => 'CHkk bbbb bccc cccc cccc c',
],
'TN' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'TNkk bbss sccc cccc cccc cccc',
],
'TR' => [
'length' => 26,
'pattern' => '5n 17c',
'structure' => 'TRkk bbbb b0cc cccc cccc cccc cc',
],
'AE' => [
'length' => 23,
'pattern' => '3n 16n',
'structure' => 'AEkk bbbc cccc cccc cccc ccc',
],
'GB' => [
'length' => 22,
'pattern' => '4a 14n',
'structure' => 'GBkk bbbb ssss sscc cccc cc',
],
'VG' => [
'length' => 24,
'pattern' => '4c 16n',
'structure' => 'VGkk bbbb cccc cccc cccc cccc',
],
];
protected static $parsers = [
'b' => 'bank_code',
's' => 'branch_code',
'c' => 'account_number',
'd' => 'account_type',
'i' => 'id',
'k' => 'check_digits',
'x' => 'national_check_digits',
];
/**
* @var string
*/
protected $iban;
/**
* @var string
*/
protected $nation;
/**
* @var string
*/
protected $bank_code;
/**
* @var string
*/
protected $branch_code;
/**
* @var string
*/
protected $account_number;
/**
* @var string
*/
protected $account_type;
/**
* @var string
*/
protected $id;
/**
* @var string
*/
protected $check_digits;
/**
* @var string
*/
protected $national_check_digits;
public function __construct($iban)
{
$iban = str_replace(' ', '', $iban);
$this->iban = $iban;
$this->nation = $nation = substr($iban, 0, 2);
$info = self::$countries[$nation];
$structure = $info['structure'];
$structure = str_replace(' ', '', $structure);
$regex = $nation;
$keys = array_keys(self::$parsers);
$length = strlen($this->iban);
$current = strlen($nation);
while ($current <= $length) {
$char = $structure[$current];
if (in_array($char, $keys)) {
$count = substr_count($structure, $char);
$regex .= '(?<'.self::$parsers[$char].'>[A-Z0-9]{'.$count.'})';
$current += $count;
} else {
$regex .= $char;
++$current;
}
}
preg_match_all('/^'.$regex.'/', $iban, $matches);
$matches = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
foreach ($matches as $key => $value) {
if (empty($value[0])) {
throw new UnexpectedValueException('Invalid '.$key.' for format '.$regex);
}
$this->{$key} = $value[0];
}
}
public static function generate($contents = [])
{
$nation = $contents['nation'];
$info = self::$countries[$nation];
$structure = $info['structure'];
$structure = str_replace(' ', '', $structure);
$keys = array_keys(self::$parsers);
$length = strlen($structure);
$current = strlen($nation);
$result = $nation;
while ($current <= $length) {
$char = $structure[$current];
if (in_array($char, $keys)) {
$count = substr_count($structure, $char);
$result .= str_pad($contents[self::$parsers[$char]], $count, STR_PAD_LEFT);
$current += $count;
} else {
$result .= $char;
++$current;
}
}
return new self($result);
}
/**
* @return string
*/
public function getIban()
{
return $this->iban;
}
/**
* @return string
*/
public function getNation()
{
return $this->nation;
}
/**
* @return string
*/
public function getBankCode()
{
return $this->bank_code;
}
/**
* @return string
*/
public function getBranchCode()
{
return $this->branch_code;
}
/**
* @return string
*/
public function getAccountNumber()
{
return $this->account_number;
}
/**
* @return string
*/
public function getAccountType()
{
return $this->account_type;
}
/**
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getCheckDigits()
{
return $this->check_digits;
}
/**
* @return string
*/
public function getNationalCheckDigits()
{
return $this->national_check_digits;
}
}