Completed
Push — scrutinizer ( 42ac6a...7bc18e )
by z38
02:40
created

IBAN::normalize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Z38\SwissPayment;
4
5
/**
6
 * IBAN
7
 */
8
class IBAN
9
{
10
    const MAX_LENGTH = 34;
11
    const PATTERN = '/^[A-Z]{2,2}[0-9]{2,2}[A-Z0-9]{1,30}$/';
12
13
    /**
14
     * @var string
15
     */
16
    protected $iban;
17
18
    /**
19
     * Constructor
20
     *
21
     * @param string $iban
22
     *
23
     * @throws \InvalidArgumentException When the IBAN does contain invalid characters or the checksum calculation fails.
24
     */
25 8
    public function __construct($iban)
26
    {
27 8
        $cleanedIban = str_replace(' ', '', strtoupper($iban));
28 8
        if (!preg_match(self::PATTERN, $cleanedIban)) {
29 1
            throw new \InvalidArgumentException('IBAN is not properly formatted.');
30
        }
31 7
        if (!self::check($cleanedIban)) {
32 1
            throw new \InvalidArgumentException('IBAN has an invalid checksum.');
33
        }
34
35 6
        $this->iban = $cleanedIban;
36 6
    }
37
38
    /**
39
     * Format the IBAN either in a human-readable manner
40
     *
41
     * @return string The formatted IBAN
42
     */
43 1
    public function format()
44
    {
45 1
        $parts = str_split($this->iban, 4);
46
47 1
        return implode(' ', $parts);
48
    }
49
50
    /**
51
     * Normalize the IBAN
52
     *
53
     * @return string The normalized IBAN
54
     */
55 3
    public function normalize()
56
    {
57 3
        return $this->iban;
58
    }
59
60
    /**
61
     * Gets the country
62
     *
63
     * @return string A ISO 3166-1 alpha-2 country code
64
     */
65 6
    public function getCountry()
66
    {
67 6
        return substr($this->iban, 0, 2);
68
    }
69
70
    /**
71
     * Checks whether the checksum of an IBAN is correct
72
     *
73
     * @param string $iban
74
     *
75
     * @return bool true if checksum is correct, false otherwise
76
     */
77 3
    protected static function check($iban)
78
    {
79 3
        $chars = str_split(substr($iban, 4).substr($iban, 0, 4));
80 3
        $length = count($chars);
81 3
        for ($i = 0; $i < $length; $i++) {
82 3
            $code = ord($chars[$i]);
83 3
            if ($code >= 65 && $code <= 90) { // A-Z
84 3
                $chars[$i] = $code - 65 + 10;
85 3
            }
86 3
        }
87 3
        $prepared = implode($chars);
88
89 3
        $r = '';
90 3
        $rLength = 0;
91 3
        $i = 0;
92 3
        $length = strlen($prepared);
93 3
        while ($i < $length) {
94 3
            $d = $r.substr($prepared, $i, 9 - $rLength);
95 3
            $i += 9 - $rLength;
96 3
            $r = $d % 97;
97 3
            $rLength = 1 + ($r >= 10);
98 3
        }
99
100 3
        return ($r == 1);
101
    }
102
103
    /**
104
     * Returns a string representation.
105
     *
106
     * @return string The string representation.
107
     */
108 3
    public function __toString()
109
    {
110 3
        return $this->format();
111
    }
112
}
113