Completed
Push — develop ( f29211...ed262e )
by Remco
10:29 queued 57s
created

Subscription::get_end_date()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

494
		return get_post_meta( /** @scrutinizer ignore-type */ $this->id, $key, true );
Loading history...
495
	}
496
497
	/**
498
	 * Set meta data.
499
	 *
500
	 * @param  string $key   A meta key.
501
	 * @param  mixed  $value A meta value.
502
	 *
503
	 * @return boolean        True on successful update, false on failure.
504
	 */
505
	public function set_meta( $key, $value = false ) {
506
		$key = '_pronamic_subscription_' . $key;
507
508
		if ( $value instanceof DateTime ) {
509
			$value = $value->format( 'Y-m-d H:i:s' );
510
		}
511
512
		if ( empty( $value ) ) {
513
			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

513
			return delete_post_meta( /** @scrutinizer ignore-type */ $this->id, $key );
Loading history...
514
		}
515
516
		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

516
		return update_post_meta( /** @scrutinizer ignore-type */ $this->id, $key, $value );
Loading history...
517
	}
518
519
	/**
520
	 * Get source description.
521
	 *
522
	 * @return string
523
	 */
524
	public function get_source_description() {
525
		$description = $this->source;
526
527
		$payment = $this->get_first_payment();
528
529
		if ( $payment ) {
530
			$description = apply_filters( 'pronamic_payment_source_description', $description, $payment );
531
			$description = apply_filters( 'pronamic_payment_source_description_' . $this->source, $description, $payment );
532
		}
533
534
		return $description;
535
	}
536
537
	/**
538
	 * Get source link for this subscription.
539
	 *
540
	 * @return string
541
	 */
542
	public function get_source_link() {
543
		$url = null;
544
545
		$payment = $this->get_first_payment();
546
547
		if ( $payment ) {
548
			$url = apply_filters( 'pronamic_payment_source_url', $url, $payment );
549
			$url = apply_filters( 'pronamic_payment_source_url_' . $this->source, $url, $payment );
550
		}
551
552
		return $url;
553
	}
554
555
	/**
556
	 * Get cancel URL for this subscription.
557
	 *
558
	 * @return string
559
	 */
560
	public function get_cancel_url() {
561
		$cancel_url = add_query_arg(
562
			array(
563
				'subscription' => $this->get_id(),
564
				'key'          => $this->get_key(),
565
				'action'       => 'cancel',
566
			), home_url()
567
		);
568
569
		return $cancel_url;
570
	}
571
572
	/**
573
	 * Get renewal URL for this subscription.
574
	 *
575
	 * @return string
576
	 */
577
	public function get_renewal_url() {
578
		$renewal_url = add_query_arg(
579
			array(
580
				'subscription' => $this->get_id(),
581
				'key'          => $this->get_key(),
582
				'action'       => 'renew',
583
			), home_url()
584
		);
585
586
		return $renewal_url;
587
	}
588
589
	/**
590
	 * Get all the payments for this subscription.
591
	 *
592
	 * @return array
593
	 */
594
	public function get_payments() {
595
		return get_pronamic_payments_by_meta( '_pronamic_payment_subscription_id', $this->id );
596
	}
597
598
	/**
599
	 * Get the first payment of this subscription.
600
	 *
601
	 * @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...
602
	 */
603
	public function get_first_payment() {
604
		$payments = $this->get_payments();
605
606
		if ( count( $payments ) > 0 ) {
607
			return $payments[0];
608
		}
609
610
		return null;
611
	}
612
613
	/**
614
	 * Get the start date of this subscription.
615
	 *
616
	 * @return DateTime|null
617
	 */
618
	public function get_start_date() {
619
		return $this->start_date;
620
	}
621
622
	/**
623
	 * Set the start date of this subscription.
624
	 *
625
	 * @param DateTime $date Start date.
626
	 */
627
	public function set_start_date( DateTime $date ) {
0 ignored issues
show
Unused Code introduced by
The parameter $date 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

627
	public function set_start_date( /** @scrutinizer ignore-unused */ DateTime $date ) {

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...
628
		$this->start_date = $value;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $value seems to be never defined.
Loading history...
629
	}
630
631
	/**
632
	 * Get the end date of this subscription.
633
	 *
634
	 * @return DateTime|null
635
	 */
636
	public function get_end_date() {
637
		return $this->end_date;
638
	}
639
640
	/**
641
	 * Set the end date of this subscription.
642
	 *
643
	 * @param DateTime|null $date End date.
644
	 */
645
	public function set_end_date( DateTime $date ) {
646
		$this->end_date = $date;
647
	}
648
649
	/**
650
	 * Get the expiry date of this subscription.
651
	 *
652
	 * @return DateTime
653
	 */
654
	public function get_expiry_date() {
655
		return $this->expiry_date;
656
	}
657
658
	/**
659
	 * Set the expiry date of this subscription.
660
	 *
661
	 * @param DateTime $date Expiry date.
662
	 */
663
	public function set_expiry_date( DateTime $date ) {
0 ignored issues
show
Unused Code introduced by
The parameter $date 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

663
	public function set_expiry_date( /** @scrutinizer ignore-unused */ DateTime $date ) {

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...
664
		$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...
665
	}
666
667
	/**
668
	 * Set the next payment date of this subscription.
669
	 *
670
	 * @param DateTime $date Next payment date.
671
	 */
672
	public function set_next_payment_date( DateTime $date ) {
673
		$this->next_payment = $date;
674
	}
675
676
	/**
677
	 * Get the next payment date of this subscription.
678
	 *
679
	 * @return DateTime
680
	 */
681
	public function get_next_payment_date() {
682
		return $this->next_payment;
683
	}
684
685
	/**
686
	 * Update meta.
687
	 *
688
	 * @todo  Not sure how and when this function is used.
689
	 * @param array $meta The meta data to update.
690
	 */
691
	public function update_meta( $meta ) {
692
		if ( ! is_array( $meta ) || count( $meta ) === 0 ) {
0 ignored issues
show
introduced by
The condition is_array($meta) is always true.
Loading history...
693
			return;
694
		}
695
696
		$note = sprintf(
697
			'<p>%s:</p>',
698
			__( 'Subscription changed', 'pronamic_ideal' )
699
		);
700
701
		$note .= '<dl>';
702
703
		foreach ( $meta as $key => $value ) {
704
			$this->set_meta( $key, $value );
705
706
			if ( $value instanceof DateTime ) {
707
				$value = date_i18n( __( 'l jS \o\f F Y, h:ia', 'pronamic_ideal' ), $value->getTimestamp() );
708
			}
709
710
			$note .= sprintf( '<dt>%s</dt>', esc_html( $key ) );
711
			$note .= sprintf( '<dd>%s</dd>', esc_html( $value ) );
712
		}
713
714
		$note .= '</dl>';
715
716
		$this->add_note( $note );
717
	}
718
}
719