Completed
Pull Request — master (#4)
by Marcin
01:47
created
src/Builder.php 1 patch
Indentation   +454 added lines, -454 removed lines patch added patch discarded remove patch
@@ -19,458 +19,458 @@
 block discarded – undo
19 19
 
20 20
 class Builder
21 21
 {
22
-	/** @var int */
23
-	const TYPE_COMPANY = 1;
24
-
25
-	/** @var int */
26
-	const TYPE_PERSON = 2;
27
-
28
-	/** @var string */
29
-	protected $separator = '|';
30
-
31
-	/** @var int Maks. allowed length of result string */
32
-	const MAX_LEN = 160;
33
-
34
-
35
-	/**
36
-	 * Builder constructor.
37
-	 *
38
-	 * @param int  $recipient_type
39
-	 * @param bool $strict_mode
40
-	 */
41
-	public function __construct($recipient_type = self::TYPE_PERSON, $strict_mode = false)
42
-	{
43
-		if ($recipient_type !== self::TYPE_COMPANY && $recipient_type !== self::TYPE_PERSON) {
44
-			throw new RuntimeException('Invalid recipient type specified.');
45
-		}
46
-
47
-		$this->recipient_type = $recipient_type;
48
-		$this->strictMode($strict_mode);
49
-	}
50
-
51
-	/** @var bool */
52
-	protected $strict_mode = false;
53
-
54
-	/**
55
-	 * Controls strict mode. When mode is disabled (default) some methods may trim down string arguments
56
-	 * exceeding max allowed length. With strict mode on, such case would throw InvalidArgumentException.
57
-	 *
58
-	 * @param bool $mode Set to @true to enable strict mode, @false (default) otherwise.
59
-	 */
60
-	public function strictMode($mode)
61
-	{
62
-		if (!is_bool($mode)) {
63
-			throw new InvalidArgumentException('Mode argument must be a boolean.');
64
-		}
65
-
66
-		$this->strict_mode = (bool)$mode;
67
-	}
68
-
69
-	/** @var int */
70
-	protected $recipient_type = self::TYPE_PERSON;
71
-
72
-	/** @var string VAT ID (10 chars). required for TYPE_COMPANY (VAT ID), optional otherwise, digits */
73
-	protected $vat_id = '';
74
-
75
-	/**
76
-	 * Sets recipient Vat ID
77
-	 *
78
-	 * @param string|int|null $vat_id
79
-	 *
80
-	 * @return $this
81
-	 */
82
-	public function vatId($vat_id)
83
-	{
84
-		$this->vat_id = $this->validateVatId($vat_id);
85
-
86
-		return $this;
87
-	}
88
-
89
-	/**
90
-	 * @param string|int|null $vat_id
91
-	 *
92
-	 * @return string
93
-	 *
94
-	 * @throws \InvalidArgumentException
95
-	 * @throws \RuntimeException
96
-	 */
97
-	protected function validateVatId($vat_id)
98
-	{
99
-		if (is_string($vat_id)) {
100
-			$vat_id = trim(str_replace('-', '', $vat_id));
101
-		} elseif ($vat_id === null) {
102
-			$vat_id = '';
103
-		} elseif (is_int($vat_id)) {
104
-			$vat_id = sprintf('%010d', $vat_id);
105
-		} else {
106
-			throw new InvalidArgumentException('VatId can either be a string, int or null.');
107
-		}
108
-
109
-		if ($vat_id !== '') {
110
-			if (preg_match('/^\d{10}$/', $vat_id) !== 1) {
111
-				throw new InvalidArgumentException("Invalid VAT ID set. Must be contain 10 chars, digits only. '{$vat_id}' provided.");
112
-			}
113
-		}
114
-
115
-		if ($this->recipient_type === self::TYPE_COMPANY && $vat_id === '') {
116
-			throw new RuntimeException('Company recipient must have VAT ID set.');
117
-		}
118
-
119
-		return $vat_id;
120
-	}
121
-
122
-	/** @var string Recipient bank account number (26 digits), mandatory */
123
-	protected $bank_account = '';
124
-
125
-	/**
126
-	 * Sets mandatory recipient routing bank account number. Account number must contain 26 digits.
127
-	 * Digits can be grouped and separated by spaces however all spaces will be removed.
128
-	 *
129
-	 * @param string $account Recipient bank account number (26 digits)
130
-	 *
131
-	 * @return $this
132
-	 */
133
-	public function bankAccount($account)
134
-	{
135
-		$this->bank_account = $this->validateBankAccount($account);
136
-
137
-		return $this;
138
-	}
139
-
140
-	/**
141
-	 * @param string $account
142
-	 *
143
-	 * @return string
144
-	 *
145
-	 * @throws \InvalidArgumentException
146
-	 */
147
-	protected function validateBankAccount($account)
148
-	{
149
-		if (!is_string($account)) {
150
-			throw new InvalidArgumentException('Bank account number must be a string.');
151
-		}
152
-		$account = str_replace(' ', '', $account);
153
-
154
-		if (preg_match('/^\d{26}$/', $account) !== 1) {
155
-			throw new InvalidArgumentException("Bank account number must be 26 chars long, digits only. '{$account}' provided.");
156
-		}
157
-
158
-		return $account;
159
-	}
160
-
161
-	/** @var string 20 chars max, recipient name, mandatory */
162
-	protected $recipient_name = '';
163
-
164
-	/** @var int */
165
-	const NAME_MAX_LEN = 20;
166
-
167
-	/**
168
-	 * Sets recipient name. Up to 20 chars (longer strings are allowed and will be trimmed).
169
-	 *
170
-	 * @param string $name recipient name
171
-	 *
172
-	 * @return $this
173
-	 */
174
-	public function name($name)
175
-	{
176
-		$this->recipient_name = $this->validateName($name);
177
-
178
-		return $this;
179
-	}
180
-
181
-	/**
182
-	 * @param string $name
183
-	 *
184
-	 * @return string
185
-	 *
186
-	 * @throws \InvalidArgumentException
187
-	 * @throws \RuntimeException
188
-	 */
189
-	protected function validateName($name)
190
-	{
191
-		if (!is_string($name)) {
192
-			throw new InvalidArgumentException('Recipient name must be a string.');
193
-		}
194
-
195
-		if ($this->strict_mode && mb_strlen($name) > self::NAME_MAX_LEN) {
196
-			throw new InvalidArgumentException(sprintf('Recipient name must not exceed %d chars.', self::NAME_MAX_LEN));
197
-		}
198
-
199
-		$name = mb_substr(trim($name), 0, self::NAME_MAX_LEN);
200
-
201
-		if ($name === '') {
202
-			throw new RuntimeException('Recipient name cannot be empty.');
203
-		}
204
-
205
-		return $name;
206
-	}
207
-
208
-	/** @var string 2 chars, country code (i.e. 'PL'), optional, letters */
209
-	protected $country_code = '';
210
-
211
-	/**
212
-	 * @param string|null $country_code 2 chars, country code (i.e. 'PL'), optional, letters
213
-	 *
214
-	 * @return $this
215
-	 *
216
-	 * @throws \InvalidArgumentException
217
-	 */
218
-	public function country($country_code)
219
-	{
220
-		if ($country_code === null) {
221
-			$country_code = '';
222
-		}
223
-
224
-		if (!is_string($country_code)) {
225
-			throw new InvalidArgumentException('Country code must be a string.');
226
-		}
227
-
228
-		$country_code = mb_strtoupper($country_code);
229
-		if ($country_code !== '') {
230
-			if (preg_match('/^[A-Z]{2}$/', $country_code) !== 1) {
231
-				throw new InvalidArgumentException("Country code must be a 2 character long, letters only. '{$country_code}' provided.");
232
-			}
233
-		}
234
-
235
-		$this->country_code = strtoupper($country_code);
236
-
237
-		return $this;
238
-	}
239
-
240
-	/** @var string */
241
-	protected $payment_title = '';
242
-
243
-	/** @var int */
244
-	const TITLE_MAX_LEN = 32;
245
-
246
-	/**
247
-	 * @param string $title 32 chars, payment title, mandatory, letters+digits
248
-	 *
249
-	 * @return $this
250
-	 */
251
-	public function title($title)
252
-	{
253
-		$this->payment_title = $this->validateTitle($title);
254
-
255
-		return $this;
256
-	}
257
-
258
-	/**
259
-	 * @param string $title
260
-	 *
261
-	 * @return string
262
-	 *
263
-	 * @throws \InvalidArgumentException
264
-	 */
265
-	protected function validateTitle($title)
266
-	{
267
-		if (!is_string($title)) {
268
-			throw new InvalidArgumentException('Payment title must be a string.');
269
-		}
270
-
271
-		if ($this->strict_mode && mb_strlen($title) > self::TITLE_MAX_LEN) {
272
-			throw new InvalidArgumentException(sprintf('Payment title must not exceed %d chars.', self::TITLE_MAX_LEN));
273
-		}
274
-
275
-		if ($title === '') {
276
-			throw new RuntimeException('Payment title cannot be empty.');
277
-		}
278
-
279
-		return mb_substr(trim($title), 0, self::TITLE_MAX_LEN);
280
-	}
281
-
282
-	/** @var int|null */
283
-	protected $amount = null;
284
-
285
-	/**
286
-	 * @param float|int $amount 6 chars, amount in Polish grosz, digits, mandatory
287
-	 *
288
-	 * @return $this
289
-	 */
290
-	public function amount($amount)
291
-	{
292
-		$this->amount = $this->validateAmount($amount);
293
-
294
-		return $this;
295
-	}
296
-
297
-	/**
298
-	 * @param float|int $amount
299
-	 *
300
-	 * @return int
301
-	 *
302
-	 * @throws \OutOfRangeException
303
-	 * @throws \InvalidArgumentException
304
-	 * @throws \RuntimeException
305
-	 */
306
-	protected function validateAmount($amount)
307
-	{
308
-		if ($amount === null) {
309
-			throw new RuntimeException('Amount not specified.');
310
-		}
311
-
312
-		if (is_float($amount)) {
313
-			$amount = (int)($amount * 100);
314
-		} elseif (!is_int($amount)) {
315
-			throw new InvalidArgumentException('Amount must be either float or int');
316
-		}
317
-
318
-		if ($amount < 0) {
319
-			throw new OutOfRangeException('Amount cannot be negative.');
320
-		}
321
-
322
-		if ($amount > 999999) {
323
-			throw new OutOfRangeException('Amount representation cannot exceed 6 digits. Current value: {$amount}');
324
-		}
325
-
326
-		return $amount;
327
-	}
328
-
329
-	/** @var string */
330
-	protected $reserved1 = '';
331
-
332
-	/** @var int */
333
-	const RESERVED1_MAX_LEN = 20;
334
-
335
-	/**
336
-	 * @param string|null $id 20 chars, reserved i.e. for payment reference id, optional, digits (but we use letters+digits as some banks do too)
337
-	 *
338
-	 * @return $this
339
-	 *
340
-	 * @throws \InvalidArgumentException
341
-	 */
342
-	public function reserved1($id)
343
-	{
344
-		if ($id === null) {
345
-			$id = '';
346
-		}
347
-
348
-		if (!is_string($id)) {
349
-			throw new InvalidArgumentException('Reserved1/RefId value must be a string.');
350
-		}
351
-
352
-		if (mb_strlen($id) > self::RESERVED1_MAX_LEN) {
353
-			throw new InvalidArgumentException(sprintf('Maksymalna długość wartości Reserved1/RefId to %d znaków.', self::RESERVED1_MAX_LEN));
354
-		}
355
-
356
-		$this->reserved1 = $id;
357
-
358
-		return $this;
359
-	}
360
-
361
-	/**
362
-	 * Alias for reserved1()
363
-	 *
364
-	 * @param string|null $id
365
-	 *
366
-	 * @return $this
367
-	 */
368
-	public function refId($id)
369
-	{
370
-		return $this->reserved1($id);
371
-	}
372
-
373
-	/** @var string */
374
-	protected $reserved2 = '';
375
-
376
-	/** @var int */
377
-	const RESERVED2_MAX_LEN = 12;
378
-
379
-	/**
380
-	 * 12 chars, reserved i.e. for Invobill reference id, optional, digits (but we allow letters+digits as some banks do too)
381
-	 *
382
-	 * @param string|null $id
383
-	 *
384
-	 * @return $this
385
-	 *
386
-	 * @throws \InvalidArgumentException
387
-	 */
388
-	public function reserved2($id)
389
-	{
390
-		if ($id === null) {
391
-			$id = '';
392
-		}
393
-
394
-		if (!is_string($id)) {
395
-			throw new InvalidArgumentException('Reserved2 value must be a string.');
396
-		}
397
-
398
-		if (mb_strlen($id) > self::RESERVED2_MAX_LEN) {
399
-			throw new InvalidArgumentException(sprintf('Maksymalna długość wartości Reserved2 to %d znaków.', self::RESERVED2_MAX_LEN));
400
-		}
401
-
402
-		$this->reserved2 = $id;
403
-
404
-		return $this;
405
-	}
406
-
407
-	/** @var string */
408
-	protected $reserved3 = '';
409
-
410
-	/** @var int */
411
-	const RESERVED3_MAX_LEN = 24;
412
-
413
-	/**
414
-	 * 24 chars, reserved, optional, letters+digits
415
-	 *
416
-	 * @param string|null $id
417
-	 *
418
-	 * @return $this
419
-	 *
420
-	 * @throws \InvalidArgumentException
421
-	 */
422
-	public function reserved3($id)
423
-	{
424
-		if ($id === null) {
425
-			$id = '';
426
-		}
427
-
428
-		if (!is_string($id)) {
429
-			throw new InvalidArgumentException('Reserved3 value must be a string.');
430
-		}
431
-
432
-		if (mb_strlen($id) > self::RESERVED3_MAX_LEN) {
433
-			throw new InvalidArgumentException(sprintf('Maksymalna długość wartości Reserved3 to %d znaków.', self::RESERVED3_MAX_LEN));
434
-		}
435
-
436
-		$this->reserved3 = $id;
437
-
438
-		return $this;
439
-	}
440
-
441
-	/**
442
-	 * @return string
443
-	 *
444
-	 * @throws \RuntimeException
445
-	 */
446
-	public function build()
447
-	{
448
-		// validate
449
-		$this->validateBankAccount($this->bank_account);
450
-		$this->validateName($this->recipient_name);
451
-		$this->validateVatId($this->vat_id);
452
-		$this->validateTitle($this->payment_title);
453
-		$this->validateAmount($this->amount);
454
-
455
-		// build
456
-		$fields = [
457
-			$this->vat_id,
458
-			$this->country_code,
459
-			$this->bank_account,
460
-			sprintf('%06d', $this->amount),
461
-			$this->recipient_name,
462
-			$this->payment_title,
463
-			$this->reserved1,
464
-			$this->reserved2,
465
-			$this->reserved3,
466
-		];
467
-
468
-		$result = implode($this->separator, $fields);
469
-		if (mb_strlen($result) > self::MAX_LEN) {
470
-			throw new RuntimeException(
471
-				sprintf('Oops, this should not happen! Result string is %d chars long (max allowed %d). Please report this!', mb_strlen($result), self::MAX_LEN));
472
-		}
473
-
474
-		return $result;
475
-	}
22
+    /** @var int */
23
+    const TYPE_COMPANY = 1;
24
+
25
+    /** @var int */
26
+    const TYPE_PERSON = 2;
27
+
28
+    /** @var string */
29
+    protected $separator = '|';
30
+
31
+    /** @var int Maks. allowed length of result string */
32
+    const MAX_LEN = 160;
33
+
34
+
35
+    /**
36
+     * Builder constructor.
37
+     *
38
+     * @param int  $recipient_type
39
+     * @param bool $strict_mode
40
+     */
41
+    public function __construct($recipient_type = self::TYPE_PERSON, $strict_mode = false)
42
+    {
43
+        if ($recipient_type !== self::TYPE_COMPANY && $recipient_type !== self::TYPE_PERSON) {
44
+            throw new RuntimeException('Invalid recipient type specified.');
45
+        }
46
+
47
+        $this->recipient_type = $recipient_type;
48
+        $this->strictMode($strict_mode);
49
+    }
50
+
51
+    /** @var bool */
52
+    protected $strict_mode = false;
53
+
54
+    /**
55
+     * Controls strict mode. When mode is disabled (default) some methods may trim down string arguments
56
+     * exceeding max allowed length. With strict mode on, such case would throw InvalidArgumentException.
57
+     *
58
+     * @param bool $mode Set to @true to enable strict mode, @false (default) otherwise.
59
+     */
60
+    public function strictMode($mode)
61
+    {
62
+        if (!is_bool($mode)) {
63
+            throw new InvalidArgumentException('Mode argument must be a boolean.');
64
+        }
65
+
66
+        $this->strict_mode = (bool)$mode;
67
+    }
68
+
69
+    /** @var int */
70
+    protected $recipient_type = self::TYPE_PERSON;
71
+
72
+    /** @var string VAT ID (10 chars). required for TYPE_COMPANY (VAT ID), optional otherwise, digits */
73
+    protected $vat_id = '';
74
+
75
+    /**
76
+     * Sets recipient Vat ID
77
+     *
78
+     * @param string|int|null $vat_id
79
+     *
80
+     * @return $this
81
+     */
82
+    public function vatId($vat_id)
83
+    {
84
+        $this->vat_id = $this->validateVatId($vat_id);
85
+
86
+        return $this;
87
+    }
88
+
89
+    /**
90
+     * @param string|int|null $vat_id
91
+     *
92
+     * @return string
93
+     *
94
+     * @throws \InvalidArgumentException
95
+     * @throws \RuntimeException
96
+     */
97
+    protected function validateVatId($vat_id)
98
+    {
99
+        if (is_string($vat_id)) {
100
+            $vat_id = trim(str_replace('-', '', $vat_id));
101
+        } elseif ($vat_id === null) {
102
+            $vat_id = '';
103
+        } elseif (is_int($vat_id)) {
104
+            $vat_id = sprintf('%010d', $vat_id);
105
+        } else {
106
+            throw new InvalidArgumentException('VatId can either be a string, int or null.');
107
+        }
108
+
109
+        if ($vat_id !== '') {
110
+            if (preg_match('/^\d{10}$/', $vat_id) !== 1) {
111
+                throw new InvalidArgumentException("Invalid VAT ID set. Must be contain 10 chars, digits only. '{$vat_id}' provided.");
112
+            }
113
+        }
114
+
115
+        if ($this->recipient_type === self::TYPE_COMPANY && $vat_id === '') {
116
+            throw new RuntimeException('Company recipient must have VAT ID set.');
117
+        }
118
+
119
+        return $vat_id;
120
+    }
121
+
122
+    /** @var string Recipient bank account number (26 digits), mandatory */
123
+    protected $bank_account = '';
124
+
125
+    /**
126
+     * Sets mandatory recipient routing bank account number. Account number must contain 26 digits.
127
+     * Digits can be grouped and separated by spaces however all spaces will be removed.
128
+     *
129
+     * @param string $account Recipient bank account number (26 digits)
130
+     *
131
+     * @return $this
132
+     */
133
+    public function bankAccount($account)
134
+    {
135
+        $this->bank_account = $this->validateBankAccount($account);
136
+
137
+        return $this;
138
+    }
139
+
140
+    /**
141
+     * @param string $account
142
+     *
143
+     * @return string
144
+     *
145
+     * @throws \InvalidArgumentException
146
+     */
147
+    protected function validateBankAccount($account)
148
+    {
149
+        if (!is_string($account)) {
150
+            throw new InvalidArgumentException('Bank account number must be a string.');
151
+        }
152
+        $account = str_replace(' ', '', $account);
153
+
154
+        if (preg_match('/^\d{26}$/', $account) !== 1) {
155
+            throw new InvalidArgumentException("Bank account number must be 26 chars long, digits only. '{$account}' provided.");
156
+        }
157
+
158
+        return $account;
159
+    }
160
+
161
+    /** @var string 20 chars max, recipient name, mandatory */
162
+    protected $recipient_name = '';
163
+
164
+    /** @var int */
165
+    const NAME_MAX_LEN = 20;
166
+
167
+    /**
168
+     * Sets recipient name. Up to 20 chars (longer strings are allowed and will be trimmed).
169
+     *
170
+     * @param string $name recipient name
171
+     *
172
+     * @return $this
173
+     */
174
+    public function name($name)
175
+    {
176
+        $this->recipient_name = $this->validateName($name);
177
+
178
+        return $this;
179
+    }
180
+
181
+    /**
182
+     * @param string $name
183
+     *
184
+     * @return string
185
+     *
186
+     * @throws \InvalidArgumentException
187
+     * @throws \RuntimeException
188
+     */
189
+    protected function validateName($name)
190
+    {
191
+        if (!is_string($name)) {
192
+            throw new InvalidArgumentException('Recipient name must be a string.');
193
+        }
194
+
195
+        if ($this->strict_mode && mb_strlen($name) > self::NAME_MAX_LEN) {
196
+            throw new InvalidArgumentException(sprintf('Recipient name must not exceed %d chars.', self::NAME_MAX_LEN));
197
+        }
198
+
199
+        $name = mb_substr(trim($name), 0, self::NAME_MAX_LEN);
200
+
201
+        if ($name === '') {
202
+            throw new RuntimeException('Recipient name cannot be empty.');
203
+        }
204
+
205
+        return $name;
206
+    }
207
+
208
+    /** @var string 2 chars, country code (i.e. 'PL'), optional, letters */
209
+    protected $country_code = '';
210
+
211
+    /**
212
+     * @param string|null $country_code 2 chars, country code (i.e. 'PL'), optional, letters
213
+     *
214
+     * @return $this
215
+     *
216
+     * @throws \InvalidArgumentException
217
+     */
218
+    public function country($country_code)
219
+    {
220
+        if ($country_code === null) {
221
+            $country_code = '';
222
+        }
223
+
224
+        if (!is_string($country_code)) {
225
+            throw new InvalidArgumentException('Country code must be a string.');
226
+        }
227
+
228
+        $country_code = mb_strtoupper($country_code);
229
+        if ($country_code !== '') {
230
+            if (preg_match('/^[A-Z]{2}$/', $country_code) !== 1) {
231
+                throw new InvalidArgumentException("Country code must be a 2 character long, letters only. '{$country_code}' provided.");
232
+            }
233
+        }
234
+
235
+        $this->country_code = strtoupper($country_code);
236
+
237
+        return $this;
238
+    }
239
+
240
+    /** @var string */
241
+    protected $payment_title = '';
242
+
243
+    /** @var int */
244
+    const TITLE_MAX_LEN = 32;
245
+
246
+    /**
247
+     * @param string $title 32 chars, payment title, mandatory, letters+digits
248
+     *
249
+     * @return $this
250
+     */
251
+    public function title($title)
252
+    {
253
+        $this->payment_title = $this->validateTitle($title);
254
+
255
+        return $this;
256
+    }
257
+
258
+    /**
259
+     * @param string $title
260
+     *
261
+     * @return string
262
+     *
263
+     * @throws \InvalidArgumentException
264
+     */
265
+    protected function validateTitle($title)
266
+    {
267
+        if (!is_string($title)) {
268
+            throw new InvalidArgumentException('Payment title must be a string.');
269
+        }
270
+
271
+        if ($this->strict_mode && mb_strlen($title) > self::TITLE_MAX_LEN) {
272
+            throw new InvalidArgumentException(sprintf('Payment title must not exceed %d chars.', self::TITLE_MAX_LEN));
273
+        }
274
+
275
+        if ($title === '') {
276
+            throw new RuntimeException('Payment title cannot be empty.');
277
+        }
278
+
279
+        return mb_substr(trim($title), 0, self::TITLE_MAX_LEN);
280
+    }
281
+
282
+    /** @var int|null */
283
+    protected $amount = null;
284
+
285
+    /**
286
+     * @param float|int $amount 6 chars, amount in Polish grosz, digits, mandatory
287
+     *
288
+     * @return $this
289
+     */
290
+    public function amount($amount)
291
+    {
292
+        $this->amount = $this->validateAmount($amount);
293
+
294
+        return $this;
295
+    }
296
+
297
+    /**
298
+     * @param float|int $amount
299
+     *
300
+     * @return int
301
+     *
302
+     * @throws \OutOfRangeException
303
+     * @throws \InvalidArgumentException
304
+     * @throws \RuntimeException
305
+     */
306
+    protected function validateAmount($amount)
307
+    {
308
+        if ($amount === null) {
309
+            throw new RuntimeException('Amount not specified.');
310
+        }
311
+
312
+        if (is_float($amount)) {
313
+            $amount = (int)($amount * 100);
314
+        } elseif (!is_int($amount)) {
315
+            throw new InvalidArgumentException('Amount must be either float or int');
316
+        }
317
+
318
+        if ($amount < 0) {
319
+            throw new OutOfRangeException('Amount cannot be negative.');
320
+        }
321
+
322
+        if ($amount > 999999) {
323
+            throw new OutOfRangeException('Amount representation cannot exceed 6 digits. Current value: {$amount}');
324
+        }
325
+
326
+        return $amount;
327
+    }
328
+
329
+    /** @var string */
330
+    protected $reserved1 = '';
331
+
332
+    /** @var int */
333
+    const RESERVED1_MAX_LEN = 20;
334
+
335
+    /**
336
+     * @param string|null $id 20 chars, reserved i.e. for payment reference id, optional, digits (but we use letters+digits as some banks do too)
337
+     *
338
+     * @return $this
339
+     *
340
+     * @throws \InvalidArgumentException
341
+     */
342
+    public function reserved1($id)
343
+    {
344
+        if ($id === null) {
345
+            $id = '';
346
+        }
347
+
348
+        if (!is_string($id)) {
349
+            throw new InvalidArgumentException('Reserved1/RefId value must be a string.');
350
+        }
351
+
352
+        if (mb_strlen($id) > self::RESERVED1_MAX_LEN) {
353
+            throw new InvalidArgumentException(sprintf('Maksymalna długość wartości Reserved1/RefId to %d znaków.', self::RESERVED1_MAX_LEN));
354
+        }
355
+
356
+        $this->reserved1 = $id;
357
+
358
+        return $this;
359
+    }
360
+
361
+    /**
362
+     * Alias for reserved1()
363
+     *
364
+     * @param string|null $id
365
+     *
366
+     * @return $this
367
+     */
368
+    public function refId($id)
369
+    {
370
+        return $this->reserved1($id);
371
+    }
372
+
373
+    /** @var string */
374
+    protected $reserved2 = '';
375
+
376
+    /** @var int */
377
+    const RESERVED2_MAX_LEN = 12;
378
+
379
+    /**
380
+     * 12 chars, reserved i.e. for Invobill reference id, optional, digits (but we allow letters+digits as some banks do too)
381
+     *
382
+     * @param string|null $id
383
+     *
384
+     * @return $this
385
+     *
386
+     * @throws \InvalidArgumentException
387
+     */
388
+    public function reserved2($id)
389
+    {
390
+        if ($id === null) {
391
+            $id = '';
392
+        }
393
+
394
+        if (!is_string($id)) {
395
+            throw new InvalidArgumentException('Reserved2 value must be a string.');
396
+        }
397
+
398
+        if (mb_strlen($id) > self::RESERVED2_MAX_LEN) {
399
+            throw new InvalidArgumentException(sprintf('Maksymalna długość wartości Reserved2 to %d znaków.', self::RESERVED2_MAX_LEN));
400
+        }
401
+
402
+        $this->reserved2 = $id;
403
+
404
+        return $this;
405
+    }
406
+
407
+    /** @var string */
408
+    protected $reserved3 = '';
409
+
410
+    /** @var int */
411
+    const RESERVED3_MAX_LEN = 24;
412
+
413
+    /**
414
+     * 24 chars, reserved, optional, letters+digits
415
+     *
416
+     * @param string|null $id
417
+     *
418
+     * @return $this
419
+     *
420
+     * @throws \InvalidArgumentException
421
+     */
422
+    public function reserved3($id)
423
+    {
424
+        if ($id === null) {
425
+            $id = '';
426
+        }
427
+
428
+        if (!is_string($id)) {
429
+            throw new InvalidArgumentException('Reserved3 value must be a string.');
430
+        }
431
+
432
+        if (mb_strlen($id) > self::RESERVED3_MAX_LEN) {
433
+            throw new InvalidArgumentException(sprintf('Maksymalna długość wartości Reserved3 to %d znaków.', self::RESERVED3_MAX_LEN));
434
+        }
435
+
436
+        $this->reserved3 = $id;
437
+
438
+        return $this;
439
+    }
440
+
441
+    /**
442
+     * @return string
443
+     *
444
+     * @throws \RuntimeException
445
+     */
446
+    public function build()
447
+    {
448
+        // validate
449
+        $this->validateBankAccount($this->bank_account);
450
+        $this->validateName($this->recipient_name);
451
+        $this->validateVatId($this->vat_id);
452
+        $this->validateTitle($this->payment_title);
453
+        $this->validateAmount($this->amount);
454
+
455
+        // build
456
+        $fields = [
457
+            $this->vat_id,
458
+            $this->country_code,
459
+            $this->bank_account,
460
+            sprintf('%06d', $this->amount),
461
+            $this->recipient_name,
462
+            $this->payment_title,
463
+            $this->reserved1,
464
+            $this->reserved2,
465
+            $this->reserved3,
466
+        ];
467
+
468
+        $result = implode($this->separator, $fields);
469
+        if (mb_strlen($result) > self::MAX_LEN) {
470
+            throw new RuntimeException(
471
+                sprintf('Oops, this should not happen! Result string is %d chars long (max allowed %d). Please report this!', mb_strlen($result), self::MAX_LEN));
472
+        }
473
+
474
+        return $result;
475
+    }
476 476
 }
Please login to merge, or discard this patch.