Failed Conditions
Push — develop ( 611b60...45e009 )
by Reüel
05:45
created

Gateway::display_options_form()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 30
nc 2
nop 0
dl 0
loc 34
ccs 0
cts 22
cp 0
crap 6
rs 9.44
c 0
b 0
f 0
1
<?php
2
/**
3
 * Gateway
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2021 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay\Extensions\MemberPress
9
 */
10
11
namespace Pronamic\WordPress\Pay\Extensions\MemberPress\Gateways;
12
13
use MeprBaseRealGateway;
14
use MeprEmailFactory;
15
use MeprOptions;
16
use MeprProduct;
17
use MeprSubscription;
18
use MeprTransaction;
19
use MeprTransactionsHelper;
20
use MeprUser;
21
use MeprUtils;
22
use MeprView;
23
use Pronamic\WordPress\Pay\Core\PaymentMethods;
24
use Pronamic\WordPress\Pay\Core\Util as Core_Util;
25
use Pronamic\WordPress\Pay\Payments\Payment;
26
use Pronamic\WordPress\Pay\Plugin;
27
use Pronamic\WordPress\Pay\Extensions\MemberPress\Pronamic;
28
use Pronamic\WordPress\Pay\Subscriptions\SubscriptionStatus;
29
use ReflectionClass;
30
31
/**
32
 * WordPress pay MemberPress gateway
33
 *
34
 * @author  Remco Tolsma
35
 * @version 2.3.1
36
 * @since   1.0.0
37
 */
38
class Gateway extends MeprBaseRealGateway {
39
	/**
40
	 * Payment method.
41
	 *
42
	 * @var string|null
43
	 */
44
	protected $payment_method;
45
46
	/**
47
	 * Class alias.
48
	 *
49
	 * @var string
50
	 */
51
	protected $class_alias;
52
53
	/**
54
	 * Key.
55
	 * 
56
	 * The key property is not defined in the MemberPress library,
57
	 * but it is a MemberPress property.
58
	 * 
59
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php
60
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L12
61
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/helpers/MeprOptionsHelper.php#L192
62
	 * @var string
63
	 */
64
	public $key;
65
66
	/**
67
	 * MemberPress transaction.
68
	 *
69
	 * @var MeprTransaction|null
70
	 */
71
	private $memberpress_transaction;
72
73
	/**
74
	 * Pronamic payment.
75
	 *
76
	 * @var Payment|null
77
	 */
78
	private $pronamic_payment;
79
80
	/**
81
	 * Constructs and initialize gateway.
82
	 * 
83
	 * @param string      $class_alias    Class alias.
84
	 * @param string|null $payment_method Payment method.
85
	 */
86
	public function __construct( $class_alias = 'MeprPronamicGateway', $payment_method = null ) {
87
		$this->class_alias = $class_alias;
88
89
		$this->payment_method = $payment_method;
90
91
		// Set the name of this gateway.
92
		// @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprBaseGateway.php#L12-13.
93
		$this->name = __( 'Pronamic', 'pronamic_ideal' );
94
95
		if ( ! empty( $this->payment_method ) ) {
96
			$this->name = sprintf(
97
				/* translators: %s: payment method name */
98
				__( 'Pronamic - %s', 'pronamic_ideal' ),
99
				PaymentMethods::get_name( $this->payment_method )
100
			);
101
		}
102
103
		// Set the default settings.
104
		// @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprBaseGateway.php#L72-73.
105
		$this->set_defaults();
106
107
		// Set the capabilities of this gateway.
108
		// @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprBaseGateway.php#L36-37.
109
		$this->capabilities = array();
110
111
		// Setup the notification actions for this gateway.
112
		$this->notifiers = array();
113
114
		// Support single-page checkout.
115
		$this->has_spc_form = true;
116
117
		// Key.
118
		$key = 'pronamic_pay';
119
120
		if ( null !== $this->payment_method ) {
121
			$key = sprintf( 'pronamic_pay_%s', $this->payment_method );
122
		}
123
124
		$this->key = $key;
125
	}
126
127
	/**
128
	 * Load the specified settings.
129
	 *
130
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L73-L74
131
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprGatewayFactory.php#L18
132
	 * @param mixed $settings MemberPress gateway settings array.
133
	 * @return void
134
	 */
135
	public function load( $settings ) {
136
		$this->settings = (object) $settings;
137
138
		$this->set_defaults();
139
	}
140
141
	/**
142
	 * Get icon function (this is not a MemberPress function).
143
	 *
144
	 * @since 1.0.2
145
	 * @return string|null
146
	 */
147
	private function get_icon() {
148
		return PaymentMethods::get_icon_url( $this->payment_method );
149
	}
150
151
	/**
152
	 * Set the default settings.
153
	 *
154
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L76-L77
155
	 * @return void
156
	 */
157
	protected function set_defaults() {
158
		if ( ! isset( $this->settings ) ) {
159
			$this->settings = array();
160
		}
161
162
		$this->settings = (object) array_merge(
163
			array(
164
				'gateway'   => $this->class_alias,
165
				'id'        => $this->generate_id(),
166
				'label'     => '',
167
				'use_label' => true,
168
				'icon'      => $this->get_icon(),
169
				'use_icon'  => true,
170
				'desc'      => '',
171
				'use_desc'  => true,
172
				'config_id' => '',
173
				'email'     => '',
174
				'sandbox'   => false,
175
				'debug'     => false,
176
			),
177
			(array) $this->settings
178
		);
179
180
		$this->id        = $this->settings->id;
181
		$this->label     = $this->settings->label;
182
		$this->use_label = $this->settings->use_label;
183
		$this->icon      = $this->settings->icon;
184
		$this->use_icon  = $this->settings->use_icon;
185
		$this->desc      = $this->settings->desc;
186
		$this->use_desc  = $this->settings->use_desc;
187
	}
188
189
	/**
190
	 * Process payment.
191
	 *
192
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L149-L152
193
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L520-L585
194
	 * @param MeprTransaction $txn MemberPress transaction object.
195
	 * @return void
196
	 */
197
	public function process_payment( $txn ) {
198
199
	}
200
201
	/**
202
	 * Set record data.
203
	 * 
204
	 * @param Payment         $pronamic_payment        Pronamic payment.
205
	 * @param MeprTransaction $memberpress_transaction MemberPress transaction.
206
	 */
207
	public function set_record_data( $pronamic_payment, $memberpress_transaction ) {
208
		$this->pronamic_payment        = $pronamic_payment;
209
		$this->memberpress_transaction = $memberpress_transaction;
210
	}
211
212
	/**
213
	 * Record subscription payment.
214
	 *
215
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L170-L175
216
	 * @return void
217
	 */
218
	public function record_subscription_payment() {
219
		if ( nulll === $this->pronamic_payment ) {
0 ignored issues
show
Bug introduced by
The constant Pronamic\WordPress\Pay\E...berPress\Gateways\nulll was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
220
			return;
221
		}
222
223
		if ( nulll === $this->memberpress_transaction ) {
224
			return;
225
		}
226
227
		$transaction = $this->memberpress_transaction;
228
229
		$transaction->status     = MeprTransaction::$complete_str;
230
		$transaction->expires_at = MeprUtils::ts_to_mysql_date( $this->pronamic_payment->get_end_date()->getTimestamp(), 'Y-m-d 23:59:59' );
0 ignored issues
show
Bug Best Practice introduced by
The property expires_at does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
The method get_end_date() does not exist on null. ( Ignorable by Annotation )

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

230
		$transaction->expires_at = MeprUtils::ts_to_mysql_date( $this->pronamic_payment->/** @scrutinizer ignore-call */ get_end_date()->getTimestamp(), 'Y-m-d 23:59:59' );

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...
231
		$transaction->store();
0 ignored issues
show
Bug introduced by
The method store() does not exist on null. ( Ignorable by Annotation )

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

231
		$transaction->/** @scrutinizer ignore-call */ 
232
                store();

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...
232
233
		$subscription = $transaction->subscription();
234
235
		if ( $subscription ) {
236
			$should_activate = ! \in_array(
237
				$subscription->status,
238
				array(
239
					MeprSubscription::$active_str,
240
					MeprSubscription::$cancelled_str,
241
				),
242
				true
243
			);
244
245
			if ( $should_activate ) {
246
				$subscription->status = MeprSubscription::$active_str;
247
				$subscription->store();
248
			}
249
250
			$subscription->expire_confirmation_txn();
251
252
			$subscription->limit_payment_cycles();
253
		}
254
255
		/**
256
		 * Send transaction receipt notices.
257
		 * 
258
		 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprUtils.php#L1396-L1418
259
		 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprAuthorizeGateway.php#L249
260
		 */
261
		MeprUtils::send_transaction_receipt_notices( $transaction );
262
	}
263
264
	/**
265
	 * Record payment failure.
266
	 *
267
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L177-L178
268
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L833-L910
269
	 * @return void
270
	 */
271
	public function record_payment_failure() {
272
		if ( nulll === $this->pronamic_payment ) {
0 ignored issues
show
Bug introduced by
The constant Pronamic\WordPress\Pay\E...berPress\Gateways\nulll was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
273
			return;
274
		}
275
276
		if ( nulll === $this->memberpress_transaction ) {
277
			return;
278
		}
279
280
		$transaction = $this->memberpress_transaction;
281
282
		// @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/models/MeprTransaction.php#L50.
283
		$transaction->status = MeprTransaction::$failed_str;
284
		$transaction->store();
285
286
		// Expire associated subscription transactions for non-recurring payments.
287
		if ( ! ( isset( $this->pronamic_payment ) && $this->pronamic_payment->get_recurring() ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->pronamic_payment->get_recurring() of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
288
			$subscription = $transaction->subscription();
289
290
			if ( $subscription ) {
291
				$subscription->expire_txns();
292
				$subscription->store();
293
			}
294
		}
295
296
		/**
297
		 * Send failed transaction notices.
298
		 * 
299
		 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprUtils.php#L1515-L1528
300
		 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprAuthorizeGateway.php#L299
301
		 */
302
		MeprUtils::send_failed_txn_notices( $transaction );
303
	}
304
305
	/**
306
	 * Record payment.
307
	 *
308
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L154-L159
309
	 * @return void
310
	 */
311
	public function record_payment() {
312
		if ( nulll === $this->pronamic_payment ) {
0 ignored issues
show
Bug introduced by
The constant Pronamic\WordPress\Pay\E...berPress\Gateways\nulll was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
313
			return;
314
		}
315
316
		if ( nulll === $this->memberpress_transaction ) {
317
			return;
318
		}
319
320
		$transaction = $this->memberpress_transaction;
321
322
		$transaction->status = MeprTransaction::$complete_str;
323
324
		// This will only work before maybe_cancel_old_sub is run.
325
		$upgrade   = $transaction->is_upgrade();
326
		$downgrade = $transaction->is_downgrade();
327
328
		$event_transaction = $transaction->maybe_cancel_old_sub();
329
330
		$subscription = $transaction->subscription();
331
332
		if ( $subscription ) {
333
			$event_subscription = $subscription->maybe_cancel_old_sub();
334
335
			$subscription->status     = MeprSubscription::$active_str;
336
			$subscription->created_at = $transaction->created_at;
337
			$subscription->store();
338
339
			if ( false === $event_transaction && false !== $event_subscription ) {
340
				$event_transaction = $event_subscription;
341
			}
342
		}
343
344
		$transaction->store();
345
346
		// Send upgrade/downgrade notices.
347
		$product = $transaction->product();
348
349
		if ( 'lifetime' === $product->period_type ) {
350
			if ( $upgrade ) {
351
				$this->upgraded_sub( $transaction, $event_transaction );
352
			} elseif ( $downgrade ) {
353
				$this->downgraded_sub( $transaction, $event_transaction );
354
			} else {
355
				$this->new_sub( $transaction );
356
			}
357
		}
358
359
		/**
360
		 * Send signup notices.
361
		 * 
362
		 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprUtils.php#L1361-L1390
363
		 */
364
		MeprUtils::send_signup_notices( $transaction );
365
366
		/**
367
		 * Send transaction receipt notices.
368
		 * 
369
		 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprUtils.php#L1396-L1418
370
		 */
371
		MeprUtils::send_transaction_receipt_notices( $transaction );
372
	}
373
374
	/**
375
	 * Process refund.
376
	 *
377
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L161-L163
378
	 * @param MeprTransaction $txn MemberPress transaction object.
379
	 * @return void
380
	 */
381
	public function process_refund( MeprTransaction $txn ) {
382
383
	}
384
385
	/**
386
	 * Record refund.
387
	 *
388
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L165-L168
389
	 * @return void
390
	 */
391
	public function record_refund() {
392
393
	}
394
395
	/**
396
	 * Process trial payment.
397
	 *
398
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L180-L187
399
	 * @param MeprTransaction $transaction MemberPress transaction object.
400
	 * @return void
401
	 */
402
	public function process_trial_payment( $transaction ) {
403
404
	}
405
406
	/**
407
	 * Record trial payment.
408
	 *
409
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L189-L191
410
	 * @param MeprTransaction $transaction MemberPress transaction object.
411
	 * @return void
412
	 */
413
	public function record_trial_payment( $transaction ) {
414
415
	}
416
417
	/**
418
	 * Process create subscription.
419
	 *
420
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L193-L197
421
	 * @param MeprTransaction $txn MemberPress transaction object.
422
	 * @return void
423
	 */
424
	public function process_create_subscription( $txn ) {
425
426
	}
427
428
	/**
429
	 * Record create subscription.
430
	 *
431
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L199-L204
432
	 * @return void
433
	 */
434
	public function record_create_subscription() {
435
436
	}
437
438
	/**
439
	 * Process update subscription.
440
	 *
441
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L206
442
	 * @param int $sub_id Subscription ID.
443
	 * @return void
444
	 */
445
	public function process_update_subscription( $sub_id ) {
446
447
	}
448
449
	/**
450
	 * Record update subscription.
451
	 *
452
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L208-L212
453
	 * @return void
454
	 */
455
	public function record_update_subscription() {
456
457
	}
458
459
	/**
460
	 * Process suspend subscription.
461
	 *
462
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L214-L216
463
	 * @param int $sub_id Subscription id.
464
	 * @return void
465
	 */
466
	public function process_suspend_subscription( $sub_id ) {
467
		if ( ! MeprSubscription::exists( $sub_id ) ) {
468
			return;
469
		}
470
471
		$sub = new MeprSubscription( $sub_id );
472
473
		if ( MeprSubscription::$suspended_str === $sub->status ) {
474
			// Subscription is already suspended.
475
			return;
476
		}
477
478
		$subscription = get_pronamic_subscription_by_meta( '_pronamic_subscription_source_id', $sub->id );
479
480
		if ( ! $subscription ) {
481
			return;
482
		}
483
484
		$sub->status = MeprSubscription::$suspended_str;
485
486
		$sub->store();
487
488
		// Send suspended subscription notices.
489
		MeprUtils::send_suspended_sub_notices( $sub );
490
491
		$note = sprintf(
492
			/* translators: %s: extension name */
493
			__( '%s subscription on hold.', 'pronamic_ideal' ),
494
			__( 'MemberPress', 'pronamic_ideal' )
495
		);
496
497
		$subscription->add_note( $note );
498
499
		// The status of canceled or completed subscriptions will not be changed automatically.
500
		if ( ! in_array( $subscription->get_status(), array( SubscriptionStatus::CANCELLED, SubscriptionStatus::COMPLETED ), true ) ) {
501
			$subscription->set_status( SubscriptionStatus::ON_HOLD );
502
503
			$subscription->save();
504
		}
505
	}
506
507
	/**
508
	 * Record suspend subscription.
509
	 *
510
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L218-L221
511
	 * @return void
512
	 */
513
	public function record_suspend_subscription() {
514
515
	}
516
517
	/**
518
	 * Process resume subscription.
519
	 *
520
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L223-L225
521
	 * @param int $sub_id Subscription id.
522
	 * @return void
523
	 */
524
	public function process_resume_subscription( $sub_id ) {
525
		if ( ! MeprSubscription::exists( $sub_id ) ) {
526
			return;
527
		}
528
529
		$sub = new MeprSubscription( $sub_id );
530
531
		if ( MeprSubscription::$active_str === $sub->status ) {
532
			// Subscription is already active.
533
			return;
534
		}
535
536
		$subscription = get_pronamic_subscription_by_meta( '_pronamic_subscription_source_id', $sub->id );
537
538
		if ( ! $subscription ) {
539
			return;
540
		}
541
542
		$sub->status = MeprSubscription::$active_str;
543
544
		$sub->store();
545
546
		// Check if prior txn is expired yet or not, if so create a temporary txn so the user can access the content immediately.
547
		$prior_txn = $sub->latest_txn();
548
549
		if ( false === $prior_txn || ! ( $prior_txn instanceof MeprTransaction ) || strtotime( $prior_txn->expires_at ) < time() ) {
550
			$txn                  = new MeprTransaction();
551
			$txn->subscription_id = $sub->id;
552
			$txn->trans_num       = $sub->subscr_id . '-' . uniqid();
553
			$txn->status          = MeprTransaction::$confirmed_str;
554
			$txn->txn_type        = MeprTransaction::$subscription_confirmation_str;
555
			$txn->response        = (string) $sub;
556
			$txn->expires_at      = MeprUtils::ts_to_mysql_date( time() + MeprUtils::days( 1 ), 'Y-m-d 23:59:59' );
557
558
			$txn->set_subtotal( 0.00 ); // Just a confirmation txn.
559
560
			$txn->store();
561
		}
562
563
		// Send resumed subscription notices.
564
		MeprUtils::send_resumed_sub_notices( $sub );
565
566
		// Add note.
567
		$note = sprintf(
568
			/* translators: %s: extension name */
569
			__( '%s subscription reactivated.', 'pronamic_ideal' ),
570
			__( 'MemberPress', 'pronamic_ideal' )
571
		);
572
573
		$subscription->add_note( $note );
574
575
		// The status of canceled or completed subscriptions will not be changed automatically.
576
		if ( ! in_array( $subscription->get_status(), array( SubscriptionStatus::CANCELLED, SubscriptionStatus::COMPLETED ), true ) ) {
577
			$subscription->set_status( SubscriptionStatus::ACTIVE );
578
579
			$subscription->save();
580
		}
581
	}
582
583
	/**
584
	 * Record resume subscription.
585
	 *
586
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L227-L230
587
	 * @return void
588
	 */
589
	public function record_resume_subscription() {
590
591
	}
592
593
	/**
594
	 * Process cancel subscription.
595
	 *
596
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L232-L236
597
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L1687-L1715
598
	 * @param int $sub_id Subscription id.
599
	 * @return void
600
	 */
601
	public function process_cancel_subscription( $sub_id ) {
602
		if ( ! MeprSubscription::exists( $sub_id ) ) {
603
			return;
604
		}
605
606
		$sub = new MeprSubscription( $sub_id );
607
608
		if ( MeprSubscription::$cancelled_str === $sub->status ) {
609
			// Subscription is already cancelled.
610
			return;
611
		}
612
613
		$subscription = get_pronamic_subscription_by_meta( '_pronamic_subscription_source_id', $sub->id );
614
615
		if ( ! $subscription ) {
616
			return;
617
		}
618
619
		// Add note.
620
		$note = sprintf(
621
			/* translators: %s: extension name */
622
			__( '%s subscription cancelled.', 'pronamic_ideal' ),
623
			__( 'MemberPress', 'pronamic_ideal' )
624
		);
625
626
		$subscription->add_note( $note );
627
628
		// The status of canceled or completed subscriptions will not be changed automatically.
629
		if ( ! in_array( $subscription->get_status(), array( SubscriptionStatus::CANCELLED, SubscriptionStatus::COMPLETED ), true ) ) {
630
			$subscription->set_status( SubscriptionStatus::CANCELLED );
631
632
			$subscription->next_payment_date          = null;
633
			$subscription->next_payment_delivery_date = null;
634
635
			// Delete next payment post meta.
636
			$subscription->set_meta( 'next_payment', null );
637
			$subscription->set_meta( 'next_payment_delivery_date', null );
638
639
			$subscription->save();
640
		}
641
642
		// Cancel MemberPress subscription.
643
		$sub->status = MeprSubscription::$cancelled_str;
644
645
		$sub->store();
646
647
		// Expire the grace period (confirmation) if no completed payments have come through.
648
		if ( (int) $sub->txn_count <= 0 ) {
649
			$sub->expire_txns();
650
		}
651
652
		$sub->limit_reached_actions();
653
654
		// Send cancelled subscription notices.
655
		MeprUtils::send_cancelled_sub_notices( $sub );
656
	}
657
658
	/**
659
	 * Record cancel subscription.
660
	 *
661
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L238-L242
662
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L1717-L1753
663
	 * @return void
664
	 */
665
	public function record_cancel_subscription() {
666
667
	}
668
669
	/**
670
	 * Process signup form.
671
	 *
672
	 * Gets called when the signup form is posted used for running any payment
673
	 * method specific actions when processing the customer signup form.
674
	 *
675
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L244-L247
676
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L1755-L1764
677
	 * @param MeprTransaction $txn MemberPress transaction object.
678
	 * @return void
679
	 */
680
	public function process_signup_form( $txn ) {
681
682
	}
683
684
	/**
685
	 * Payment redirect.
686
	 * 
687
	 * Note: this is not a MemberPress method.
688
	 *
689
	 * @since 1.0.2
690
	 * @param MeprTransaction $txn MemberPress transaction object.
691
	 * @return void
692
	 * @throws \Exception Throws exception on gateway payment start error.
693
	 */
694
	private function payment_redirect( $txn ) {
695
		// Gateway.
696
		$config_id = $this->get_config_id();
697
698
		$gateway = Plugin::get_gateway( $config_id );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $gateway is correct as Pronamic\WordPress\Pay\P...get_gateway($config_id) targeting Pronamic\WordPress\Pay\Plugin::get_gateway() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
699
700
		if ( null === $gateway ) {
0 ignored issues
show
introduced by
The condition null === $gateway is always true.
Loading history...
701
			return;
702
		}
703
704
		// Create Pronamic payment.
705
		$txn = new MeprTransaction( $txn->id );
706
707
		$payment = Pronamic::get_payment( $txn );
708
709
		$payment->config_id = $config_id;
710
		$payment->method    = $this->payment_method;
711
712
		$error = null;
713
714
		try {
715
			$payment = Plugin::start_payment( $payment );
716
		} catch ( \Exception $e ) {
717
			$error = $e;
718
		}
719
720
		/*
721
		 * Update trial transaction.
722
		 *
723
		 * Notes:
724
		 * - MemberPress also uses trial amount for prorated upgrade/downgrade
725
		 * - Not updated BEFORE payment start, as transaction total amount is used for subscription amount.
726
		 * - Reload transaction to make sure actual status is being used (i.e. on free downgrade).
727
		 */
728
		$txn = new MeprTransaction( $txn->id );
729
730
		$subscription = $txn->subscription();
731
732
		if ( $subscription && $subscription->in_trial() ) {
733
			$txn->expires_at = MeprUtils::ts_to_mysql_date( $payment->get_end_date()->getTimestamp(), 'Y-m-d 23:59:59' );
734
735
			$txn->set_subtotal( $subscription->trial_amount );
736
			$txn->store();
737
		}
738
739
		if ( $error instanceof \Exception ) {
740
			// Rethrow error, caught by MemberPress.
741
			throw $error;
742
		}
743
744
		// Redirect.
745
		$gateway->redirect( $payment );
746
	}
747
748
	/**
749
	 * Display payment page.
750
	 *
751
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L249-L253
752
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L1766-L1768
753
	 * @param MeprTransaction $txn MemberPress transaction object.
754
	 * @return void
755
	 * @throws \Exception Throws exception on gateway payment start error.
756
	 */
757
	public function display_payment_page( $txn ) {
758
		// Gateway.
759
		$config_id = $this->get_config_id();
760
761
		$gateway = Plugin::get_gateway( $config_id );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $gateway is correct as Pronamic\WordPress\Pay\P...get_gateway($config_id) targeting Pronamic\WordPress\Pay\Plugin::get_gateway() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
762
763
		if ( null === $gateway ) {
0 ignored issues
show
introduced by
The condition null === $gateway is always true.
Loading history...
764
			return;
765
		}
766
767
		// Redirect payment on empty input HTML.
768
		$gateway->set_payment_method( $this->payment_method );
769
770
		$html = $gateway->get_input_html();
771
772
		if ( empty( $html ) ) {
773
			$this->payment_redirect( $txn );
774
		}
775
	}
776
777
	/**
778
	 * Process payment form.
779
	 *
780
	 * @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprBaseGateway.php#L239-289
781
	 * @link https://github.com/wp-premium/memberpress-basic/blob/1.3.18/app/controllers/MeprCheckoutCtrl.php#L336
782
	 * @link https://github.com/wp-premium/memberpress-basic/blob/1.3.18/app/gateways/MeprPayPalGateway.php#L1011
783
	 *
784
	 * @param MeprTransaction $txn MemberPress transaction object.
785
	 *
786
	 * @return void
787
	 * @throws \Exception Throws exception on gateway payment start error.
788
	 */
789
	public function process_payment_form( $txn ) {
790
		// Gateway.
791
		$config_id = $this->get_config_id();
792
793
		$gateway = Plugin::get_gateway( $config_id );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $gateway is correct as Pronamic\WordPress\Pay\P...get_gateway($config_id) targeting Pronamic\WordPress\Pay\Plugin::get_gateway() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
794
795
		if ( null === $gateway ) {
0 ignored issues
show
introduced by
The condition null === $gateway is always true.
Loading history...
796
			return;
797
		}
798
799
		// Redirect.
800
		$this->payment_redirect( $txn );
801
	}
802
803
	/**
804
	 * Enqueue payment form scripts.
805
	 *
806
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprBaseGateway.php#L255-L258
807
	 * @return void
808
	 */
809
	public function enqueue_payment_form_scripts() {
810
811
	}
812
813
	/**
814
	 * Display payment form.
815
	 *
816
	 * This spits out html for the payment form on the registration / payment
817
	 * page for the user to fill out for payment.
818
	 *
819
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/controllers/MeprCheckoutCtrl.php#L571
820
	 * @param float    $amount     Transaction amount to create a payment form for.
821
	 * @param MeprUser $user       MemberPress user object.
822
	 * @param int      $product_id Product ID.
823
	 * @param int      $txn_id     Transaction ID.
824
	 * @return void
825
	 */
826
	public function display_payment_form( $amount, $user, $product_id, $txn_id ) {
827
		// Gateway.
828
		$config_id = $this->get_config_id();
829
830
		$gateway = Plugin::get_gateway( $config_id );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $gateway is correct as Pronamic\WordPress\Pay\P...get_gateway($config_id) targeting Pronamic\WordPress\Pay\Plugin::get_gateway() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
831
832
		if ( null === $gateway ) {
0 ignored issues
show
introduced by
The condition null === $gateway is always true.
Loading history...
833
834
			$admin_message = null;
835
836
			if ( \current_user_can( 'manage_options' ) ) {
837
				$admin_message = __( 'For admins only: check payment method settings in MemberPress.', 'pronamic_ideal' );
838
			}
839
840
			printf(
841
				'<div class="mp_wrapper mp_payment_form_wrapper"><ul><li>%s</li>%s</ul></div>',
842
				\esc_html( Plugin::get_default_error_message() ),
843
				null === $admin_message ? '' : sprintf( '<li><em>%s</em></li>', \esc_html( $admin_message ) )
844
			);
845
846
			return;
847
		}
848
849
		// Invoice.
850
		$product = new MeprProduct( $product_id );
851
852
		$coupon = false;
853
854
		$txn = new MeprTransaction( $txn_id );
855
856
		// Artificially set the price of the $prd in case a coupon was used.
857
		if ( $product->price !== $amount ) {
858
			$coupon         = true;
859
			$product->price = $amount;
860
		}
861
862
		$invoice = MeprTransactionsHelper::get_invoice( $txn );
863
864
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
865
		echo $invoice;
866
867
		?>
868
		<div class="mp_wrapper mp_payment_form_wrapper">
869
			<form action="" method="post" id="payment-form" class="mepr-form" novalidate>
870
				<input type="hidden" name="mepr_process_payment_form" value="Y"/>
871
				<input type="hidden" name="mepr_transaction_id" value="<?php echo \esc_attr( (string) $txn_id ); ?>"/>
872
				<input type="hidden" name="pronamic_pay_memberpress_pay" value="1"/>
873
874
				<div class="mepr_spacer">&nbsp;</div>
875
876
				<?php
877
878
				$gateway->set_payment_method( $this->payment_method );
879
880
				// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
881
				echo $gateway->get_input_html();
882
883
				?>
884
885
				<div class="mepr_spacer">&nbsp;</div>
886
887
				<input type="submit" class="mepr-submit" value="<?php esc_attr_e( 'Pay', 'pronamic_ideal' ); ?>"/>
888
				<img src="<?php echo \esc_url( admin_url( 'images/loading.gif' ) ); ?>" style="display: none;" class="mepr-loading-gif"/>
889
				<?php MeprView::render( '/shared/has_errors', get_defined_vars() ); ?>
890
891
				<noscript>
892
					<p class="mepr_nojs">
893
						<?php esc_html_e( 'JavaScript is disabled in your browser. You will not be able to complete your purchase until you either enable JavaScript in your browser, or switch to a browser that supports it.', 'pronamic_ideal' ); ?>
894
					</p>
895
				</noscript>
896
			</form>
897
		</div>
898
		<?php
899
	}
900
901
	/**
902
	 * Single-page checkout payment fields.
903
	 *
904
	 * @return string
905
	 */
906
	public function spc_payment_fields() {
907
		// Gateway.
908
		$config_id = $this->get_config_id();
909
910
		$gateway = Plugin::get_gateway( $config_id );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $gateway is correct as Pronamic\WordPress\Pay\P...get_gateway($config_id) targeting Pronamic\WordPress\Pay\Plugin::get_gateway() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
911
912
		if ( null === $gateway ) {
0 ignored issues
show
introduced by
The condition null === $gateway is always true.
Loading history...
913
			return '';
914
		}
915
916
		// Input HTML.
917
		$gateway->set_payment_method( $this->payment_method );
918
919
		$html = $gateway->get_input_html();
920
921
		if ( empty( $html ) ) {
922
			return '';
923
		}
924
925
		return $html;
926
	}
927
928
	/**
929
	 * Validate payment form.
930
	 *
931
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/controllers/MeprCheckoutCtrl.php#L648
932
	 * @param string[] $errors Array with errors.
933
	 * @return string[]
934
	 */
935
	public function validate_payment_form( $errors ) {
936
		return $errors;
937
	}
938
939
	/**
940
	 * Display options form.
941
	 *
942
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/views/admin/options/gateway.php#L41
943
	 * @return void
944
	 */
945
	public function display_options_form() {
946
		$mepr_options = MeprOptions::fetch();
947
948
		?>
949
		<table>
950
			<tr>
951
				<?php
952
953
				$name = sprintf(
954
					'%s[%s][%s]',
955
					$mepr_options->integrations_str,
956
					$this->id,
957
					'config_id'
958
				);
959
960
				?>
961
				<td>
962
					<?php esc_html_e( 'Configuration', 'pronamic_ideal' ); ?>
963
				</td>
964
				<td>
965
					<select name="<?php echo esc_attr( $name ); ?>">
966
						<?php
967
968
						foreach ( Plugin::get_config_select_options( $this->payment_method ) as $value => $label ) {
969
							printf(
970
								'<option value="%s" %s>%s</option>',
971
								esc_attr( $value ),
972
								selected( $value, $this->settings->config_id, false ),
973
								esc_html( $label )
974
							);
975
						}
976
977
						?>
978
					</select>
979
				</td>
980
			</tr>
981
		</table>
982
		<?php
983
	}
984
985
	/**
986
	 * Validate options form.
987
	 *
988
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/models/MeprOptions.php#L468
989
	 * @ilnk https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L2006-L2026
990
	 * @param string[] $errors Array with errors.
991
	 * @return string[]
992
	 */
993
	public function validate_options_form( $errors ) {
994
		return $errors;
995
	}
996
997
	/**
998
	 * Enqueue user account scripts.
999
	 *
1000
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/controllers/MeprAccountCtrl.php#L126
1001
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L2028-L2044
1002
	 * @return void
1003
	 */
1004
	public function enqueue_user_account_scripts() {
1005
1006
	}
1007
1008
	/**
1009
	 * Display update account form.
1010
	 *
1011
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/controllers/MeprAccountCtrl.php#L423
1012
	 * @param int      $sub_id  Subscription ID.
1013
	 * @param string[] $errors  Array with errors.
1014
	 * @param string   $message Update message.
1015
	 * @return void
1016
	 */
1017
	public function display_update_account_form( $sub_id, $errors = array(), $message = '' ) {
1018
		$subscriptions = \get_pronamic_subscriptions_by_source( 'memberpress', (int) $sub_id );
1019
1020
		$message = \__( 'The payment method for this subscription can not be updated manually.', 'pronamic_ideal' );
1021
1022
		if ( \is_array( $subscriptions ) ) {
0 ignored issues
show
introduced by
The condition is_array($subscriptions) is always true.
Loading history...
1023
			$subscription = \array_shift( $subscriptions );
1024
1025
			$message = \sprintf(
1026
				/* translators: %s: mandate selection URL anchor */
1027
				\__( 'To update the payment method for this subscription, please visit the %s page.', 'pronamic_ideal' ),
1028
				\sprintf(
1029
					'<a href="%1$s" title="%2$s">%3$s</a>',
1030
					\esc_url( $subscription->get_mandate_selection_url() ),
1031
					\esc_attr( \__( 'payment method update', 'pronamic_ideal' ) ),
1032
					\esc_html( \__( 'payment method update', 'pronamic_ideal' ) )
1033
				)
1034
			);
1035
		}
1036
1037
		?>
1038
1039
		<h3>
1040
			<?php echo \esc_html( __( 'Update payment method', 'pronamic_ideal' ) ); ?>
1041
		</h3>
1042
1043
		<div>
1044
			<?php echo \wp_kses_post( $message ); ?>
1045
		</div>
1046
1047
		<?php
1048
	}
1049
1050
	/**
1051
	 * Validate update account form.
1052
	 *
1053
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprAuthorizeGateway.php#L1182-L1197
1054
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L2100-L2103
1055
	 * @param string[] $errors Array with errors.
1056
	 * @return string[]
1057
	 */
1058
	public function validate_update_account_form( $errors = array() ) {
1059
		return $errors;
1060
	}
1061
1062
	/**
1063
	 * Process update account form.
1064
	 *
1065
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/controllers/MeprAccountCtrl.php#L430
1066
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L2105-L2111
1067
	 * @param int $sub_id Subscription ID.
1068
	 * @return void
1069
	 */
1070
	public function process_update_account_form( $sub_id ) {
1071
1072
	}
1073
1074
	/**
1075
	 * Is test mode.
1076
	 *
1077
	 * @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprBaseGateway.php#L374-375
1078
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L2113-L2121
1079
	 * @return boolean
1080
	 */
1081
	public function is_test_mode() {
1082
		return false;
1083
	}
1084
1085
	/**
1086
	 * Force SSL.
1087
	 *
1088
	 * @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprBaseGateway.php#L377-378
1089
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/gateways/MeprStripeGateway.php#L2123-L2125
1090
	 * @return boolean
1091
	 */
1092
	public function force_ssl() {
1093
		return false;
1094
	}
1095
1096
	/**
1097
	 * Get config ID.
1098
	 *
1099
	 * @return string|int|null
1100
	 */
1101
	protected function get_config_id() {
1102
		// Get config ID setting.
1103
		$config_id = $this->settings->config_id;
1104
1105
		// Check empty config ID.
1106
		if ( empty( $config_id ) ) {
1107
			$config_id = \get_option( 'pronamic_pay_config_id' );
1108
		}
1109
1110
		// Check empty config ID.
1111
		if ( empty( $config_id ) ) {
1112
			$config_id = null;
1113
		}
1114
1115
		return $config_id;
1116
	}
1117
}
1118