Completed
Pull Request — master (#19)
by Antonio Oertel
03:12
created

AbstractDocument::extractCheckerDigit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Brazanation\Documents;
4
5
use Brazanation\Documents\Exception\InvalidDocument as InvalidDocumentException;
6
7
abstract class AbstractDocument implements DocumentInterface
8
{
9
    /**
10
     * @var string
11
     */
12
    protected $number;
13
14
    /**
15
     * @var string
16
     */
17
    protected $digit;
18
19
    /**
20
     * @var int
21
     */
22
    protected $length;
23
24
    /**
25
     * @var int
26
     */
27
    protected $numberOfDigits;
28
29
    /**
30
     * @var string
31
     */
32
    protected $type;
33
34
    /**
35
     * AbstractDocument constructor.
36
     *
37
     * @param string $number         Numeric section with checker digit.
38
     * @param int    $length         Max length of document.
39
     * @param int    $numberOfDigits Max length of checker digits.
40
     * @param string $type           Document name/type.
41
     */
42 548
    public function __construct($number, $length, $numberOfDigits, $type)
43
    {
44 548
        $this->type = (string) $type;
45 548
        $this->numberOfDigits = (int) $numberOfDigits;
46 548
        $this->length = (int) $length;
47 548
        $this->digit = $this->extractCheckerDigit($number);
48 548
        $this->validate($number);
49 409
        $this->number = $number;
50 409
    }
51
52
    /**
53
     * Check if document number is valid.
54
     *
55
     * @param string $number Numeric section with checker digit.
56
     *
57
     * @throws InvalidDocumentException when number is empty
58
     * @throws InvalidDocumentException when number is not valid
59
     */
60 548
    protected function validate($number)
61
    {
62 548
        if (empty($number)) {
63 57
            throw InvalidDocumentException::notEmpty($this->type);
64
        }
65 491
        if (!$this->isValid($number)) {
66 82
            throw InvalidDocumentException::isNotValid($this->type, $number);
67
        }
68 409
    }
69
70
    /**
71
     * Validates number is a valid.
72
     *
73
     * @param string $number Numeric section with checker digit.
74
     *
75
     * @return bool Returns true if it is a valid number, otherwise false.
76
     */
77 491
    protected function isValid($number)
78
    {
79 491
        $isRepeated = preg_match("/^{$number[0]}{" . $this->length . '}$/', $number);
80
81 491
        if (strlen($number) != $this->length || $isRepeated) {
82 49
            return false;
83
        }
84
85 442
        $baseNumber = $this->extractBaseNumber($number);
86 442
        $digit = $this->calculateDigit($baseNumber);
87
88 442
        return "$digit" === "{$this->digit}";
89
    }
90
91
    /**
92
     * Handle number to string.
93
     *
94
     * @return string
95
     */
96 409
    public function __toString()
97
    {
98 409
        return "{$this->number}";
99
    }
100
101
    /**
102
     * Extracts the base number document.
103
     *
104
     * @param string $number Number of document.
105
     *
106
     * @return string Returns only base number without checker digit.
107
     */
108 44
    protected function extractBaseNumber($number)
109
    {
110 44
        return substr($number, 0, -($this->numberOfDigits));
111
    }
112
113
    /**
114
     * Extracts the checker digit from document number.
115
     *
116
     * @param string $number Number of document.
117
     *
118
     * @return string Returns only checker digit.
119
     */
120 72
    protected function extractCheckerDigit($number)
121
    {
122 72
        return substr($number, -($this->numberOfDigits));
123
    }
124
}
125