ESAlgorithm   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 42
c 1
b 0
f 0
dl 0
loc 91
rs 10
wmc 23

10 Methods

Rating   Name   Duplication   Size   Complexity  
A isFollowLength() 0 3 1
A isFollowESRule1() 0 7 1
A validate() 0 13 5
A isFollowPattern2() 0 3 1
A isFollowRules() 0 3 4
B getNumberFromChar() 0 14 7
A fillWith0() 0 3 1
A isFollowESRule2() 0 9 1
A getCharFromNumber() 0 3 1
A isFollowPattern1() 0 3 1
1
<?php
2
3
namespace LeKoala\Tin\Algo;
4
5
use LeKoala\Tin\Util\StringUtil;
6
7
/**
8
 * Spain
9
 */
10
class ESAlgorithm extends TINAlgorithm
11
{
12
    const LENGTH = 9;
13
    const PATTERN_1 = "\\d{8}[a-zA-Z]";
14
    const PATTERN_2 = "[XYZKLMxyzklm]\\d{7}[a-zA-Z]";
15
16
    /**
17
     * @var array
18
     */
19
    private static $tabConvertToChar = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E'];
20
21
    public function validate(string $tin)
22
    {
23
        $normalizedTIN = $this->fillWith0($tin);
24
        if (!$this->isFollowLength($normalizedTIN)) {
25
            return StatusCode::INVALID_LENGTH;
26
        }
27
        if (!$this->isFollowPattern1($normalizedTIN) && !$this->isFollowPattern2($normalizedTIN)) {
28
            return StatusCode::INVALID_PATTERN;
29
        }
30
        if (!$this->isFollowRules($normalizedTIN)) {
31
            return StatusCode::INVALID_SYNTAX;
32
        }
33
        return StatusCode::VALID;
34
    }
35
36
    public function isFollowLength(string $tin)
37
    {
38
        return StringUtil::isFollowLength($tin, self::LENGTH);
39
    }
40
41
    public function isFollowPattern1(string $tin)
42
    {
43
        return StringUtil::isFollowPattern($tin, self::PATTERN_1);
44
    }
45
46
    public function isFollowPattern2(string $tin)
47
    {
48
        return StringUtil::isFollowPattern($tin, self::PATTERN_2);
49
    }
50
51
    public function isFollowRules(string $tin)
52
    {
53
        return ($this->isFollowPattern1($tin) && $this->isFollowESRule1($tin)) || ($this->isFollowPattern2($tin) && $this->isFollowESRule2($tin));
54
    }
55
56
    private function isFollowESRule1(string $tin)
57
    {
58
        $number = intval(StringUtil::substring($tin, 0, strlen($tin) - 1));
59
        $checkDigit = $tin[strlen($tin) - 1];
60
        $remainderBy23 = $number % 23;
61
        $sum = $remainderBy23 + 1;
62
        return strtoupper($checkDigit) == $this->getCharFromNumber($sum);
63
    }
64
65
    private function isFollowESRule2(string $tin)
66
    {
67
        $c1 = StringUtil::forDigit($this->getNumberFromChar($tin[0]), 10);
68
        $number = intval($c1 . StringUtil::substring($tin, 1, strlen($tin) - 1));
69
        $checkDigit =  $tin[strlen($tin) - 1];
70
        $remainderBy23 = $number % 23;
71
        $sum = $remainderBy23 + 1;
72
73
        return strtoupper($checkDigit) == $this->getCharFromNumber($sum);
74
    }
75
76
    protected function getNumberFromChar($m)
77
    {
78
        switch (strtoupper($m)) {
79
            case 'K':
80
            case 'L':
81
            case 'M':
82
            case 'X':
83
                return 0;
84
            case 'Y':
85
                return 1;
86
            case 'Z':
87
                return 2;
88
            default:
89
                return -1;
90
        }
91
    }
92
93
    private function getCharFromNumber($sum)
94
    {
95
        return self::$tabConvertToChar[$sum - 1];
96
    }
97
98
    private function fillWith0(string $tin)
99
    {
100
        return StringUtil::fillWith0UntilLength($tin, self::LENGTH);
101
    }
102
}
103