dimtrovich /
validation
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * This file is part of Dimtrovich/Validation. |
||
| 5 | * |
||
| 6 | * (c) 2023 Dimitri Sitchet Tomkeu <[email protected]> |
||
| 7 | * |
||
| 8 | * For the full copyright and license information, please view |
||
| 9 | * the LICENSE file that was distributed with this source code. |
||
| 10 | */ |
||
| 11 | |||
| 12 | namespace Dimtrovich\Validation\Traits; |
||
| 13 | |||
| 14 | /** |
||
| 15 | * @credit <a href="https://github.com/milwad-dev/laravel-validate">milwad/laravel-validate - Milwad\LaravelValidate\Traits\IbanTrait</a> |
||
| 16 | */ |
||
| 17 | trait IbanTrait |
||
| 18 | { |
||
| 19 | /** |
||
| 20 | * Set value of $countries property. |
||
| 21 | * |
||
| 22 | * @return void |
||
| 23 | */ |
||
| 24 | private function setCountries(?array $countries) |
||
| 25 | { |
||
| 26 | if (empty($countries)) { |
||
| 27 | 2 | $this->countries = []; |
|
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||
| 28 | |||
| 29 | 2 | return; |
|
| 30 | } |
||
| 31 | |||
| 32 | if (is_array($countries[0])) { |
||
| 33 | $countries = $countries[0]; |
||
| 34 | } |
||
| 35 | |||
| 36 | foreach ($countries as $country) { |
||
| 37 | $this->countries[] = $country; |
||
| 38 | } |
||
| 39 | } |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Check IBAN is valid. |
||
| 43 | */ |
||
| 44 | private function isIbanValid(string $iban): bool |
||
| 45 | { |
||
| 46 | if (! $this->checkIbanFormat($iban)) { |
||
| 47 | 2 | return false; |
|
| 48 | } |
||
| 49 | |||
| 50 | // Connect Iban title with value (code) ex: 8330001234567NO . |
||
| 51 | 2 | $parsedIban = substr($iban, 4) . substr($iban, 0, 4); |
|
| 52 | |||
| 53 | // Replace iban value with character map. |
||
| 54 | 2 | $parsedIban = strtr($parsedIban, $this->characterMap); |
|
| 55 | |||
| 56 | 2 | return bcmod($parsedIban, '97') === '1'; |
|
| 57 | } |
||
| 58 | |||
| 59 | /** |
||
| 60 | * Check IBAN format is valid. |
||
| 61 | */ |
||
| 62 | private function checkIbanFormat(string $iban): bool |
||
| 63 | { |
||
| 64 | if (empty($iban)) { |
||
| 65 | return false; |
||
| 66 | } |
||
| 67 | |||
| 68 | 2 | $ibanCountryCode = $this->getIbanCountryCode($iban); |
|
| 69 | |||
| 70 | return ! (empty($this->checkIfBcmodIsAvailable()) |
||
| 71 | || ! $this->twoFirstCharactersValid($ibanCountryCode) |
||
| 72 | || ! $this->isCountriesValid($ibanCountryCode) |
||
| 73 | 2 | || ! $this->isIbanLengthValid($iban, $ibanCountryCode)); |
|
| 74 | } |
||
| 75 | |||
| 76 | /** |
||
| 77 | * Get IBAN country code. |
||
| 78 | */ |
||
| 79 | private function getIbanCountryCode(string $iban): string |
||
| 80 | { |
||
| 81 | 2 | return substr($iban, 0, 2); |
|
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * Check if bcmod function is available. |
||
| 86 | */ |
||
| 87 | private function checkIfBcmodIsAvailable(): bool |
||
| 88 | { |
||
| 89 | 2 | return function_exists('bcmod'); |
|
| 90 | } |
||
| 91 | |||
| 92 | /** |
||
| 93 | * Check two first character's validity. |
||
| 94 | */ |
||
| 95 | private function twoFirstCharactersValid(string $countryCode): bool |
||
| 96 | { |
||
| 97 | 2 | return ! empty($countryCode) && ctype_alpha($countryCode); |
|
| 98 | } |
||
| 99 | |||
| 100 | /** |
||
| 101 | * Check countries of the IBAN. |
||
| 102 | */ |
||
| 103 | private function isCountriesValid(string $ibanCountryCode): bool |
||
| 104 | { |
||
| 105 | if (empty($this->countries)) { |
||
| 106 | 2 | return true; |
|
| 107 | } |
||
| 108 | |||
| 109 | foreach ($this->countries as $country) { |
||
| 110 | if ($this->isCountryValid($country, $ibanCountryCode)) { |
||
| 111 | return true; |
||
| 112 | } |
||
| 113 | } |
||
| 114 | |||
| 115 | return false; |
||
| 116 | } |
||
| 117 | |||
| 118 | /** |
||
| 119 | * Check country of the IBAN. |
||
| 120 | */ |
||
| 121 | private function isCountryValid(string $country, string $ibanCountryCode): bool |
||
| 122 | { |
||
| 123 | return ! empty($country) |
||
| 124 | && isset($this->ibanLengthByCountry[$country]) |
||
| 125 | && $ibanCountryCode === $country; |
||
| 126 | } |
||
| 127 | |||
| 128 | /** |
||
| 129 | * Check country of the IBAN. |
||
| 130 | */ |
||
| 131 | private function isIbanLengthValid(string $iban, string $ibanCountryCode): bool |
||
| 132 | { |
||
| 133 | 2 | return strlen($iban) === $this->ibanLengthByCountry[$ibanCountryCode]; |
|
| 134 | } |
||
| 135 | } |
||
| 136 |