Passed
Push — develop ( 984b92...f29211 )
by Remco
05:08
created

Subscription::refresh_next_payment_date()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 0
dl 0
loc 23
rs 9.0856
c 0
b 0
f 0
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 DateTime;
15
use DateTimeZone;
16
use Pronamic\WordPress\Pay\Plugin;
17
use Pronamic_IDeal_IDeal;
0 ignored issues
show
Bug introduced by
The type Pronamic_IDeal_IDeal was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Pronamic\WordPress\Pay\Core\Statuses;
19
use Pronamic\WordPress\Pay\Util;
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 key of this subscription, used in URL's for security.
34
	 *
35
	 * @var string
36
	 */
37
	public $key;
38
39
	/**
40
	 * The frequency of this subscription, for example: `daily`, `weekly`, `monthly` or `annually`.
41
	 *
42
	 * @var string
43
	 */
44
	public $frequency;
45
46
	/**
47
	 * The interval of this subscription, for example: 1, 2, 3, etc.
48
	 *
49
	 * @todo Improve documentation?
50
	 * @var  int
51
	 */
52
	public $interval;
53
54
	/**
55
	 * The interval period of this subscription.
56
	 *
57
	 * @todo Improve documentation?
58
	 * @var  int
59
	 */
60
	public $interval_period;
61
62
	/**
63
	 * The transaction ID of this subscription.
64
	 *
65
	 * @todo Is this required within a transaction?
66
	 * @var string
67
	 */
68
	public $transaction_id;
69
70
	/**
71
	 * The description of this subscription.
72
	 *
73
	 * @todo Is this required within a transaction?
74
	 * @var string
75
	 */
76
	public $description;
77
78
	/**
79
	 * The currency of this subscription, for example 'EUR' or 'USD'.
80
	 *
81
	 * @var string
82
	 */
83
	public $currency;
84
85
	/**
86
	 * The amount of this subscription, for example 18.95.
87
	 *
88
	 * @var float
89
	 */
90
	public $amount;
91
92
	/**
93
	 * The status of this subscription, for example 'Success'.
94
	 *
95
	 * @todo How to reference to a class constant?
96
	 * @see  Pronamic\WordPress\Pay\Core\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  string
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
226
	 */
227
	public $start_date;
228
229
	/**
230
	 * The end date of the last succesfull payment.
231
	 *
232
	 * @var DateTime
233
	 */
234
	public $expiry_date;
235
236
	/**
237
	 * The date of the first payment.
238
	 *
239
	 * @todo Is this required? And is this not equeal to start date of the subscription?
240
	 * @var DateTime
241
	 */
242
	public $first_payment;
243
244
	/**
245
	 * The next payment date.
246
	 *
247
	 * @todo Is this required?
248
	 * @var DateTime
249
	 */
250
	public $next_payment;
251
252
	/**
253
	 * The final payment date, can be null if the subscrption never ends.
254
	 *
255
	 * @todo Is this required?
256
	 * @var DateTime
257
	 */
258
	public $final_payment;
259
260
	/**
261
	 * The renewal notice date.
262
	 *
263
	 * @todo Is this required?
264
	 * @var DateTime
265
	 */
266
	public $renewal_notice;
267
268
	/**
269
	 * Array for extra meta data to store with this subscription.
270
	 *
271
	 * @var array
272
	 */
273
	public $meta;
274
275
	/**
276
	 * WordPress post object related to this subscription.
277
	 *
278
	 * @var \WP_Post
279
	 */
280
	public $post;
281
282
	/**
283
	 * Construct and initialize payment object.
284
	 *
285
	 * @param int $post_id A subscription post ID or null.
286
	 */
287
	public function __construct( $post_id = null ) {
288
		$this->id   = $post_id;
289
		$this->date = new \DateTime();
0 ignored issues
show
Bug Best Practice introduced by
The property date does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
290
		$this->meta = array();
291
292
		if ( null !== $post_id ) {
293
			global $pronamic_ideal;
294
295
			$pronamic_ideal->subscriptions_data_store->read( $this );
296
		}
297
	}
298
299
	/**
300
	 * Get the ID of this subscription.
301
	 *
302
	 * @return string
303
	 */
304
	public function get_id() {
305
		return $this->id;
306
	}
307
308
	/**
309
	 * Set the ID of this subscription.
310
	 *
311
	 * @param string $id The ID of this subscription.
312
	 */
313
	public function set_id( $id ) {
314
		$this->id = $id;
315
	}
316
317
	/**
318
	 * Get the unique key of this subscription.
319
	 *
320
	 * @return string
321
	 */
322
	public function get_key() {
323
		return $this->key;
324
	}
325
326
	/**
327
	 * Get the source identifier of this subscription, for example: 'woocommerce', 'gravityforms', etc.
328
	 *
329
	 * @return string
330
	 */
331
	public function get_source() {
332
		return $this->source;
333
	}
334
335
	/**
336
	 * Get the source ID of this subscription, for example a WooCommerce order ID or a Gravity Forms entry ID.
337
	 *
338
	 * @return string
339
	 */
340
	public function get_source_id() {
341
		return $this->source_id;
342
	}
343
344
	/**
345
	 * Get the frequency of this subscription, for example: 'daily', 'weekly', 'monthly' or 'annually'.
346
	 *
347
	 * @return string
348
	 */
349
	public function get_frequency() {
350
		return $this->frequency;
351
	}
352
353
	/**
354
	 * Get the interval, for example: 1, 2, 3, 4, etc., this specifies for example:
355
	 * - Repeat every *2* days
356
	 * - Repeat every *1* months
357
	 * - Repeat every *2* year
358
	 *
359
	 * @return int
360
	 */
361
	public function get_interval() {
362
		return $this->interval;
363
	}
364
365
	/**
366
	 * Get the interval period, for example 'D', 'M', 'Y', etc.
367
	 *
368
	 * @see    http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters
369
	 * @return string
370
	 */
371
	public function get_interval_period() {
372
		return $this->interval_period;
373
	}
374
375
	/**
376
	 * Get date interval.
377
	 *
378
	 * @see http://php.net/manual/en/dateinterval.construct.php#refsect1-dateinterval.construct-parameters
379
	 * @return \DateInterval
380
	 * @throws \Exception    Throws an Exception when the `interval_spec` cannot be parsed as an interval.
381
	 */
382
	public function get_date_interval() {
383
		$interval_spec = 'P' . $this->interval . $this->interval_period;
384
385
		$interval = new DateInterval( $interval_spec );
386
387
		return $interval;
388
	}
389
390
	/**
391
	 * Get the description of this subscription.
392
	 *
393
	 * @return string
394
	 */
395
	public function get_description() {
396
		return $this->description;
397
	}
398
399
	/**
400
	 * Get the currency of this subscription.
401
	 *
402
	 * @return string
403
	 */
404
	public function get_currency() {
405
		return $this->currency;
406
	}
407
408
	/**
409
	 * Get the amount of this subscription.
410
	 *
411
	 * @return float
412
	 */
413
	public function get_amount() {
414
		return $this->amount;
415
	}
416
417
	/**
418
	 * Get the transaction ID of this subscription.
419
	 *
420
	 * @return string
421
	 */
422
	public function get_transaction_id() {
423
		return $this->transaction_id;
424
	}
425
426
	/**
427
	 * Set the transaction ID of this subscription.
428
	 *
429
	 * @param string $transaction_id A transaction ID.
430
	 */
431
	public function set_transaction_id( $transaction_id ) {
432
		$this->transaction_id = $transaction_id;
433
	}
434
435
	/**
436
	 * Get the status of this subscription.
437
	 *
438
	 * @todo   Check constant?
439
	 * @return string
440
	 */
441
	public function get_status() {
442
		return $this->status;
443
	}
444
445
	/**
446
	 * Set the status of this subscription.
447
	 *
448
	 * @todo  Check constant?
449
	 * @param string $status A status string.
450
	 */
451
	public function set_status( $status ) {
452
		$this->status = $status;
453
	}
454
455
	/**
456
	 * Set consumer name.
457
	 *
458
	 * @param string $name A name.
459
	 */
460
	public function set_consumer_name( $name ) {
461
		$this->consumer_name = $name;
462
	}
463
464
	/**
465
	 * Set consumer IBAN.
466
	 *
467
	 * @param string $iban A IBAN.
468
	 */
469
	public function set_consumer_iban( $iban ) {
470
		$this->consumer_iban = $iban;
471
	}
472
473
	/**
474
	 * Set consumer BIC.
475
	 *
476
	 * @param string $bic A BIC.
477
	 */
478
	public function set_consumer_bic( $bic ) {
479
		$this->consumer_bic = $bic;
480
	}
481
482
	/**
483
	 * Add the specified note to this subscription.
484
	 *
485
	 * @param string $note A Note.
486
	 */
487
	public function add_note( $note ) {
488
		$commentdata = array(
489
			'comment_post_ID'      => $this->id,
490
			'comment_author'       => 'admin',
491
			'comment_author_email' => '[email protected]',
492
			'comment_author_url'   => 'http://',
493
			'comment_content'      => $note,
494
			'comment_type'         => 'subscription_note',
495
			'comment_parent'       => 0,
496
			'user_id'              => 0,
497
			'comment_approved'     => 1,
498
		);
499
500
		$comment_id = wp_insert_comment( $commentdata );
501
502
		return $comment_id;
503
	}
504
505
	/**
506
	 * Get meta by the specified meta key.
507
	 *
508
	 * @param string $key A meta key.
509
	 * @return string
510
	 */
511
	public function get_meta( $key ) {
512
		$key = '_pronamic_subscription_' . $key;
513
514
		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

514
		return get_post_meta( /** @scrutinizer ignore-type */ $this->id, $key, true );
Loading history...
515
	}
516
517
	/**
518
	 * Set meta data.
519
	 *
520
	 * @param  string $key   A meta key.
521
	 * @param  mixed  $value A meta value.
522
	 *
523
	 * @return boolean        True on successful update, false on failure.
524
	 */
525
	public function set_meta( $key, $value = false ) {
526
		$key = '_pronamic_subscription_' . $key;
527
528
		if ( $value instanceof DateTime ) {
529
			$value = $value->format( 'Y-m-d H:i:s' );
530
		}
531
532
		if ( empty( $value ) ) {
533
			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

533
			return delete_post_meta( /** @scrutinizer ignore-type */ $this->id, $key );
Loading history...
534
		}
535
536
		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

536
		return update_post_meta( /** @scrutinizer ignore-type */ $this->id, $key, $value );
Loading history...
537
	}
538
539
	/**
540
	 * Get source description.
541
	 *
542
	 * @return string
543
	 */
544
	public function get_source_description() {
545
		$description = $this->source;
546
547
		$payment = $this->get_first_payment();
548
549
		if ( $payment ) {
550
			$description = apply_filters( 'pronamic_payment_source_description', $description, $payment );
551
			$description = apply_filters( 'pronamic_payment_source_description_' . $this->source, $description, $payment );
552
		}
553
554
		return $description;
555
	}
556
557
	/**
558
	 * Get source link for this subscription.
559
	 *
560
	 * @return string
561
	 */
562
	public function get_source_link() {
563
		$url = null;
564
565
		$payment = $this->get_first_payment();
566
567
		if ( $payment ) {
568
			$url = apply_filters( 'pronamic_payment_source_url', $url, $payment );
569
			$url = apply_filters( 'pronamic_payment_source_url_' . $this->source, $url, $payment );
570
		}
571
572
		return $url;
573
	}
574
575
	/**
576
	 * Get cancel URL for this subscription.
577
	 *
578
	 * @return string
579
	 */
580
	public function get_cancel_url() {
581
		$cancel_url = add_query_arg(
582
			array(
583
				'subscription' => $this->get_id(),
584
				'key'          => $this->get_key(),
585
				'action'       => 'cancel',
586
			), home_url()
587
		);
588
589
		return $cancel_url;
590
	}
591
592
	/**
593
	 * Get renewal URL for this subscription.
594
	 *
595
	 * @return string
596
	 */
597
	public function get_renewal_url() {
598
		$renewal_url = add_query_arg(
599
			array(
600
				'subscription' => $this->get_id(),
601
				'key'          => $this->get_key(),
602
				'action'       => 'renew',
603
			), home_url()
604
		);
605
606
		return $renewal_url;
607
	}
608
609
	/**
610
	 * Get all the payments for this subscription.
611
	 *
612
	 * @return array
613
	 */
614
	public function get_payments() {
615
		return get_pronamic_payments_by_meta( '_pronamic_payment_subscription_id', $this->id );
616
	}
617
618
	/**
619
	 * Get the first payment of this subscription.
620
	 *
621
	 * @return Payment
0 ignored issues
show
Bug introduced by
The type Pronamic\WordPress\Pay\Subscriptions\Payment was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
622
	 */
623
	public function get_first_payment() {
624
		$payments = $this->get_payments();
625
626
		if ( count( $payments ) > 0 ) {
627
			return $payments[0];
628
		}
629
630
		return null;
631
	}
632
633
	/**
634
	 * Set the start date of this subscription.
635
	 *
636
	 * @todo  Should we set meta directly?
637
	 * @param string $value A date value.
638
	 */
639
	public function set_start_date( $value ) {
640
		$this->start_date = $value;
0 ignored issues
show
Documentation Bug introduced by
It seems like $value of type string is incompatible with the declared type DateTime of property $start_date.

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...
641
	}
642
643
	/**
644
	 * Get the start date of this subscription.
645
	 *
646
	 * @todo Should we handle logic in this getter?
647
	 * @return DateTime|null
648
	 */
649
	public function get_start_date() {
650
		return $this->start_date;
651
	}
652
653
	/**
654
	 * Set the expiry date of this subscription.
655
	 *
656
	 * @todo  Should we set meta directly?
657
	 * @param string $value A date value.
658
	 */
659
	public function set_expiry_date( $value ) {
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed. ( Ignorable by Annotation )

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

659
	public function set_expiry_date( /** @scrutinizer ignore-unused */ $value ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
660
		$this->expiry_date = $expiry_date;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $expiry_date seems to be never defined.
Loading history...
661
	}
662
663
	/**
664
	 * Get the expiry date of this subscription.
665
	 *
666
	 * @todo Should we handle logic in this getter?
667
	 * @return DateTime
668
	 */
669
	public function get_expiry_date() {
670
		return $this->expiry_date;
671
	}
672
673
	/**
674
	 * Set the first payment date of this subscription.
675
	 *
676
	 * @todo  Should we set meta directly?
677
	 * @param string $value A date value.
678
	 */
679
	public function set_first_payment_date( $value ) {
680
		$this->first_payment = $value;
0 ignored issues
show
Documentation Bug introduced by
It seems like $value of type string is incompatible with the declared type DateTime of property $first_payment.

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...
681
	}
682
683
	/**
684
	 * Get the first payment date of this subscription.
685
	 *
686
	 * @todo Should we handle logic in this getter?
687
	 * @return DateTime
688
	 */
689
	public function get_first_payment_date() {
690
		return $this->first_payment;
691
	}
692
693
	/**
694
	 * Set the final payment date of this subscription.
695
	 *
696
	 * @todo  Should we set meta directly?
697
	 * @param string $value A date value.
698
	 */
699
	public function set_final_payment_date( $value ) {
700
		$this->set_meta( 'final_payment', $value );
701
	}
702
703
	/**
704
	 * Get the final payment date of this subscription.
705
	 *
706
	 * @todo Should we handle logic in this getter?
707
	 * @return DateTime
708
	 */
709
	public function get_final_payment_date() {
710
		return $this->final_payment;
711
712
		$final = $this->get_meta( 'final_payment' );
0 ignored issues
show
Unused Code introduced by
$final = $this->get_meta('final_payment') is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
713
714
		if ( '' !== $final ) {
715
			return new DateTime( $final );
716
		}
717
718
		// If no frequency is set, use next payment or start date.
719
		$frequency = $this->get_frequency();
720
721
		if ( '' === $frequency ) {
722
			$next_date = $this->get_next_payment_date();
723
724
			if ( null === $next_date ) {
725
				return $this->get_start_date();
726
			}
727
728
			return $next_date;
729
		}
730
731
		// Add frequency * interval period to first payment date.
732
		$first_date = $this->get_first_payment_date();
733
734
		return $first_date->modify(
735
			sprintf(
736
				'+%d %s',
737
				( $frequency - 1 ) * $this->get_interval(),
738
				Util::to_interval_name( $this->get_interval_period() )
739
			)
740
		);
741
	}
742
743
	/**
744
	 * Set the next payment date of this subscription.
745
	 *
746
	 * @todo  Should we set meta directly?
747
	 * @param string $value A date value.
748
	 */
749
	public function set_next_payment_date( $value ) {
750
		$this->set_meta( 'next_payment', $value );
751
752
		if ( false === $value ) {
0 ignored issues
show
introduced by
The condition false === $value is always false.
Loading history...
753
			$this->set_renewal_notice_date( false );
754
		}
755
	}
756
757
	/**
758
	 * Get the next payment date of this subscription.
759
	 *
760
	 * @todo   Should we handle logic in this getter?
761
	 * @param  int $cycle TODO.
762
	 * @return DateTime
763
	 */
764
	public function get_next_payment_date( $cycle = 0 ) {
0 ignored issues
show
Unused Code introduced by
The parameter $cycle is not used and could be removed. ( Ignorable by Annotation )

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

764
	public function get_next_payment_date( /** @scrutinizer ignore-unused */ $cycle = 0 ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
765
		return $this->next_payment;
766
767
		// Meta next_payment, possibly doesn't exist if last payment has been processed.
768
		$next_payment = $this->get_meta( 'next_payment' );
0 ignored issues
show
Unused Code introduced by
$next_payment = $this->get_meta('next_payment') is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
769
770
		if ( '' === $next_payment ) {
771
			return;
772
		}
773
774
		$next = new DateTime( $next_payment );
775
776
		if ( 0 !== $cycle ) {
777
			$next->modify(
778
				sprintf(
779
					'+%d %s',
780
					( $cycle * $this->get_interval() ),
781
					Util::to_interval_name( $this->get_interval_period() )
782
				)
783
			);
784
		}
785
786
		return $next;
787
	}
788
789
	/**
790
	 * Set the renewal notice date of this subscription.
791
	 *
792
	 * @todo  Should we set meta directly?
793
	 * @param string $value A date value.
794
	 */
795
	public function set_renewal_notice_date( $value ) {
796
		$this->set_meta( 'renewal_notice', $value );
797
	}
798
799
	/**
800
	 * Get the renewal notice date of this subscription.
801
	 *
802
	 * @todo   Should we handle logic in this getter?
803
	 * @return DateTime
804
	 */
805
	public function get_renewal_notice_date() {
806
		$renewal_notice = $this->get_meta( 'renewal_notice' );
807
808
		if ( '' !== $renewal_notice ) {
809
			return $renewal_notice;
810
		}
811
812
		return false;
813
	}
814
815
	/**
816
	 * Update meta.
817
	 *
818
	 * @todo  Not sure how and when this function is used.
819
	 * @param array $meta The meta data to update.
820
	 */
821
	public function update_meta( $meta ) {
822
		if ( ! is_array( $meta ) || count( $meta ) === 0 ) {
0 ignored issues
show
introduced by
The condition is_array($meta) is always true.
Loading history...
823
			return;
824
		}
825
826
		$note = sprintf(
827
			'<p>%s:</p>',
828
			__( 'Subscription changed', 'pronamic_ideal' )
829
		);
830
831
		$note .= '<dl>';
832
833
		foreach ( $meta as $key => $value ) {
834
			$this->set_meta( $key, $value );
835
836
			if ( $value instanceof DateTime ) {
837
				$value = date_i18n( __( 'l jS \o\f F Y, h:ia', 'pronamic_ideal' ), $value->getTimestamp() );
838
			}
839
840
			$note .= sprintf( '<dt>%s</dt>', esc_html( $key ) );
841
			$note .= sprintf( '<dd>%s</dd>', esc_html( $value ) );
842
		}
843
844
		$note .= '</dl>';
845
846
		$this->add_note( $note );
847
	}
848
}
849