Completed
Push — master ( 81a1ef...954e16 )
by kouinkouin
01:56
created

TransferMessage   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 188
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 95.92%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 1
dl 0
loc 188
ccs 47
cts 49
cp 0.9592
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A generate() 0 12 1
A mod() 0 6 2
A getNumber() 0 4 1
B setNumber() 0 22 6
A getModulus() 0 4 1
A getStructuredMessage() 0 4 1
A setStructuredMessage() 0 13 3
A validate() 0 11 2
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 int
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 24
    public function __construct($number = null)
51
    {
52 24
        $this->setNumber($number);
53 24
        $this->generate();
54 24
    }
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 24
    public function generate($circumfix = self::CIRCUMFIX_PLUS)
64
    {
65 24
        $this->modulus = $this->mod($this->number);
66
67 24
        $structuredMessage = str_pad($this->number, 10, 0, STR_PAD_LEFT).str_pad($this->modulus, 2, 0, STR_PAD_LEFT);
68
69 24
        $pattern = ['/^([0-9]{3})([0-9]{4})([0-9]{5})$/'];
70 24
        $replace = [str_pad('$1/$2/$3', 14, $circumfix, STR_PAD_BOTH)];
71 24
        $this->structuredMessage = preg_replace($pattern, $replace, $structuredMessage);
0 ignored issues
show
Documentation Bug introduced by
The property $structuredMessage was declared of type integer, but preg_replace($pattern, $...ce, $structuredMessage) is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
72
73 24
        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 24
    private function mod($dividend)
86
    {
87 24
        $modulus = $dividend % self::MODULO;
88
89 24
        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 3
    public function getNumber()
98
    {
99 3
        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 24
    public function setNumber($number = null)
112
    {
113
        try {
114 24
            if (is_null($number)) {
115 15
                if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
116
                    $this->number = random_int(1, 9999999999);
117
                } else {
118 15
                    $this->number = mt_rand(1, 9999999999);
119
                }
120 15
            } else {
121 21
                if (($number < 1) || ($number > 9999999999)) {
122 9
                    throw new \InvalidArgumentException(
123
                        'The number should be an integer larger then 0 and smaller then 9999999999.'
124 9
                    );
125
                }
126
127 12
                $this->number = $number;
128
            }
129 24
        } catch (\Exception $e) {
130 9
            throw new TransferMessageException('Failed to set number', null, $e);
131
        }
132 24
    }
133
134
    /**
135
     * Get the modulus
136
     *
137
     * @return int The modulus resulting from the modulo operation
138
     */
139 3
    public function getModulus()
140
    {
141 3
        return $this->modulus;
142
    }
143
144
    /**
145
     * Get the structured message
146
     *
147
     * @return string A valid formatted structured message
148
     */
149 3
    public function getStructuredMessage()
150
    {
151 3
        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 6
    public function setStructuredMessage($structuredMessage)
162
    {
163
        try {
164 6
            $pattern = '/^[\+\*]{3}[0-9]{3}[\/]?[0-9]{4}[\/]?[0-9]{5}[\+\*]{3}$/';
165 6
            if (preg_match($pattern, $structuredMessage) === 0) {
166 3
                throw new \InvalidArgumentException('The structured message does not have a valid format.');
167
            } else {
168 3
                $this->structuredMessage = $structuredMessage;
0 ignored issues
show
Documentation Bug introduced by
The property $structuredMessage was declared of type integer, but $structuredMessage is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
169
            }
170 6
        } catch (\Exception $e) {
171 3
            throw new TransferMessageException('Failed to validate the format of the structured message', null, $e);
172
        }
173 3
    }
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 3
    public function validate()
184
    {
185 3
        $pattern = ['/^[\+\*]{3}([0-9]{3})[\/]?([0-9]{4})[\/]?([0-9]{5})[\+\*]{3}$/'];
186 3
        $replace = ['${1}${2}${3}'];
187 3
        $rawStructuredMessage = preg_replace($pattern, $replace, $this->structuredMessage);
188
189 3
        $number = substr($rawStructuredMessage, 0, 10);
190 3
        $modulus = substr($rawStructuredMessage, 10, 2);
191
192 3
        return ($modulus == $this->mod($number)) ? true : false;
193
    }
194
}
195