Passed
Pull Request — 1.x (#46)
by Milwad
03:01
created

IbanTrait::isCountryValid()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 3
c 1
b 0
f 1
nc 3
nop 2
dl 0
loc 5
rs 10
1
<?php
2
3
namespace Milwad\LaravelValidate\Traits;
4
5
trait IbanTrait
6
{
7
    /**
8
     * Set value of $countries property.
9
     *
10
     * @return void
11
     */
12
    private function setCountries(array|null $countries)
13
    {
14
        if (empty($countries)) {
15
            $this->countries = [];
0 ignored issues
show
Bug Best Practice introduced by
The property countries does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
16
17
            return;
18
        }
19
20
        if (is_array($countries[0])) {
21
            $countries = $countries[0];
22
        }
23
24
        foreach ($countries as $country) {
25
            $this->countries[] = $country;
26
        }
27
    }
28
29
    /**
30
     * Check IBAN is valid.
31
     *
32
     * @return bool
33
     */
34
    private function isIbanValid(string $iban)
35
    {
36
        if (! $this->checkIbanFormat($iban)) {
37
            return false;
38
        }
39
40
        /*
41
         * Connect Iban title with value (code) ex: 8330001234567NO .
42
         */
43
        $parsedIban = substr($iban, 4).substr($iban, 0, 4);
44
45
        /*
46
         * Replace iban value with character map.
47
         */
48
        $parsedIban = strtr($parsedIban, $this->characterMap);
49
50
        return bcmod($parsedIban, '97') === '1';
51
    }
52
53
    /**
54
     * Check IBAN format is valid.
55
     *
56
     * @return bool
57
     */
58
    private function checkIbanFormat(string $iban)
59
    {
60
        if (empty($iban)) {
61
            return false;
62
        }
63
64
        $ibanCountryCode = $this->getIbanCountryCode($iban);
65
66
        return ! (empty($this->checkIfBcmodIsAvailable())
67
            || ! $this->twoFirstCharactersValid($ibanCountryCode)
68
            || ! $this->isCountriesValid($ibanCountryCode)
69
            || ! $this->isIbanLengthValid($iban, $ibanCountryCode));
70
    }
71
72
    /**
73
     * Get IBAN country code.
74
     *
75
     * @return string
76
     */
77
    private function getIbanCountryCode(string $iban)
78
    {
79
        return substr($iban, 0, 2);
80
    }
81
82
    /**
83
     * Check if bcmod function is available.
84
     *
85
     * @return bool
86
     */
87
    private function checkIfBcmodIsAvailable()
88
    {
89
        return function_exists('bcmod');
90
    }
91
92
    /**
93
     * Check two first character's validity.
94
     *
95
     * @return bool
96
     */
97
    private function twoFirstCharactersValid(string $countryCode)
98
    {
99
        return ! empty($countryCode) && ctype_alpha($countryCode);
100
    }
101
102
    /**
103
     * Check countries of the IBAN.
104
     *
105
     * @return bool
106
     */
107
    private function isCountriesValid(string $ibanCountryCode)
108
    {
109
        if (empty($this->countries)) {
110
            return true;
111
        }
112
113
        foreach ($this->countries as $country) {
114
            if ($this->isCountryValid($country, $ibanCountryCode)) {
115
                return true;
116
            }
117
        }
118
119
        return false;
120
    }
121
122
    /**
123
     * Check country of the IBAN.
124
     *
125
     * @return bool
126
     */
127
    private function isCountryValid(string $country, string $ibanCountryCode)
128
    {
129
        return ! empty($country)
130
            && isset($this->ibanLengthByCountry[$country])
131
            && $ibanCountryCode === $country;
132
    }
133
134
    /**
135
     * Check country of the IBAN.
136
     *
137
     * @return bool
138
     */
139
    private function isIbanLengthValid(string $iban, string $ibanCountryCode)
140
    {
141
        return strlen($iban) === $this->ibanLengthByCountry[$ibanCountryCode];
142
    }
143
}
144