Passed
Push — master ( 7bcc6f...9b4044 )
by Thanos
01:49
created

AfmValidator   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 51
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 96.43%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 4
dl 0
loc 51
ccs 27
cts 28
cp 0.9643
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A validate() 0 26 5
A checkModAgainstLastDigit() 0 4 3
A calculateChecksum() 0 9 2
A buildViolation() 0 6 1
1
<?php
2
3
namespace SymfonyGreekValidation;
4
5
use Symfony\Component\Validator\Constraint;
6
use Symfony\Component\Validator\ConstraintValidator;
7
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
8
9
class AfmValidator extends ConstraintValidator
10
{
11 10
    public function validate($value, Constraint $constraint)
12
    {
13 10
        if (!$constraint instanceof Afm) {
14
            throw new UnexpectedTypeException($constraint, Afm::class);
15
        }
16
17 10
        if (empty($value)) {
18 2
            return;
19
        }
20
21 8
        if (!is_numeric($value)) {
22 1
            $this->buildViolation($value, $constraint);
23 1
            return;
24
        }
25
26 7
        $reverseAfm = array_reverse(str_split($value));
27 7
        $lastDigit = (int)array_shift($reverseAfm);
28 7
        $checksum = $this->calculateChecksum($reverseAfm);
29 7
        $mod = $checksum % 11;
30
31 7
        if ($this->checkModAgainstLastDigit($mod, $lastDigit)) {
32 6
            return;
33
        }
34
35 1
        $this->buildViolation($value, $constraint);
36 1
    }
37
38 7
    private function checkModAgainstLastDigit($mod, $lastDigit): bool
39
    {
40 7
        return (10 === $mod && $lastDigit === 0) || ($mod === $lastDigit);
41
    }
42
43 7
    private function calculateChecksum($reverseAfm): int
44
    {
45 7
        $checksum = 0;
46 7
        foreach ($reverseAfm as $index => $value) {
47 7
            $checksum += $value * pow(2, ++$index);
48
        }
49
50 7
        return $checksum;
51
    }
52
53 2
    private function buildViolation($value, $constraint): void
54
    {
55 2
        $this->context->buildViolation($constraint->message)
56 2
            ->setParameter('{{ string }}', $value)
57 2
            ->addViolation();
58
    }
59
}