Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
19 / 19
CRAP
100.00% covered (success)
100.00%
1 / 1
Iban
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
19 / 19
24
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 parse
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 normalize
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLength
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getChecksum
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSequence
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
 getCountry
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 getNationalChecksum
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBranchCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAccountType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCurrency
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBankCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAccount
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHoldersKennital
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getOwnerAccountNumber
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBicCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 serialize
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 prettyPrint
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 unserialize
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Stdlib\Base
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Stdlib\Base;
16
17use phpOMS\Contract\SerializableInterface;
18use phpOMS\Validation\Finance\IbanEnum;
19
20/**
21 * Iban class.
22 *
23 * @package phpOMS\Stdlib\Base
24 * @license OMS License 2.0
25 * @link    https://jingga.app
26 * @since   1.0.0
27 */
28class Iban implements SerializableInterface
29{
30    /**
31     * Iban.
32     *
33     * @var string
34     * @since 1.0.0
35     */
36    private string $iban = '';
37
38    /**
39     * Constructor.
40     *
41     * @param string $iban Iban
42     *
43     * @since 1.0.0
44     */
45    public function __construct(string $iban)
46    {
47        $this->parse($iban);
48    }
49
50    /**
51     * Parsing iban string
52     *
53     * @param string $iban Iban to parse
54     *
55     * @return void
56     *
57     * @throws \InvalidArgumentException
58     *
59     * @since 1.0.0
60     */
61    private function parse(string $iban) : void
62    {
63        $this->iban = self::normalize($iban);
64
65        if (!\phpOMS\Validation\Finance\Iban::isValid($this->iban)) {
66            throw new \InvalidArgumentException('Invalid IBAN');
67        }
68    }
69
70    /**
71     * Normalize iban
72     *
73     * @param string $iban Iban to normalize
74     *
75     * @return string
76     *
77     * @since 1.0.0
78     */
79    public static function normalize(string $iban) : string
80    {
81        return \strtoupper(\str_replace(' ', '', $iban));
82    }
83
84    /**
85     * Get normalized iban length
86     *
87     * @return int
88     *
89     * @since 1.0.0
90     */
91    public function getLength() : int
92    {
93        return \strlen($this->iban);
94    }
95
96    /**
97     * Get iban checksum
98     *
99     * @return string
100     *
101     * @since 1.0.0
102     */
103    public function getChecksum() : string
104    {
105        return $this->getSequence('k');
106    }
107
108    /**
109     * Get sequence specified in the layout
110     *
111     * @param string $sequence Sequence identifier
112     *
113     * @return string
114     *
115     * @since 1.0.0
116     */
117    private function getSequence(string $sequence) : string
118    {
119        $country = $this->getCountry();
120
121        /** @var string $iban */
122        $iban   = IbanEnum::getByName('C_' . $country);
123        $layout = \str_replace(' ', '', $iban);
124        $start  = \stripos($layout, $sequence);
125        $end    = \strrpos($layout, $sequence);
126
127        if ($start === false || $end === false) {
128            return '';
129        }
130
131        $sequence = \substr($this->iban, $start, $end - $start + 1);
132
133        return $sequence === false ? '' : $sequence;
134    }
135
136    /**
137     * Get 2 digit country code
138     *
139     * @return string
140     *
141     * @since 1.0.0
142     */
143    public function getCountry() : string
144    {
145        $country = \substr($this->iban, 0, 2);
146
147        return $country === false ? '?' : $country;
148    }
149
150    /**
151     * Get national checksum
152     *
153     * @return string
154     *
155     * @since 1.0.0
156     */
157    public function getNationalChecksum() : string
158    {
159        return $this->getSequence('x');
160    }
161
162    /**
163     * Get branch code
164     *
165     * @return string
166     *
167     * @since 1.0.0
168     */
169    public function getBranchCode() : string
170    {
171        return $this->getSequence('s');
172    }
173
174    /**
175     * Get account type (cheque account, savings etc.)
176     *
177     * @return string
178     *
179     * @since 1.0.0
180     */
181    public function getAccountType() : string
182    {
183        return $this->getSequence('t');
184    }
185
186    /**
187     * Get currency
188     *
189     * @return string
190     *
191     * @since 1.0.0
192     */
193    public function getCurrency() : string
194    {
195        return $this->getSequence('m');
196    }
197
198    /**
199     * Get bank code
200     *
201     * @return string
202     *
203     * @since 1.0.0
204     */
205    public function getBankCode() : string
206    {
207        return $this->getSequence('b');
208    }
209
210    /**
211     * Get account
212     *
213     * @return string
214     *
215     * @since 1.0.0
216     */
217    public function getAccount() : string
218    {
219        return $this->getSequence('c');
220    }
221
222    /**
223     * Get holder's kennital
224     *
225     * @return string
226     *
227     * @since 1.0.0
228     */
229    public function getHoldersKennital() : string
230    {
231        return $this->getSequence('i');
232    }
233
234    /**
235     * Get owner account number
236     *
237     * @return string
238     *
239     * @since 1.0.0
240     */
241    public function getOwnerAccountNumber() : string
242    {
243        return $this->getSequence('n');
244    }
245
246    /**
247     * Get BIC
248     *
249     * Only very rarely used in iban
250     *
251     * @return string
252     *
253     * @since 1.0.0
254     */
255    public function getBicCode() : string
256    {
257        return $this->getSequence('a');
258    }
259
260    /**
261     * {@inheritdoc}
262     */
263    public function serialize() : string
264    {
265        return $this->prettyPrint();
266    }
267
268    /**
269     * Pretty print iban
270     *
271     * @return string
272     *
273     * @since 1.0.0
274     */
275    public function prettyPrint() : string
276    {
277        return \wordwrap($this->iban, 4, ' ', true);
278    }
279
280    /**
281     * Constructs the object
282     * @link  http://php.net/manual/en/serializable.unserialize.php
283     * @param  string $serialized <p>
284     *                            The string representation of the object.
285     *                            </p>
286     * @return void
287     * @since 5.1.0
288     */
289    public function unserialize(mixed $serialized) : void
290    {
291        $this->parse($serialized);
292    }
293}