Completed
Push — master ( 2a0971...fa0347 )
by kouinkouin
01:13
created

TransferMessage::getStructuredMessage()   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.125

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 4
cp 0.5
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1.125
1
<?php
2
3
namespace Netsensei\BeBankTransferMessage;
4
5
use Netsensei\BeBankTransferMessage\Exception\TransferMessageException;
6
7
class TransferMessage
8
{
9
    /**
10
     * Set divisor used to calculate the modulus
11
     */
12
    const MODULO = 97;
13
14
    /**
15
     * Set the asterisk sign as a circumfix
16
     */
17
    const CIRCUMFIX_ASTERISK = "*";
18
19
    /**
20
     * Set the plus sign as a circumfix
21
     */
22
    const CIRCUMFIX_PLUS = "+";
23
24
    /**
25
     * The number used to generate a structured message
26
     *
27
     * @var int
28
     */
29
    private $number;
30
31
    /**
32
     * The modulus resulting from the modulo operation
33
     *
34
     * @var int
35
     */
36
    private $modulus;
37
38
    /**
39
     * A structured message with a valid formatting
40
     *
41
     * @var string
42
     */
43
    private $structuredMessage = null;
44
45
    /**
46
     * Create a new instance
47
     *
48
     * @param int $number The number used to generate a structured message
49
     */
50 16
    public function __construct($number = null)
51
    {
52 16
        $this->setNumber($number);
53 16
        $this->generate();
54 16
    }
55
56
    /**
57
     * Generate a valid structured message based on the number
58
     *
59
     * @param  string $circumfix The circumfix. Defaults to the plus sign
60
     *
61
     * @return string            A valid structured message
62
     */
63 16
    public function generate($circumfix = self::CIRCUMFIX_PLUS)
64
    {
65 16
        $this->modulus = $this->mod($this->number);
66
67 16
        $structuredMessage = str_pad($this->number, 10, 0, STR_PAD_LEFT).str_pad($this->modulus, 2, 0, STR_PAD_LEFT);
68
69 16
        $pattern = ['/^([0-9]{3})([0-9]{4})([0-9]{5})$/'];
70 16
        $replace = [str_pad('$1/$2/$3', 14, $circumfix, STR_PAD_BOTH)];
71 16
        $this->structuredMessage = preg_replace($pattern, $replace, $structuredMessage);
72
73 16
        return $this->structuredMessage;
74
    }
75
76
    /**
77
     * The mod97 calculation
78
     *
79
     * If the modulus is 0, the result is substituted to 97
80
     *
81
     * @param  int $dividend The dividend
82
     *
83
     * @return int           The modulus
84
     */
85 16
    private function mod($dividend)
86
    {
87 16
        $modulus = $dividend % self::MODULO;
88
89 16
        return ($modulus > 0) ? $modulus : self::MODULO;
90
    }
91
92
    /**
93
     * Get the number
94
     *
95
     * @return int The number used to generate a structured message
96
     */
97 2
    public function getNumber()
98
    {
99 2
        return $this->number;
100
    }
101
102
    /**
103
     * Set the number
104
     *
105
     * If no number is passed to this method, a random number will be generated
106
     *
107
     * @param int $number The number used to generate a structured message
108
     *
109
     * @throws TransferMessageException If the number is out of bounds
110
     */
111 16
    public function setNumber($number = null)
112
    {
113
        try {
114 16
            if (is_null($number)) {
115 10
                if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
116
                    $this->number = random_int(1, 9999999999);
117
                } else {
118 10
                    $this->number = mt_rand(1, 9999999999);
119
                }
120 10
            } else {
121 14
                if (($number < 1) || ($number > 9999999999)) {
122 6
                    throw new \InvalidArgumentException(
123
                        'The number should be an integer larger then 0 and smaller then 9999999999.'
124 6
                    );
125
                }
126
127 8
                $this->number = $number;
128
            }
129 16
        } catch (\Exception $e) {
130 6
            throw new TransferMessageException('Failed to set number', null, $e);
131
        }
132 16
    }
133
134
    /**
135
     * Get the modulus
136
     *
137
     * @return int The modulus resulting from the modulo operation
138
     */
139 2
    public function getModulus()
140
    {
141 2
        return $this->modulus;
142
    }
143
144
    /**
145
     * Get the structured message
146
     *
147
     * @return string A valid formatted structured message
148
     */
149 2
    public function getStructuredMessage()
150
    {
151 2
        return $this->structuredMessage;
152
    }
153
154
    /**
155
     * Set a structured message
156
     *
157
     * @param string $structuredMessage A structured message
158
     *
159
     * @throws  TransferMessageException If the format is not valid
160
     */
161 4
    public function setStructuredMessage($structuredMessage)
162
    {
163
        try {
164 4
            $pattern = '/^[\+\*]{3}[0-9]{3}[\/]?[0-9]{4}[\/]?[0-9]{5}[\+\*]{3}$/';
165 4
            if (preg_match($pattern, $structuredMessage) === 0) {
166 2
                throw new \InvalidArgumentException('The structured message does not have a valid format.');
167
            } else {
168 2
                $this->structuredMessage = $structuredMessage;
169
            }
170 4
        } catch (\Exception $e) {
171 2
            throw new TransferMessageException('Failed to validate the format of the structured message', null, $e);
172
        }
173 2
    }
174
175
    /**
176
     * Validates a structured message
177
     *
178
     * The validation is the mod97 calculation of the number and comparison of
179
     * the result to the provided modulus.
180
     *
181
     * @return bool TRUE if valid, FALSE if invalid
182
     */
183 2
    public function validate()
184
    {
185 2
        $pattern = ['/^[\+\*]{3}([0-9]{3})[\/]?([0-9]{4})[\/]?([0-9]{5})[\+\*]{3}$/'];
186 2
        $replace = ['${1}${2}${3}'];
187 2
        $rawStructuredMessage = preg_replace($pattern, $replace, $this->structuredMessage);
188
189 2
        $number = substr($rawStructuredMessage, 0, 10);
190 2
        $modulus = substr($rawStructuredMessage, 10, 2);
191
192 2
        return ($modulus == $this->mod($number)) ? true : false;
193
    }
194
}
195