Passed
Push — master ( 7a2bea...89672a )
by Antonio Oertel
35s
created

Cpf::calculateDigits()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 13
ccs 10
cts 10
cp 1
rs 9.4285
cc 1
eloc 10
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Brazanation\Documents;
4
5
use Brazanation\Documents\Exception\InvalidDocument as InvalidDocumentException;
6
7
final class Cpf implements DocumentInterface
8
{
9
    const LENGTH = 11;
10
11
    const LABEL = 'CPF';
12
13
    const REGEX = '/^([\d]{3})([\d]{3})([\d]{3})([\d]{2})$/';
14
15
    const FORMAT_REGEX = '/^[\d]{3}\.[\d]{3}\.[\d]{3}-[\d]{2}$/';
16
17
    /**
18
     * @var string
19
     */
20
    private $cpf;
21
22
    /**
23
     * Cpf constructor.
24
     *
25
     * @param string $number Only accept numbers
26
     */
27 11
    public function __construct($number)
28
    {
29 11
        $number = preg_replace('/\D/', '', $number);
30 11
        $this->validate($number);
31 4
        $this->cpf = $number;
32 4
    }
33
34
    /**
35
     * Check if CPF is not empty and is a valid number.
36
     *
37
     * @param string $number
38
     *
39
     * @throws InvalidDocumentException when CPF is empty
40
     * @throws InvalidDocumentException when CPF is not valid number
41
     */
42 11
    private function validate($number)
43
    {
44 11
        if (empty($number)) {
45 3
            throw InvalidDocumentException::notEmpty(static::LABEL);
46
        }
47 8
        if (!$this->isValid($number)) {
48 4
            throw InvalidDocumentException::isNotValid(static::LABEL, $number);
49
        }
50 4
    }
51
52
    /**
53
     * Validates cpf is a valid number.
54
     *
55
     * @param string $number A number to be validate.
56
     *
57
     * @return bool Returns true if it is a valid number, otherwise false.
58
     */
59 8
    private function isValid($number)
60
    {
61 8
        if (strlen($number) != static::LENGTH) {
62 1
            return false;
63
        }
64
65 7
        if (preg_match("/^{$number[0]}{" . static::LENGTH . '}$/', $number)) {
66 1
            return false;
67
        }
68
69 6
        $digits = $this->calculateDigits(substr($number, 0, -2));
70
71 6
        return $digits === substr($number, -2);
72
    }
73
74
    /**
75
     * Formats CPF number
76
     *
77
     * @return string Returns formatted number, such as: 00.000.000/0000-00
78
     */
79 2
    public function format()
80
    {
81 2
        return preg_replace(static::REGEX, '$1.$2.$3-$4', $this->cpf);
82
    }
83
84
    /**
85
     * Returns the CPF number
86
     *
87
     * @return string
88
     */
89 2
    public function __toString()
90
    {
91 2
        return $this->cpf;
92
    }
93
94
    /**
95
     * Calculate check digits from base number.
96
     *
97
     * @param string $number Base numeric section to be calculate your digit.
98
     *
99
     * @return string
100
     */
101 6
    private function calculateDigits($number)
102
    {
103 6
        $calculator = new DigitCalculator($number);
104 6
        $calculator->withMultipliersInterval(2, 11);
105 6
        $calculator->useComplementaryInsteadOfModule();
106 6
        $calculator->replaceWhen('0', 10, 11);
107 6
        $calculator->withModule(DigitCalculator::MODULE_11);
108 6
        $firstDigit = $calculator->calculate();
109 6
        $calculator->addDigit($firstDigit);
110 6
        $secondDigit = $calculator->calculate();
111
112 6
        return "{$firstDigit}{$secondDigit}";
113
    }
114
}
115