Passed
Pull Request — 1.x (#44)
by Milwad
03:20
created

ValidIban::message()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Milwad\LaravelValidate\Rules;
4
5
use Illuminate\Contracts\Validation\Rule;
6
7
class ValidIban implements Rule
8
{
9
    /**
10
     * Character map
11
     *
12
     * @var array|int[]
13
     */
14
    private array $characterMap = [
15
        'A' => 10,
16
        'B' => 11,
17
        'C' => 12,
18
        'D' => 13,
19
        'E' => 14,
20
        'F' => 15,
21
        'G' => 16,
22
        'H' => 17,
23
        'I' => 18,
24
        'J' => 19,
25
        'K' => 20,
26
        'L' => 21,
27
        'M' => 22,
28
        'N' => 23,
29
        'O' => 24,
30
        'P' => 25,
31
        'Q' => 26,
32
        'R' => 27,
33
        'S' => 28,
34
        'T' => 29,
35
        'U' => 30,
36
        'V' => 31,
37
        'W' => 32,
38
        'X' => 33,
39
        'Y' => 34,
40
        'Z' => 35,
41
    ];
42
43
    /**
44
     * Get country code with length.
45
     *
46
     * @var array|int[]
47
     */
48
    private array $ibanLengthByCountry = [
49
        'AD' => 24, // Andorra
50
        'AE' => 23, // United Arab Emirates
51
        'AL' => 28, // Albania
52
        'AO' => 25, // Angola
53
        'AT' => 20, // Austria
54
        'AZ' => 28, // Azerbaijan
55
        'BA' => 20, // Bosnia and Herzegovina
56
        'BE' => 16, // Belgium
57
        'BF' => 28, // Burkina Faso
58
        'BG' => 22, // Bulgaria
59
        'BH' => 22, // Bahrain
60
        'BI' => 28, // Burundi
61
        'BJ' => 28, // Benin
62
        'BR' => 29, // Brazil
63
        'BY' => 28, // Belarus
64
        'CF' => 27, // Central African Republic
65
        'CG' => 27, // Congo
66
        'CH' => 21, // Switzerland
67
        'CI' => 28, // Ivory Coast
68
        'CM' => 27, // Cameroon
69
        'CR' => 22, // Costa Rica
70
        'CV' => 25, // Cape Verde
71
        'CY' => 28, // Cyprus
72
        'CZ' => 24, // Czech Republic
73
        'DE' => 22, // Germany
74
        'DJ' => 27, // Djibouti
75
        'DK' => 18, // Denmark
76
        'DO' => 28, // Dominican Republic
77
        'DZ' => 26, // Algeria
78
        'EE' => 20, // Estonia
79
        'EG' => 29, // Egypt
80
        'ES' => 24, // Spain
81
        'FI' => 18, // Finland
82
        'FO' => 18, // Faroe Islands
83
        'FR' => 27, // France
84
        'GA' => 27, // Gabon
85
        'GB' => 22, // United Kingdom
86
        'GE' => 22, // Georgia
87
        'GI' => 23, // Gibraltar
88
        'GL' => 18, // Greenland
89
        'GQ' => 27, // Equatorial Guinea
90
        'GR' => 27, // Greece
91
        'GT' => 28, // Guatemala
92
        'GW' => 25, // Guinea-Bissau
93
        'HN' => 28, // Honduras
94
        'HR' => 21, // Croatia
95
        'HU' => 28, // Hungary
96
        'IE' => 22, // Ireland
97
        'IL' => 23, // Israel
98
        'IQ' => 23, // Iraq
99
        'IR' => 26, // Iran
100
        'IS' => 26, // Iceland
101
        'IT' => 27, // Italy
102
        'JO' => 30, // Jordan
103
        'KM' => 27, // Comoros
104
        'KW' => 30, // Kuwait
105
        'KZ' => 20, // Kazakhstan
106
        'LB' => 28, // Lebanon
107
        'LC' => 32, // Saint Lucia
108
        'LI' => 21, // Liechtenstein
109
        'LT' => 20, // Lithuania
110
        'LU' => 20, // Luxembourg
111
        'LV' => 21, // Latvia
112
        'LY' => 25, // Libya
113
        'MA' => 28, // Morocco
114
        'MC' => 27, // Monaco
115
        'MD' => 24, // Moldova
116
        'ME' => 22, // Montenegro
117
        'MG' => 27, // Madagascar
118
        'MK' => 19, // North Macedonia
119
        'ML' => 28, // Mali
120
        'MN' => 20, // Mongolia
121
        'MR' => 27, // Mauritania
122
        'MT' => 31, // Malta
123
        'MU' => 30, // Mauritius
124
        'MZ' => 25, // Mozambique
125
        'NE' => 28, // Niger
126
        'NI' => 32, // Nicaragua
127
        'NL' => 18, // Netherlands
128
        'NO' => 15, // Norway
129
        'PK' => 24, // Pakistan
130
        'PL' => 28, // Poland
131
        'PS' => 29, // Palestine
132
        'PT' => 25, // Portugal
133
        'QA' => 29, // Qatar
134
        'RO' => 24, // Romania
135
        'RS' => 22, // Serbia
136
        'RU' => 33, // Russia
137
        'SA' => 24, // Saudi Arabia
138
        'SC' => 31, // Seychelles
139
        'SD' => 18, // Sudan
140
        'SE' => 24, // Sweden
141
        'SI' => 19, // Slovenia
142
        'SK' => 24, // Slovakia
143
        'SM' => 27, // San Marino
144
        'SN' => 28, // Senegal
145
        'SO' => 23, // Somalia
146
        'ST' => 25, // Sao Tome and Principe
147
        'SV' => 28, // El Salvador
148
        'TD' => 27, // Chad
149
        'TG' => 28, // Togo
150
        'TL' => 23, // Timor-Leste
151
        'TN' => 24, // Tunisia
152
        'TR' => 26, // Turkey
153
        'UA' => 29, // Ukraine
154
        'VA' => 22, // Holy See (the)
155
        'VG' => 24, // Virgin Islands, British
156
        'XK' => 20, // Kosovo
157
    ];
158
159
    /**
160
     * Country code from outside.
161
     *
162
     * @var string|null
163
     */
164
    private string|null $country;
165
166
    public function __construct(string|null $country = null) // TODO: Add $country into the progress
167
    {
168
        $this->country = $country;
169
    }
170
171
    /**
172
     * Check IBAN.
173
     *
174
     * @param  string $attribute
175
     * @param  mixed $value
176
     * @return bool
177
     */
178
    public function passes($attribute, $value)
179
    {
180
        if (!$this->isIbanValid($value)) {
181
            return false;
182
        }
183
184
        /*
185
         * Connect Iban title with value (code) ex: 8330001234567NO .
186
         */
187
        $parsedIban = substr($value, 4) . substr($value, 0, 4);
188
189
        /*
190
         * Replace iban value with character map.
191
         */
192
        $parsedIban = strtr($parsedIban, $this->characterMap);
193
194
        return bcmod($parsedIban, '97') === '1';
195
    }
196
197
    /**
198
     * Get the validation error message.
199
     *
200
     * @return string
201
     */
202
    public function message()
203
    {
204
        return __('validate.iban');
205
    }
206
207
    /**
208
     * Check iban is valid.
209
     *
210
     * @param  string $iban
211
     * @return bool
212
     */
213
    private function isIbanValid(string $iban)
214
    {
215
        $countryCode = substr($iban, 0, 2); // Get character of value
216
217
        return ! empty($iban)
218
            || function_exists('bcmod') // Check `bcmod` is exists
219
            || ctype_alpha(substr($iban, 0, 2)) //
220
            || strlen($iban) !== $this->ibanLengthByCountry[$countryCode];
221
    }
222
}
223