Passed
Push — develop ( 7df30e...22e89a )
by Reüel
12:39
created

Subscription   C

Complexity

Total Complexity 52

Size/Duplication

Total Lines 727
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 727
rs 6.6666
c 0
b 0
f 0
wmc 52

41 Methods

Rating   Name   Duplication   Size   Complexity  
A get_interval_period() 0 2 1
A set_meta() 0 12 3
A get_status() 0 2 1
A get_date_interval() 0 6 1
A get_meta() 0 4 1
A set_consumer_name() 0 2 1
A get_transaction_id() 0 2 1
A get_amount() 0 2 1
A set_amount() 0 2 1
A get_description() 0 2 1
A set_transaction_id() 0 2 1
A get_interval() 0 2 1
A get_source() 0 2 1
A __construct() 0 9 2
A set_status() 0 2 1
A get_frequency() 0 2 1
A get_currency() 0 2 1
A get_id() 0 2 1
A set_consumer_iban() 0 2 1
A get_source_id() 0 2 1
A set_consumer_bic() 0 2 1
A set_id() 0 2 1
A add_note() 0 12 1
A get_key() 0 2 1
A get_source_text() 0 10 2
A set_end_date() 0 2 1
A get_expiry_date() 0 2 1
B update_meta() 0 26 5
A save() 0 2 1
A get_start_date() 0 2 1
A get_next_payment_date() 0 2 1
A get_first_payment() 0 8 2
A get_source_description() 0 10 2
A set_expiry_date() 0 2 1
A get_source_link() 0 11 2
A get_payments() 0 2 1
A set_next_payment_date() 0 2 1
A get_cancel_url() 0 10 1
A get_end_date() 0 2 1
A get_renewal_url() 0 10 1
A set_start_date() 0 2 1

How to fix   Complexity   

Complex Class

Complex classes like Subscription often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Subscription, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Subscription
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2018 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay\Subscriptions
9
 */
10
11
namespace Pronamic\WordPress\Pay\Subscriptions;
12
13
use DateInterval;
14
use Pronamic\WordPress\DateTime\DateTime;
15
use Pronamic\WordPress\Money\Currency;
16
use Pronamic\WordPress\Money\Money;
17
use Pronamic\WordPress\Pay\Core\Statuses;
18
use Pronamic\WordPress\Pay\Payments\Payment;
19
use WP_Post;
20
21
/**
22
 * Subscription.
23
 */
24
class Subscription {
25
	/**
26
	 * The ID of this subscription.
27
	 *
28
	 * @var string
29
	 */
30
	protected $id;
31
32
	/**
33
	 * The date of this subscription.
34
	 *
35
	 * @var DateTime
36
	 */
37
	public $date;
38
39
	/**
40
	 * The key of this subscription, used in URL's for security.
41
	 *
42
	 * @var string
43
	 */
44
	public $key;
45
46
	/**
47
	 * The frequency of this subscription, for example: `daily`, `weekly`, `monthly` or `annually`.
48
	 *
49
	 * @var string
50
	 */
51
	public $frequency;
52
53
	/**
54
	 * The interval of this subscription, for example: 1, 2, 3, etc.
55
	 *
56
	 * @todo Improve documentation?
57
	 * @var  int
58
	 */
59
	public $interval;
60
61
	/**
62
	 * The interval period of this subscription.
63
	 *
64
	 * @todo Improve documentation?
65
	 * @var  int
66
	 */
67
	public $interval_period;
68
69
	/**
70
	 * The transaction ID of this subscription.
71
	 *
72
	 * @todo Is this required within a transaction?
73
	 * @var string
74
	 */
75
	public $transaction_id;
76
77
	/**
78
	 * The description of this subscription.
79
	 *
80
	 * @todo Is this required within a transaction?
81
	 * @var string
82
	 */
83
	public $description;
84
85
	/**
86
	 * The amount of this subscription, for example 18.95.
87
	 *
88
	 * @var Money
89
	 */
90
	protected $amount;
91
92
	/**
93
	 * The status of this subscription, for example 'Success'.
94
	 *
95
	 * @todo How to reference to a class constant?
96
	 * @see  Statuses
97
	 * @var  string
98
	 */
99
	public $status;
100
101
	/**
102
	 * Identifier for the source which started this subsription.
103
	 * For example: 'woocommerce', 'gravityforms', 'easydigitaldownloads', etc.
104
	 *
105
	 * @var string
106
	 */
107
	public $source;
108
109
	/**
110
	 * Unique ID at the source which started this subscription, for example:
111
	 * - WooCommerce order ID.
112
	 * - Easy Digital Downloads payment ID.
113
	 * - Gravity Forms entry ID.
114
	 *
115
	 * @var string
116
	 */
117
	public $source_id;
118
119
	/**
120
	 * The name of the consumer of this subscription.
121
	 *
122
	 * @todo Is this required and should we add the 'consumer' part?
123
	 * @var  string
124
	 */
125
	public $consumer_name;
126
127
	/**
128
	 * The IBAN of the consumer of this subscription.
129
	 *
130
	 * @todo Is this required and should we add the 'consumer' part?
131
	 * @var  string
132
	 */
133
	public $consumer_iban;
134
135
	/**
136
	 * The BIC of the consumer of this subscription.
137
	 *
138
	 * @todo Is this required and should we add the 'consumer' part?
139
	 * @var  string
140
	 */
141
	public $consumer_bic;
142
143
	/**
144
	 * The order ID of this subscription.
145
	 *
146
	 * @todo Is this required?
147
	 * @var  string
148
	 */
149
	public $order_id;
150
151
	/**
152
	 * The address of the consumer of this subscription.
153
	 *
154
	 * @todo Is this required?
155
	 * @var  string
156
	 */
157
	public $address;
158
159
	/**
160
	 * The city of the consumer of this subscription.
161
	 *
162
	 * @todo Is this required?
163
	 * @var  string
164
	 */
165
	public $city;
166
167
	/**
168
	 * The ZIP of the consumer of this subscription.
169
	 *
170
	 * @todo Is this required?
171
	 * @var  string
172
	 */
173
	public $zip;
174
175
	/**
176
	 * The country of the consumer of this subscription.
177
	 *
178
	 * @todo Is this required?
179
	 * @var  string
180
	 */
181
	public $country;
182
183
	/**
184
	 * The telephone number of the consumer of this subscription.
185
	 *
186
	 * @todo Is this required?
187
	 * @var  string
188
	 */
189
	public $telephone_number;
190
191
	/**
192
	 * The gateway configuration ID to use with this subscription.
193
	 *
194
	 * @todo Should we improve the name of this var?
195
	 * @var  integer
196
	 */
197
	public $config_id;
198
199
	/**
200
	 * The email of the consumer of this subscription.
201
	 *
202
	 * @todo Is this required?
203
	 * @var  string
204
	 */
205
	public $email;
206
207
	/**
208
	 * The customer name of the consumer of this subscription.
209
	 *
210
	 * @todo Is this required?
211
	 * @var  string
212
	 */
213
	public $customer_name;
214
215
	/**
216
	 * The payment method which was used to create this subscription.
217
	 *
218
	 * @var  string
219
	 */
220
	public $payment_method;
221
222
	/**
223
	 * The date when this subscirption started.
224
	 *
225
	 * @var DateTime|null
226
	 */
227
	public $start_date;
228
229
	/**
230
	 * The date when this subscirption will end, can be `null`.
231
	 *
232
	 * @var DateTime|null
233
	 */
234
	public $end_date;
235
236
	/**
237
	 * The end date of the last succesfull payment.
238
	 *
239
	 * @var DateTime|null
240
	 */
241
	public $expiry_date;
242
243
	/**
244
	 * The next payment date.
245
	 *
246
	 * @var DateTime|null
247
	 */
248
	public $next_payment;
249
250
	/**
251
	 * Array for extra meta data to store with this subscription.
252
	 *
253
	 * @var array
254
	 */
255
	public $meta;
256
257
	/**
258
	 * WordPress post object related to this subscription.
259
	 *
260
	 * @var WP_Post|array
261
	 */
262
	public $post;
263
264
	/**
265
	 * Construct and initialize subscription object.
266
	 *
267
	 * @param int $post_id A subscription post ID or null.
268
	 */
269
	public function __construct( $post_id = null ) {
270
		$this->id   = $post_id;
271
		$this->date = new DateTime();
272
		$this->meta = array();
273
274
		$this->set_amount( new Money() );
275
276
		if ( ! empty( $post_id ) ) {
277
			pronamic_pay_plugin()->subscriptions_data_store->read( $this );
278
		}
279
	}
280
281
	/**
282
	 * Get the ID of this subscription.
283
	 *
284
	 * @return string
285
	 */
286
	public function get_id() {
287
		return $this->id;
288
	}
289
290
	/**
291
	 * Set the ID of this subscription.
292
	 *
293
	 * @param string $id The ID of this subscription.
294
	 */
295
	public function set_id( $id ) {
296
		$this->id = $id;
297
	}
298
299
	/**
300
	 * Get the unique key of this subscription.
301
	 *
302
	 * @return string
303
	 */
304
	public function get_key() {
305
		return $this->key;
306
	}
307
308
	/**
309
	 * Get the source identifier of this subscription, for example: 'woocommerce', 'gravityforms', etc.
310
	 *
311
	 * @return string
312
	 */
313
	public function get_source() {
314
		return $this->source;
315
	}
316
317
	/**
318
	 * Get the source ID of this subscription, for example a WooCommerce order ID or a Gravity Forms entry ID.
319
	 *
320
	 * @return string
321
	 */
322
	public function get_source_id() {
323
		return $this->source_id;
324
	}
325
326
	/**
327
	 * Get the frequency of this subscription, for example: 'daily', 'weekly', 'monthly' or 'annually'.
328
	 *
329
	 * @return string
330
	 */
331
	public function get_frequency() {
332
		return $this->frequency;
333
	}
334
335
	/**
336
	 * Get the interval, for example: 1, 2, 3, 4, etc., this specifies for example:
337
	 * - Repeat every *2* days
338
	 * - Repeat every *1* months
339
	 * - Repeat every *2* year
340
	 *
341
	 * @return int
342
	 */
343
	public function get_interval() {
344
		return $this->interval;
345
	}
346
347
	/**
348
	 * Get the interval period, for example 'D', 'M', 'Y', etc.
349
	 *
350
	 * @see    http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters
351
	 * @return string
352
	 */
353
	public function get_interval_period() {
354
		return $this->interval_period;
355
	}
356
357
	/**
358
	 * Get date interval.
359
	 *
360
	 * @see http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters
361
	 * @return \DateInterval
362
	 * @throws \Exception    Throws an Exception when the `interval_spec` cannot be parsed as an interval.
363
	 */
364
	public function get_date_interval() {
365
		$interval_spec = 'P' . $this->interval . $this->interval_period;
366
367
		$interval = new DateInterval( $interval_spec );
368
369
		return $interval;
370
	}
371
372
	/**
373
	 * Get the description of this subscription.
374
	 *
375
	 * @return string
376
	 */
377
	public function get_description() {
378
		return $this->description;
379
	}
380
381
	/**
382
	 * Get the currency of this subscription.
383
	 *
384
	 * @return Currency
385
	 */
386
	public function get_currency() {
387
		return $this->get_amount()->get_currency()->get_alphabetic_code();
388
	}
389
390
	/**
391
	 * Get the amount of this subscription.
392
	 *
393
	 * @return Money
394
	 */
395
	public function get_amount() {
396
		return $this->amount;
397
	}
398
399
	/**
400
	 * Set the amount of this subscription.
401
	 *
402
	 * @param Money $amount Money object.
403
	 *
404
	 * @return void
405
	 */
406
	public function set_amount( Money $amount ) {
407
		$this->amount = $amount;
408
	}
409
410
	/**
411
	 * Get the transaction ID of this subscription.
412
	 *
413
	 * @return string
414
	 */
415
	public function get_transaction_id() {
416
		return $this->transaction_id;
417
	}
418
419
	/**
420
	 * Set the transaction ID of this subscription.
421
	 *
422
	 * @param string $transaction_id A transaction ID.
423
	 */
424
	public function set_transaction_id( $transaction_id ) {
425
		$this->transaction_id = $transaction_id;
426
	}
427
428
	/**
429
	 * Get the status of this subscription.
430
	 *
431
	 * @todo   Check constant?
432
	 * @return string
433
	 */
434
	public function get_status() {
435
		return $this->status;
436
	}
437
438
	/**
439
	 * Set the status of this subscription.
440
	 *
441
	 * @todo  Check constant?
442
	 * @param string $status A status string.
443
	 */
444
	public function set_status( $status ) {
445
		$this->status = $status;
446
	}
447
448
	/**
449
	 * Set consumer name.
450
	 *
451
	 * @param string $name A name.
452
	 */
453
	public function set_consumer_name( $name ) {
454
		$this->consumer_name = $name;
455
	}
456
457
	/**
458
	 * Set consumer IBAN.
459
	 *
460
	 * @param string $iban A IBAN.
461
	 */
462
	public function set_consumer_iban( $iban ) {
463
		$this->consumer_iban = $iban;
464
	}
465
466
	/**
467
	 * Set consumer BIC.
468
	 *
469
	 * @param string $bic A BIC.
470
	 */
471
	public function set_consumer_bic( $bic ) {
472
		$this->consumer_bic = $bic;
473
	}
474
475
	/**
476
	 * Add the specified note to this subscription.
477
	 *
478
	 * @param string $note A Note.
479
	 */
480
	public function add_note( $note ) {
481
		$commentdata = array(
482
			'comment_post_ID'  => $this->id,
483
			'comment_content'  => $note,
484
			'comment_type'     => 'subscription_note',
485
			'user_id'          => get_current_user_id(),
486
			'comment_approved' => true,
487
		);
488
489
		$comment_id = wp_insert_comment( $commentdata );
490
491
		return $comment_id;
492
	}
493
494
	/**
495
	 * Get meta by the specified meta key.
496
	 *
497
	 * @param string $key A meta key.
498
	 * @return string
499
	 */
500
	public function get_meta( $key ) {
501
		$key = '_pronamic_subscription_' . $key;
502
503
		return get_post_meta( $this->id, $key, true );
0 ignored issues
show
Bug introduced by
$this->id of type string is incompatible with the type integer expected by parameter $post_id of get_post_meta(). ( Ignorable by Annotation )

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

503
		return get_post_meta( /** @scrutinizer ignore-type */ $this->id, $key, true );
Loading history...
504
	}
505
506
	/**
507
	 * Set meta data.
508
	 *
509
	 * @param  string $key   A meta key.
510
	 * @param  mixed  $value A meta value.
511
	 *
512
	 * @return boolean        True on successful update, false on failure.
513
	 */
514
	public function set_meta( $key, $value = false ) {
515
		$key = '_pronamic_subscription_' . $key;
516
517
		if ( $value instanceof DateTime ) {
518
			$value = $value->format( 'Y-m-d H:i:s' );
519
		}
520
521
		if ( empty( $value ) ) {
522
			return delete_post_meta( $this->id, $key );
0 ignored issues
show
Bug introduced by
$this->id of type string is incompatible with the type integer expected by parameter $post_id of delete_post_meta(). ( Ignorable by Annotation )

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

522
			return delete_post_meta( /** @scrutinizer ignore-type */ $this->id, $key );
Loading history...
523
		}
524
525
		return update_post_meta( $this->id, $key, $value );
0 ignored issues
show
Bug introduced by
$this->id of type string is incompatible with the type integer expected by parameter $post_id of update_post_meta(). ( Ignorable by Annotation )

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

525
		return update_post_meta( /** @scrutinizer ignore-type */ $this->id, $key, $value );
Loading history...
526
	}
527
528
	/**
529
	 * Get source text.
530
	 *
531
	 * @return string
532
	 */
533
	public function get_source_text() {
534
		$text = $this->get_source() . '<br />' . $this->get_source_id();
535
536
		$payment = $this->get_first_payment();
537
538
		if ( $payment ) {
0 ignored issues
show
introduced by
$payment is of type Pronamic\WordPress\Pay\Payments\Payment, thus it always evaluated to true.
Loading history...
539
			$text = $payment->get_source_text();
540
		}
541
542
		return $text;
543
	}
544
545
	/**
546
	 * Get source description.
547
	 *
548
	 * @return string
549
	 */
550
	public function get_source_description() {
551
		$text = $this->get_source();
552
553
		$payment = $this->get_first_payment();
554
555
		if ( $payment ) {
0 ignored issues
show
introduced by
$payment is of type Pronamic\WordPress\Pay\Payments\Payment, thus it always evaluated to true.
Loading history...
556
			$text = $payment->get_source_description();
557
		}
558
559
		return $text;
560
	}
561
562
	/**
563
	 * Get source link for this subscription.
564
	 *
565
	 * @return string|null
566
	 */
567
	public function get_source_link() {
568
		$url = null;
569
570
		$payment = $this->get_first_payment();
571
572
		if ( $payment ) {
0 ignored issues
show
introduced by
$payment is of type Pronamic\WordPress\Pay\Payments\Payment, thus it always evaluated to true.
Loading history...
573
			$url = apply_filters( 'pronamic_payment_source_url', $url, $payment );
574
			$url = apply_filters( 'pronamic_payment_source_url_' . $this->source, $url, $payment );
575
		}
576
577
		return $url;
578
	}
579
580
	/**
581
	 * Get cancel URL for this subscription.
582
	 *
583
	 * @return string
584
	 */
585
	public function get_cancel_url() {
586
		$cancel_url = add_query_arg(
587
			array(
588
				'subscription' => $this->get_id(),
589
				'key'          => $this->get_key(),
590
				'action'       => 'cancel',
591
			), home_url()
592
		);
593
594
		return $cancel_url;
595
	}
596
597
	/**
598
	 * Get renewal URL for this subscription.
599
	 *
600
	 * @return string
601
	 */
602
	public function get_renewal_url() {
603
		$renewal_url = add_query_arg(
604
			array(
605
				'subscription' => $this->get_id(),
606
				'key'          => $this->get_key(),
607
				'action'       => 'renew',
608
			), home_url()
609
		);
610
611
		return $renewal_url;
612
	}
613
614
	/**
615
	 * Get all the payments for this subscription.
616
	 *
617
	 * @return array
618
	 */
619
	public function get_payments() {
620
		return get_pronamic_payments_by_meta( '_pronamic_payment_subscription_id', $this->id );
621
	}
622
623
	/**
624
	 * Get the first payment of this subscription.
625
	 *
626
	 * @return Payment
627
	 */
628
	public function get_first_payment() {
629
		$payments = $this->get_payments();
630
631
		if ( count( $payments ) > 0 ) {
632
			return $payments[0];
633
		}
634
635
		return null;
636
	}
637
638
	/**
639
	 * Get the start date of this subscription.
640
	 *
641
	 * @return DateTime|null
642
	 */
643
	public function get_start_date() {
644
		return $this->start_date;
645
	}
646
647
	/**
648
	 * Set the start date of this subscription.
649
	 *
650
	 * @param DateTime $date Start date.
651
	 */
652
	public function set_start_date( DateTime $date ) {
653
		$this->start_date = $date;
654
	}
655
656
	/**
657
	 * Get the end date of this subscription.
658
	 *
659
	 * @return DateTime|null
660
	 */
661
	public function get_end_date() {
662
		return $this->end_date;
663
	}
664
665
	/**
666
	 * Set the end date of this subscription.
667
	 *
668
	 * @param DateTime|null $date End date.
669
	 */
670
	public function set_end_date( DateTime $date ) {
671
		$this->end_date = $date;
672
	}
673
674
	/**
675
	 * Get the expiry date of this subscription.
676
	 *
677
	 * @return DateTime
678
	 */
679
	public function get_expiry_date() {
680
		return $this->expiry_date;
681
	}
682
683
	/**
684
	 * Set the expiry date of this subscription.
685
	 *
686
	 * @param DateTime $date Expiry date.
687
	 */
688
	public function set_expiry_date( DateTime $date ) {
689
		$this->expiry_date = $date;
690
	}
691
692
	/**
693
	 * Set the next payment date of this subscription.
694
	 *
695
	 * @param DateTime $date Next payment date.
696
	 */
697
	public function set_next_payment_date( DateTime $date ) {
698
		$this->next_payment = $date;
699
	}
700
701
	/**
702
	 * Get the next payment date of this subscription.
703
	 *
704
	 * @return DateTime
705
	 */
706
	public function get_next_payment_date() {
707
		return $this->next_payment;
708
	}
709
710
	/**
711
	 * Update meta.
712
	 *
713
	 * @todo  Not sure how and when this function is used.
714
	 * @param array $meta The meta data to update.
715
	 */
716
	public function update_meta( $meta ) {
717
		if ( ! is_array( $meta ) || count( $meta ) === 0 ) {
0 ignored issues
show
introduced by
The condition is_array($meta) is always true.
Loading history...
718
			return;
719
		}
720
721
		$note = sprintf(
722
			'<p>%s:</p>',
723
			__( 'Subscription changed', 'pronamic_ideal' )
724
		);
725
726
		$note .= '<dl>';
727
728
		foreach ( $meta as $key => $value ) {
729
			$this->set_meta( $key, $value );
730
731
			if ( $value instanceof DateTime ) {
732
				$value = date_i18n( __( 'l jS \o\f F Y, h:ia', 'pronamic_ideal' ), $value->getTimestamp() );
733
			}
734
735
			$note .= sprintf( '<dt>%s</dt>', esc_html( $key ) );
736
			$note .= sprintf( '<dd>%s</dd>', esc_html( $value ) );
737
		}
738
739
		$note .= '</dl>';
740
741
		$this->add_note( $note );
742
	}
743
744
	/**
745
	 * Save subscription.
746
	 *
747
	 * @return void
748
	 */
749
	public function save() {
750
		pronamic_pay_plugin()->subscriptions_data_store->update( $this );
751
	}
752
}
753