CifValidator::validateCIF()   B
last analyzed

Complexity

Conditions 8
Paths 18

Size

Total Lines 38
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 8
eloc 21
c 2
b 0
f 1
nc 18
nop 1
dl 0
loc 38
rs 8.4444
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ByTIC\Validator\Constraints;
6
7
use Symfony\Component\Validator\Constraint;
8
use Symfony\Component\Validator\ConstraintValidator;
9
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
10
use Symfony\Component\Validator\Exception\UnexpectedValueException;
11
12
/**
13
 * Class CifValidator.
14
 */
15
class CifValidator extends ConstraintValidator
16
{
17
    private static $controlKey = [7, 5, 3, 2, 1, 7, 5, 3, 2];
18
19
    /**
20
     * {@inheritDoc}
21
     */
22
    public function validate($value, Constraint $constraint)
23
    {
24
        if (!$constraint instanceof Cif) {
25
            throw new UnexpectedTypeException($constraint, Cif::class);
26
        }
27
28
        if (null === $value) {
29
            return;
30
        }
31
32
        $value = (string) $value;
33
        $value = trim($value);
34
        if (empty($value)) {
35
            throw new UnexpectedValueException($value, 'string');
36
        }
37
38
        if (!is_numeric($value) && !\is_string($value)) {
0 ignored issues
show
introduced by
The condition is_string($value) is always true.
Loading history...
39
            // throw this exception if your validator cannot handle the passed type so that it can be marked as invalid
40
            throw new UnexpectedValueException($value, 'string');
41
            // separate multiple types using pipes
42
            // throw new UnexpectedValueException($value, 'string|int');
43
        }
44
45
        if (false === $this->validateCIF($value)) {
46
            // the argument must be a string or an object implementing __toString()
47
            $this->context->buildViolation($constraint->message)
48
                ->setParameter('{{ string }}', $value)
49
                ->addViolation();
50
        }
51
    }
52
53
    protected function validateCIF($cif)
54
    {
55
        // Daca este string, elimina atributul fiscal si spatiile
56
        if (!is_numeric($cif)) {
57
            $cif = strtoupper($cif);
58
            if (0 === strpos($cif, 'RO')) {
59
                $cif = substr($cif, 2);
60
            }
61
            $cif = (int) trim($cif);
62
        }
63
64
        if ((int) $cif <= 0) {
65
            return false;
66
        }
67
68
        $cif = (string) $cif;
69
        $cifLength = \strlen($cif);
70
        // daca are mai mult de 10 cifre sau mai putin de 2, nu-i valid
71
        if ($cifLength > 10 || $cifLength < 2) {
72
            return false;
73
        }
74
75
        // extrage cifra de control
76
        $controlKey = (int) substr($cif, -1);
77
78
        $cif = substr($cif, 0, -1);
79
        $cif = str_pad($cif, 9, '0', \STR_PAD_LEFT);
80
        $suma = 0;
81
        foreach (self::$controlKey as $i => $key) {
82
            $suma += (int) $cif[$i] * (int) $key;
83
        }
84
        $suma = $suma * 10;
85
        $rest = (int) ($suma % 11);
86
87
        // daca modulo 11 este 10, atunci cifra de control este 0
88
        $rest = (10 == $rest) ? 0 : $rest;
89
90
        return $rest === $controlKey;
91
    }
92
}
93