Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
80.00% covered (warning)
80.00%
4 / 5
CRAP
95.00% covered (success)
95.00%
19 / 20
OgrnOgrnipValidator
0.00% covered (danger)
0.00%
0 / 1
80.00% covered (warning)
80.00%
4 / 5
10
95.00% covered (success)
95.00%
19 / 20
 getDefaultErrorMessages
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 checkValueLength
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 validateValue
0.00% covered (danger)
0.00%
0 / 1
3.02
87.50% covered (warning)
87.50%
7 / 8
 calculateCheckSum
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
8 / 8
 calculateCheckNumber
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
2 / 2
1<?php
2
3
4namespace shumorkiniv\validators;
5
6
7/**
8 * Class OgrnOgrnipValidator
9 * OgrnOgrnipValidator validates that the attribute value is valid OGRN or OGRNIP
10 *
11 * Note, this validator should only be used with string-typed or integer-typed attributes.
12 *
13 * @author Shumorkin Ilya <shumorkinilya@mail.ru>
14 */
15class OgrnOgrnipValidator extends RequisitesValidator
16{
17    /** @var int Divider for OGRN check sum */
18    const OGRN_DIVIDER = 11;
19    /** @var int Divider for OGRNIP check sum */
20    const OGRNIP_DIVIDER = 13;
21
22    /** @var int Length of OGRN */
23    private const OGRN_LENGTH = 13;
24    /** @var int Length of OGRNIP */
25    private const ORGNIP_LENGTH = 15;
26
27    /**
28     * @inheritdoc
29     */
30    protected function getDefaultErrorMessages(): array
31    {
32        return [
33            'wrongLength' => 'ОГРН/ОГРНИП должен состоять из 13 или 15 чисел.',
34            'wrongChar' => 'ОГРН/ОГРНИП должен состоять только из цифр.',
35            'invalidValue' => 'Несуществующий ОГРН/ОГРНИП.',
36        ];
37    }
38
39    /**
40     * @inheritdoc
41     */
42    protected function checkValueLength(string $value): bool
43    {
44        return strlen($value) === self::OGRN_LENGTH || strlen($value) === self::ORGNIP_LENGTH;
45    }
46
47    /**
48     * @inheritdoc
49     */
50    protected function validateValue($value): ?array
51    {
52        $preValidate = $this->preValidate($value);
53
54        if (!empty($preValidate)) {
55            return $preValidate;
56        }
57
58        $comparedNumber = $this->numbers[$this->length - 1];
59        $checkSum = $this->calculateCheckSum();
60
61        if ($comparedNumber !== $this->calculateCheckNumber($checkSum)) {
62            return [$this->message, []];
63        }
64
65        return null;
66    }
67
68    /**
69     * Calculating of check sum
70     *
71     * @return int
72     */
73    private function calculateCheckSum(): int
74    {
75        $factor = 1;
76        $checkSum = 0;
77
78        $numbers = $this->numbers;
79        array_pop($numbers);
80
81        foreach (array_reverse($numbers) as $number) {
82            $checkSum += $number * $factor;
83            $factor *= 10;
84        }
85
86        return $checkSum;
87    }
88
89    /**
90     * Calculating of check number
91     *
92     * @param int $checkSum
93     * @return int
94     */
95    private function calculateCheckNumber(int $checkSum): int
96    {
97        $divider = $this->length === self::OGRN_LENGTH ? self::OGRN_DIVIDER : self::OGRNIP_DIVIDER;
98
99        return $checkSum % $divider;
100    }
101}