Failed Conditions
Push — develop ( 56d41b...7b2b60 )
by Reüel
04:15
created

Client::get_cancel_url()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Pronamic\WordPress\Pay\Gateways\IDealBasic;
4
5
use InvalidArgumentException;
6
use DateTime;
7
use DateTimeZone;
8
use Pronamic\WordPress\Money\Money;
9
use Pronamic\WordPress\Pay\Plugin;
10
11
/**
12
 * Title: iDEAL Basic client
13
 * Description:
14
 * Copyright: 2005-2020 Pronamic
15
 * Company: Pronamic
16
 *
17
 * @author  Remco Tolsma
18
 * @version 2.0.0
19
 * @since   1.0.0
20
 */
21
class Client {
22
	/**
23
	 * An payment type indicator for iDEAL
24
	 *
25
	 * @var string
26
	 */
27
	const PAYMENT_TYPE_IDEAL = 'ideal';
28
29
	/**
30
	 * The expire date format (yyyy-MMddTHH:mm:ss.SSSZ)
31
	 * The Z stands for the time zone (CET).
32
	 *
33
	 * @var string
34
	 */
35
	const DATE_EXPIRE_FORMAT = 'Y-m-d\TH:i:s.000\Z';
36
37
	/**
38
	 * The default expire date modifier
39
	 *
40
	 * @var string
41
	 */
42
	const EXPIRE_DATE_MODIFIER = '+30 minutes';
43
44
	/**
45
	 * Forbidden characters
46
	 *
47
	 * @doc Manual iDEAL Lite.pdf (4.2 Explanation of the hash code)
48
	 * @var string
49
	 */
50
	const FORBIDDEN_CHARACHTERS = "\t\n\r ";
51
52
	/**
53
	 * The URL for testing
54
	 *
55
	 * @var string
56
	 */
57
	private $payment_server_url;
58
59
	/**
60
	 * The mercahnt ID
61
	 *
62
	 * @var string
63
	 */
64
	private $merchant_id;
65
66
	/**
67
	 * The sub ID
68
	 *
69
	 * @var string
70
	 */
71
	private $sub_id;
72
73
	/**
74
	 * The hash key
75
	 *
76
	 * @var string
77
	 */
78
	private $hash_key;
79
80
	/**
81
	 * The purchase ID
82
	 *
83
	 * @var string
84
	 */
85
	private $purchase_id;
86
87
	/**
88
	 * The language
89
	 *
90
	 * @var string
91
	 */
92
	private $language;
93
94
	/**
95
	 * Description
96
	 *
97
	 * @var string
98
	 */
99
	private $description;
100
101
	/**
102
	 * The currency
103
	 *
104
	 * @var string
105
	 */
106
	private $currency;
107
108
	/**
109
	 * Payment method
110
	 *
111
	 * @var string
112
	 */
113
	private $payment_type;
114
115
	/**
116
	 * The expire date
117
	 *
118
	 * @var DateTime
119
	 */
120
	private $expire_date;
121
122
	/**
123
	 * The expire date format
124
	 *
125
	 * @var string
126
	 */
127
	private $expire_date_format;
128
129
	/**
130
	 * The expire date modifier
131
	 *
132
	 * @var string
133
	 */
134
	private $expire_date_modifier;
135
136
	/**
137
	 * The forbidden charachters
138
	 *
139
	 * @var string
140
	 */
141
	private $forbidden_characters;
142
143
	/**
144
	 * The items
145
	 *
146
	 * @var Items
147
	 */
148
	private $items;
149
150
	/**
151
	 * The consumer is automatically directed to this URL after a successful payment.
152
	 *
153
	 * @var string
154
	 */
155
	private $success_url;
156
157
	/**
158
	 * The consumer is automatically directed to this URL after the transaction has been cancelled.
159
	 *
160
	 * @var string
161
	 */
162
	private $cancel_url;
163
164
	/**
165
	 * The consumer is directed to this URL if an error has occurred.
166
	 *
167
	 * @var string
168
	 */
169
	private $error_url;
170
171
	/**
172
	 * Constructs and initialize a iDEAL basic object
173
	 */
174 2
	public function __construct() {
175 2
		$this->items = new Items();
176
177 2
		$this->forbidden_characters = array();
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type string of property $forbidden_characters.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
178
179 2
		$this->set_payment_type( self::PAYMENT_TYPE_IDEAL );
180 2
		$this->set_expire_date_format( self::DATE_EXPIRE_FORMAT );
181 2
		$this->set_expire_date_modifier( self::EXPIRE_DATE_MODIFIER );
182 2
		$this->set_forbidden_characters( self::FORBIDDEN_CHARACHTERS );
183 2
	}
184
185
	/**
186
	 * Get the payment server URL
187
	 *
188
	 * @return string
189
	 */
190
	public function get_payment_server_url() {
191
		return $this->payment_server_url;
192
	}
193
194
	/**
195
	 * Set the payment server URL
196
	 *
197
	 * @param string $url Payment server URL.
198
	 */
199
	public function set_payment_server_url( $url ) {
200
		$this->payment_server_url = $url;
201
	}
202
203
	/**
204
	 * Get the merchant ID.
205
	 *
206
	 * @return string
207
	 */
208 1
	public function get_merchant_id() {
209 1
		return $this->merchant_id;
210
	}
211
212
	/**
213
	 * Set the merchant ID.
214
	 *
215
	 * @param string $merchant_id Merchant ID.
216
	 */
217 1
	public function set_merchant_id( $merchant_id ) {
218 1
		$this->merchant_id = $merchant_id;
219 1
	}
220
221
	/**
222
	 * Get the sub id
223
	 *
224
	 * @return string Sub id
225
	 */
226 1
	public function get_sub_id() {
227 1
		return $this->sub_id;
228
	}
229
230
	/**
231
	 * Set the sub id
232
	 *
233
	 * @param string $sub_id Sub ID.
234
	 */
235 1
	public function set_sub_id( $sub_id ) {
236 1
		$this->sub_id = $sub_id;
237 1
	}
238
239
	/**
240
	 * Get the hash key
241
	 *
242
	 * @return string Hash key
243
	 */
244 1
	public function get_hash_key() {
245 1
		return $this->hash_key;
246
	}
247
248
	/**
249
	 * Set the hash key
250
	 * N..max50
251
	 *
252
	 * @param string $hash_key Hash key.
253
	 */
254 1
	public function set_hash_key( $hash_key ) {
255 1
		$this->hash_key = $hash_key;
256 1
	}
257
258
	/**
259
	 * Get the purchase id
260
	 *
261
	 * @return string Purchase id
262
	 */
263 1
	public function get_purchase_id() {
264 1
		return $this->purchase_id;
265
	}
266
267
	/**
268
	 * Set the purchase id
269
	 * AN..max16 (AN = Alphanumeric, free text)
270
	 *
271
	 * @param string $purchase_id Purchase ID.
272
	 */
273 1
	public function set_purchase_id( $purchase_id ) {
274 1
		$this->purchase_id = substr( $purchase_id, 0, 16 );
275 1
	}
276
277
	/**
278
	 * Get the language
279
	 *
280
	 * @return string Language
281
	 */
282
	public function get_language() {
283
		return $this->language;
284
	}
285
286
	/**
287
	 * Set the language
288
	 *
289
	 * @param string $language Language.
290
	 */
291 1
	public function set_language( $language ) {
292 1
		$this->language = $language;
293 1
	}
294
295
	/**
296
	 * Get the description
297
	 *
298
	 * @return string Description
299
	 */
300 1
	public function get_description() {
301 1
		return $this->description;
302
	}
303
304
	/**
305
	 * Set the description
306
	 * AN..max32 (AN = Alphanumeric, free text)
307
	 *
308
	 * @param string $description Description.
309
	 */
310 2
	public function set_description( $description ) {
311 2
		$this->description = DataHelper::an32( $description );
312 2
	}
313
314
	/**
315
	 * Get the currency
316
	 *
317
	 * @return string Currency
318
	 */
319
	public function get_currency() {
320
		return $this->currency;
321
	}
322
323
	/**
324
	 * Set the currency
325
	 *
326
	 * @param string $currency Currency.
327
	 */
328 1
	public function set_currency( $currency ) {
329 1
		$this->currency = $currency;
330 1
	}
331
332
	/**
333
	 * Get the payment type
334
	 *
335
	 * @return string Payment type
336
	 */
337 1
	public function get_payment_type() {
338 1
		return $this->payment_type;
339
	}
340
341
	/**
342
	 * Set the payment type
343
	 * AN..max10
344
	 *
345
	 * @param string $payment_type Payment type.
346
	 */
347 2
	public function set_payment_type( $payment_type ) {
348 2
		$this->payment_type = $payment_type;
349 2
	}
350
351
	/**
352
	 * Get the expire date
353
	 *
354
	 * @param boolean $create_new Indicator for creating a new expire date.
355
	 *
356
	 * @return DateTime
357
	 */
358 1
	public function get_expire_date( $create_new = false ) {
359 1
		if ( null === $this->expire_date || $create_new ) {
360
			$this->expire_date = new DateTime( null, new DateTimeZone( Plugin::TIMEZONE ) );
361
			$this->expire_date->modify( $this->expire_date_modifier );
362
		}
363
364 1
		return $this->expire_date;
365
	}
366
367
	/**
368
	 * Get the expire date format
369
	 *
370
	 * @return string the expire date format
371
	 */
372 1
	public function get_expire_date_format() {
373 1
		return $this->expire_date_format;
374
	}
375
376
	/**
377
	 * Set the expire date formnat
378
	 *
379
	 * @param string $expire_date_format Expire date format.
380
	 */
381 2
	public function set_expire_date_format( $expire_date_format ) {
382 2
		$this->expire_date_format = $expire_date_format;
383 2
	}
384
385
	/**
386
	 * Get the expire date modifier
387
	 *
388
	 * @return string Expire date modifier
389
	 */
390
	public function get_expire_date_modifier() {
391
		return $this->expire_date_modifier;
392
	}
393
394
	/**
395
	 * Set the expire date modifier
396
	 *
397
	 * @param string $expire_date_modifier Expire date modifier.
398
	 */
399 2
	public function set_expire_date_modifier( $expire_date_modifier ) {
400 2
		$this->expire_date_modifier = $expire_date_modifier;
401 2
	}
402
403
	/**
404
	 * Set the expire date
405
	 *
406
	 * @param DateTime $date Expire date.
407
	 */
408 1
	public function set_expire_date( DateTime $date ) {
409 1
		$this->expire_date = $date;
410 1
	}
411
412
	/**
413
	 * Get the forbidden characters
414
	 *
415
	 * @return array
416
	 */
417 1
	public function get_forbidden_characters() {
418 1
		return $this->forbidden_characters;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->forbidden_characters returns the type string which is incompatible with the documented return type array.
Loading history...
419
	}
420
421
	/**
422
	 * Set the forbidden characters
423
	 *
424
	 * @param mixed $characters Array or string with forbidden characters.
425
	 *
426
	 * @throws InvalidArgumentException Passed characters is not an array or string.
427
	 */
428 2
	public function set_forbidden_characters( $characters ) {
429 2
		if ( ! is_array( $characters ) && ! is_string( $characters ) ) {
430
			throw new InvalidArgumentException( 'Invalid characters argument.' );
431
		}
432
433 2
		if ( is_string( $characters ) ) {
434 2
			$characters = str_split( $characters );
435
		}
436
437 2
		$this->forbidden_characters = $characters;
0 ignored issues
show
Documentation Bug introduced by
It seems like $characters of type array is incompatible with the declared type string of property $forbidden_characters.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
438 2
	}
439
440
	/**
441
	 * Get the success URL
442
	 *
443
	 * @return string URL
444
	 */
445
	public function get_success_url() {
446
		return $this->success_url;
447
	}
448
449
	/**
450
	 * Set the success URL
451
	 *
452
	 * @param string $url Success URL.
453
	 */
454 1
	public function set_success_url( $url ) {
455 1
		$this->success_url = $url;
456 1
	}
457
458
	/**
459
	 * Get the cancel URL
460
	 *
461
	 * @return string Cancel URL
462
	 */
463
	public function get_cancel_url() {
464
		return $this->cancel_url;
465
	}
466
467
	/**
468
	 * Set the cancel URL
469
	 *
470
	 * @param string $url Cancel URL.
471
	 */
472 1
	public function set_cancel_url( $url ) {
473 1
		$this->cancel_url = $url;
474 1
	}
475
476
	/**
477
	 * Get the error URL
478
	 *
479
	 * @return string Error URL
480
	 */
481
	public function get_error_url() {
482
		return $this->error_url;
483
	}
484
485
	/**
486
	 * Set the error URL
487
	 *
488
	 * @param string $url Error URL.
489
	 */
490 1
	public function set_error_url( $url ) {
491 1
		$this->error_url = $url;
492 1
	}
493
494
	/**
495
	 * Get the items
496
	 *
497
	 * @return Items
498
	 */
499 1
	public function get_items() {
500 1
		return $this->items;
501
	}
502
503
	/**
504
	 * Set the items
505
	 *
506
	 * @param Items $items Items.
507
	 */
508
	public function set_items( Items $items ) {
509
		$this->items = $items;
510
	}
511
512
	/**
513
	 * Calculate the total amount of all items
514
	 *
515
	 * @return Money
516
	 */
517 1
	public function get_amount() {
518 1
		return $this->items->get_amount();
519
	}
520
521
	/**
522
	 * Create hash string
523
	 */
524 1
	public function create_hash_string() {
525 1
		$string = array();
526
527
		// SHA1 hashcode, used only with the hashcode approach (Chapter 4).
528 1
		$string[] = $this->get_hash_key();
529
530
		// Your AcceptorID is provided in the registration process, also known as merchant id.
531 1
		$string[] = $this->get_merchant_id();
532
533
		// Provided in the registration process, value is normally '0' (zero).
534 1
		$string[] = $this->get_sub_id();
535
536
		// Total amount of transaction.
537 1
		$string[] = intval( $this->get_amount()->get_cents() );
0 ignored issues
show
Deprecated Code introduced by
The function Pronamic\WordPress\Money\Money::get_cents() has been deprecated: 1.2.2 Use `Money::get_minor_units()` instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

537
		$string[] = intval( /** @scrutinizer ignore-deprecated */ $this->get_amount()->get_cents() );

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
538
539
		// The online shop's unique order number, also known as purchase id.
540 1
		$string[] = $this->get_purchase_id();
541
542
		// ?? Fixed value = ideal
543 1
		$string[] = $this->get_payment_type();
544
545
		// yyyy-MMddTHH:mm:ss.SSS Z Time at which the transaction expires (maximum of 1 hour later).
546
		// The consumer has time until then to pay with iDEAL.
547 1
		$string[] = $this->get_expire_date()->format( $this->get_expire_date_format() );
548
549
		// Iterate through the items and concat.
550 1
		foreach ( $this->get_items() as $item ) {
551
			// Article number. <n> is 1 for the first product, 2 for the second, etc.
552
			// N.B. Note that for every product type the parameters
553
			// itemNumber<n>, itemDescription<n>, itemQuantity<n> and itemPrice<n> are mandatory.
554 1
			$string[] = $item->get_number();
555
556
			// Description of article <n>.
557 1
			$string[] = $item->get_description();
558
559
			// Number of items of article <n> that the consumer wants to buy.
560 1
			$string[] = $item->get_quantity();
561
562
			// Price of article <n> in whole eurocents.
563 1
			$string[] = intval( $item->get_price()->get_cents() );
564
		}
565
566 1
		$concat_string = implode( '', $string );
567
568
		// The characters "\t", "\n", "\r", " " (spaces) may not exist in the string.
569 1
		$forbidden_characters = $this->get_forbidden_characters();
570 1
		$concat_string        = str_replace( $forbidden_characters, '', $concat_string );
571
572
		// Delete special HTML entities.
573 1
		$concat_string = html_entity_decode( $concat_string, ENT_COMPAT, 'UTF-8' );
574
575 1
		return $concat_string;
576
	}
577
578
	/**
579
	 * Create hash
580
	 *
581
	 * @return string Hash
582
	 */
583 1
	public function create_hash() {
584 1
		return sha1( $this->create_hash_string() );
585
	}
586
587
	/**
588
	 * Get the iDEAL HTML fields
589
	 *
590
	 * @since 1.1.1
591
	 * @return array
592
	 */
593
	public function get_fields() {
594
		$fields = array();
595
596
		$fields['merchantID'] = $this->get_merchant_id();
597
		$fields['subID']      = $this->get_sub_id();
598
599
		$fields['amount']      = intval( $this->get_amount()->get_cents() );
0 ignored issues
show
Deprecated Code introduced by
The function Pronamic\WordPress\Money\Money::get_cents() has been deprecated: 1.2.2 Use `Money::get_minor_units()` instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

599
		$fields['amount']      = intval( /** @scrutinizer ignore-deprecated */ $this->get_amount()->get_cents() );

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
600
		$fields['purchaseID']  = $this->get_purchase_id();
601
		$fields['language']    = $this->get_language();
602
		$fields['currency']    = $this->get_currency();
603
		$fields['description'] = $this->get_description();
604
		$fields['hash']        = $this->create_hash();
605
		$fields['paymentType'] = $this->get_payment_type();
606
		$fields['validUntil']  = $this->get_expire_date()->format( $this->get_expire_date_format() );
607
608
		$serial_number = 1;
609
		foreach ( $this->get_items() as $item ) {
610
			$fields[ 'itemNumber' . $serial_number ]      = $item->get_number();
611
			$fields[ 'itemDescription' . $serial_number ] = $item->get_description();
612
			$fields[ 'itemQuantity' . $serial_number ]    = $item->get_quantity();
613
			$fields[ 'itemPrice' . $serial_number ]       = intval( $item->get_price()->get_cents() );
614
615
			$serial_number ++;
616
		}
617
618
		$fields['urlCancel']  = $this->get_cancel_url();
619
		$fields['urlSuccess'] = $this->get_success_url();
620
		$fields['urlError']   = $this->get_error_url();
621
622
		return $fields;
623
	}
624
}
625