Validator   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 95.45%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 2
dl 0
loc 122
ccs 21
cts 22
cp 0.9545
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B isValid() 0 25 6
A isValidCountryCode() 0 4 1
A getViesClient() 0 8 2
1
<?php
2
3
namespace Ddeboer\Vatin;
4
5
use Ddeboer\Vatin\Vies\Client;
6
use Ddeboer\Vatin\Exception\ViesException;
7
8
/**
9
 * Validate a VAT identification number (VATIN)
10
 *
11
 * @link http://en.wikipedia.org/wiki/VAT_identification_number
12
 * @link http://sima.cat/nif.php
13
 * @link https://github.com/jonathanmaron/zf2_proposal/blob/master/library/Zend/Validator/Vatin.php
14
 */
15
class Validator
16
{
17
    /**
18
     * Regular expression patterns per country code
19
     *
20
     * @var array
21
     * @link http://ec.europa.eu/taxation_customs/vies/faq.html?locale=lt#item_11
22
     */
23
    private $patterns = array(
24
        'AT' => 'U[A-Z\d]{8}',
25
        'BE' => '[0|1]{1}\d{9}',
26
        'BG' => '\d{9,10}',
27
        'CH' => 'E(-| ?)(\d{3}(\.)\d{3}(\.)\d{3}|\d{9})( ?)(MWST|TVA|IVA)',
28
        'CY' => '\d{8}[A-Z]',
29
        'CZ' => '\d{8,10}',
30
        'DE' => '\d{9}',
31
        'DK' => '(\d{2} ?){3}\d{2}',
32
        'EE' => '\d{9}',
33
        'EL' => '\d{9}',
34
        'ES' => '[A-Z]\d{7}[A-Z]|\d{8}[A-Z]|[A-Z]\d{8}',
35
        'FI' => '\d{8}',
36
        'FR' => '([A-Z0-9]{2})\d{9}',
37
        'GB' => '\d{9}|\d{12}|(GD|HA)\d{3}',
38
        'HR' => '\d{11}',
39
        'HU' => '\d{8}',
40
        'IE' => '[A-Z\d]{8}|[A-Z\d]{9}',
41
        'IT' => '\d{11}',
42
        'LT' => '(\d{9}|\d{12})',
43
        'LU' => '\d{8}',
44
        'LV' => '\d{11}',
45
        'MT' => '\d{8}',
46
        'NL' => '\d{9}B\d{2}',
47
        'NO' => '\d{9}(MVA){0,1}',
48
        'PL' => '\d{10}',
49
        'PT' => '\d{9}',
50
        'RO' => '\d{2,10}',
51
        'SE' => '\d{12}',
52
        'SI' => '\d{8}',
53
        'SK' => '\d{10}'
54
    );
55
56
    /**
57
     * Client for the VIES web service
58
     *
59
     * @var Client
60
     */
61
    private $viesClient;
62
63
    /**
64
     * Constructor
65
     *
66
     * @param Client|null $viesClient Client for the VIES web service
67
     */
68 79
    public function __construct(Client $viesClient = null)
69
    {
70 79
        $this->viesClient = $viesClient;
71 79
    }
72
73
    /**
74
     * Returns true if value is a valid VAT identification number, false
75
     * otherwise
76
     *
77
     * @param string $value          Value
78
     * @param bool   $checkExistence In addition to checking the VATIN's format
79
     *                               for validity, also check whether the VATIN
80
     *                               exists. This requires a call to the VIES
81
     *                               web service.
82
     *
83
     * @return bool
84
     */
85 79
    public function isValid($value, $checkExistence = false)
86
    {
87 79
        if (null === $value || '' === $value) {
88 2
            return false;
89
        }
90
91 77
        $countryCode = substr($value, 0, 2);
92 77
        $vatin = substr($value, 2);
93
94 77
        if (false === $this->isValidCountryCode($countryCode)) {
95 2
            return false;
96
        }
97
98 75
        if (0 === preg_match('/^(?:'.$this->patterns[$countryCode].')$/', $vatin)) {
99 3
            return false;
100
        }
101
102 72
        if (true === $checkExistence) {
103 3
            $result = $this->getViesClient()->checkVat($countryCode, $vatin);
104
105 2
            return $result->isValid();
106
        }
107
108 69
        return true;
109
    }
110
111
    /**
112
     * Returns true if value is valid country code, false otherwise
113
     *
114
     * @param string $value Value
115
     *
116
     * @return bool
117
     */
118 77
    private function isValidCountryCode($value)
119
    {
120 77
        return isset($this->patterns[$value]);
121
    }
122
123
    /**
124
     * Get VIES client
125
     *
126
     * @return Client
127
     */
128 3
    private function getViesClient()
129
    {
130 3
        if ($this->viesClient === null) {
131
            $this->viesClient = new Client();
132
        }
133
134 3
        return $this->viesClient;
135
    }
136
}
137