Client::get_currency()   A
last analyzed

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-2021 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 merchant 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 characters
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 format
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 true or 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[] = $this->get_amount()->get_minor_units()->format( 0, '', '' );
0 ignored issues
show
Bug introduced by
The method format() does not exist on integer. ( Ignorable by Annotation )

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

537
		$string[] = $this->get_amount()->get_minor_units()->/** @scrutinizer ignore-call */ format( 0, '', '' );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

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[] = $item->get_price()->get_minor_units()->format( 0, '', '' );
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']      = $this->get_amount()->get_minor_units()->format( 0, '', '' );
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 ]       = $item->get_price()->get_minor_units()->format( 0, '', '' );
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