Failed Conditions
Push — develop ( f473d3...859ffd )
by Remco
05:54
created

Extension   F

Complexity

Total Complexity 60

Size/Duplication

Total Lines 615
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 21
Bugs 1 Features 0
Metric Value
eloc 247
c 21
b 1
f 0
dl 0
loc 615
ccs 0
cts 328
cp 0
rs 3.6
wmc 60

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A setup() 0 37 3
A gateway_paths() 0 4 1
B redirect_url() 0 48 6
A post_type_columns_hide() 0 6 2
A memberpress_subscription_transition_status() 0 16 3
A subscription_email_params() 0 19 3
A subscription_source_text() 0 17 1
A source_url() 0 11 1
A subscription_source_url() 0 10 1
A source_description() 0 2 1
F status_update() 0 198 27
A subscription_pre_delete() 0 21 3
A subscription_source_description() 0 2 1
A transaction_email_params() 0 32 5
A source_text() 0 18 1

How to fix   Complexity   

Complex Class

Complex classes like Extension 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 Extension, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Extension
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;
12
13
use MeprDb;
14
use MeprOptions;
15
use MeprProduct;
16
use MeprSubscription;
17
use MeprTransaction;
18
use MeprUtils;
19
use Pronamic\WordPress\Pay\AbstractPluginIntegration;
20
use Pronamic\WordPress\Pay\Payments\PaymentStatus;
21
use Pronamic\WordPress\Pay\Extensions\MemberPress\Gateways\Gateway;
22
use Pronamic\WordPress\Pay\Payments\Payment;
23
use Pronamic\WordPress\Pay\Subscriptions\Subscription;
24
use Pronamic\WordPress\Pay\Subscriptions\SubscriptionStatus;
25
26
/**
27
 * WordPress pay MemberPress extension
28
 *
29
 * @author  Remco Tolsma
30
 * @version 2.2.3
31
 * @since   1.0.0
32
 */
33
class Extension extends AbstractPluginIntegration {
34
	/**
35
	 * The slug of this addon
36
	 *
37
	 * @var string
38
	 */
39
	const SLUG = 'memberpress';
40
41
	/**
42
	 * Construct MemberPress plugin integration.
43
	 */
44
	public function __construct() {
45
		parent::__construct(
46
			array(
47
				'name' => __( 'MemberPress', 'pronamic_ideal' ),
48
			)
49
		);
50
51
		// Dependencies.
52
		$dependencies = $this->get_dependencies();
53
54
		$dependencies->add( new MemberPressDependency() );
55
	}
56
57
	/**
58
	 * Setup.
59
	 */
60
	public function setup() {
61
		\add_filter( 'pronamic_subscription_source_description_' . self::SLUG, array( $this, 'subscription_source_description' ), 10, 2 );
62
		\add_filter( 'pronamic_payment_source_description_' . self::SLUG, array( $this, 'source_description' ), 10, 2 );
63
64
		// Check if dependencies are met and integration is active.
65
		if ( ! $this->is_active() ) {
66
			return;
67
		}
68
69
		// @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprGatewayFactory.php#L48-50
70
		\add_filter( 'mepr-gateway-paths', array( $this, 'gateway_paths' ) );
71
72
		\add_filter( 'pronamic_payment_redirect_url_' . self::SLUG, array( $this, 'redirect_url' ), 10, 2 );
73
		\add_action( 'pronamic_payment_status_update_' . self::SLUG, array( $this, 'status_update' ), 10, 1 );
74
75
		\add_filter( 'pronamic_subscription_source_text_' . self::SLUG, array( $this, 'subscription_source_text' ), 10, 2 );
76
		\add_filter( 'pronamic_subscription_source_url_' . self::SLUG, array( $this, 'subscription_source_url' ), 10, 2 );
77
		\add_filter( 'pronamic_payment_source_text_' . self::SLUG, array( $this, 'source_text' ), 10, 2 );
78
		\add_filter( 'pronamic_payment_source_url_' . self::SLUG, array( $this, 'source_url' ), 10, 2 );
79
80
		\add_action( 'mepr_subscription_pre_delete', array( $this, 'subscription_pre_delete' ), 10, 1 );
81
82
		\add_action( 'mepr_subscription_transition_status', array( $this, 'memberpress_subscription_transition_status' ), 10, 3 );
83
84
		// MemberPress subscription email parameters.
85
		\add_filter( 'mepr_subscription_email_params', array( $this, 'subscription_email_params' ), 10, 2 );
86
		\add_filter( 'mepr_transaction_email_params', array( $this, 'transaction_email_params' ), 10, 2 );
87
88
		// Hide MemberPress columns for payments and subscriptions.
89
		\add_action( 'registered_post_type', array( $this, 'post_type_columns_hide' ), 15, 1 );
90
91
		if ( \is_admin() ) {
92
			$admin_subscriptions = new Admin\AdminSubscriptions();
93
			$admin_transactions  = new Admin\AdminTransactions();
94
95
			$admin_subscriptions->setup();
96
			$admin_transactions->setup();
97
		}
98
	}
99
100
	/**
101
	 * Gateway paths.
102
	 *
103
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/lib/MeprGatewayFactory.php#L49
104
	 * @param string[] $paths Array with gateway paths.
105
	 * @return string[]
106
	 */
107
	public function gateway_paths( $paths ) {
108
		$paths[] = dirname( __FILE__ ) . '/../gateways/';
109
110
		return $paths;
111
	}
112
113
	/**
114
	 * Hide MemberPress columns for payments and subscriptions.
115
	 *
116
	 * @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/controllers/MeprAppCtrl.php#L129-146
117
	 *
118
	 * @param string $post_type Registered post type.
119
	 *
120
	 * @return void
121
	 */
122
	public function post_type_columns_hide( $post_type ) {
123
		if ( ! in_array( $post_type, array( 'pronamic_payment', 'pronamic_pay_subscr' ), true ) ) {
124
			return;
125
		}
126
127
		remove_filter( 'manage_edit-' . $post_type . '_columns', 'MeprAppCtrl::columns' );
128
	}
129
130
	/**
131
	 * Payment redirect URL filter.
132
	 *
133
	 * @since 1.0.1
134
	 *
135
	 * @param string  $url     Payment redirect URL.
136
	 * @param Payment $payment Payment to redirect for.
137
	 *
138
	 * @return string
139
	 */
140
	public function redirect_url( $url, Payment $payment ) {
141
		global $transaction;
142
143
		$transaction_id = $payment->get_source_id();
144
145
		$transaction = new MeprTransaction( $transaction_id );
146
147
		switch ( $payment->get_status() ) {
148
			case PaymentStatus::CANCELLED:
149
			case PaymentStatus::EXPIRED:
150
			case PaymentStatus::FAILURE:
151
				$product = $transaction->product();
152
153
				$url = add_query_arg(
154
					array(
155
						'action'   => 'payment_form',
156
						'txn'      => $transaction->trans_num,
157
						'errors'   => array(
158
							__( 'Payment failed. Please try again.', 'pronamic_ideal' ),
159
						),
160
						'_wpnonce' => wp_create_nonce( 'mepr_payment_form' ),
161
					),
162
					$product->url()
163
				);
164
165
				break;
166
			case PaymentStatus::SUCCESS:
167
				// @link https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/models/MeprOptions.php#L768-782
168
				$mepr_options = MeprOptions::fetch();
169
170
				$product         = new MeprProduct( $transaction->product_id );
171
				$sanitized_title = sanitize_title( $product->post_title );
172
173
				$args = array(
174
					'membership_id' => $product->ID,
175
					'membership'    => $sanitized_title,
176
					'trans_num'     => $transaction->trans_num,
177
				);
178
179
				$url = $mepr_options->thankyou_page_url( http_build_query( $args ) );
180
181
				break;
182
			case PaymentStatus::OPEN:
183
			default:
184
				break;
185
		}
186
187
		return $url;
188
	}
189
190
	/**
191
	 * Update lead status of the specified payment.
192
	 *
193
	 * @param Payment $payment The payment whose status is updated.
194
	 * @return void
195
	 */
196
	public function status_update( Payment $payment ) {
197
		$payment_source_id = $payment->get_source_id();
198
199
		$memberpress_transaction = MemberPress::get_transaction_by_id( $payment_source_id );
200
201
		/**
202
		 * If we can't find a MemberPress transaction by the payment source ID
203
		 * we can't update the MemberPress transaction, bail out early.
204
		 */
205
		if ( null === $memberpress_transaction ) {
206
			return;
207
		}
208
209
		/**
210
		 * Subscription.
211
		 */
212
		$subscription = $payment->get_subscription();
213
214
		if ( null !== $subscription ) {
215
			$subscription_source_id = $subscription->get_source_id();
216
217
			$memberpress_subscription = MemberPress::get_subscription_by_id( $subscription_source_id );
218
219
			if ( null === $memberpress_subscription ) {
220
				/**
221
				 * @todo What to-do?
222
				 */
223
				throw new \Exception( 'Cannot find MemberPress subscription.' );
224
			}
225
226
			// Same source ID and first transaction ID for recurring payment means we need to add a new transaction.
227
			if ( $payment_source_id === $subscription_source_id ) {
228
				// First transaction.
229
				$first_txn = $memberpress_subscription->first_txn();
230
231
				if ( false === $first_txn || ! ( $first_txn instanceof MeprTransaction ) ) {
232
					$first_txn             = new MeprTransaction();
233
					$first_txn->user_id    = $memberpress_subscription->user_id;
234
					$first_txn->product_id = $memberpress_subscription->product_id;
0 ignored issues
show
Bug Best Practice introduced by
The property product_id does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
235
					$first_txn->coupon_id  = $memberpress_subscription->coupon_id;
0 ignored issues
show
Bug Best Practice introduced by
The property coupon_id does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
236
					$first_txn->gateway    = null;
237
				}
238
239
				// Transaction number.
240
				$trans_num = $payment->get_transaction_id();
241
242
				if ( empty( $trans_num ) ) {
243
					$trans_num = uniqid();
244
				}
245
246
				// New transaction.
247
				$end_date = $payment->get_end_date();
248
249
				if ( null === $end_date ) {
250
					$periods = $payment->get_periods();
251
252
					if ( ! empty( $periods ) ) {
253
						$end_date = $periods[0]->get_end_date();
254
					}
255
				}
256
257
				$expires_at = MeprUtils::ts_to_mysql_date( $end_date->getTimestamp(), 'Y-m-d 23:59:59' );
258
259
				// Determine gateway (can be different from original, i.e. via mandate update).
260
				$old_gateway = $memberpress_subscription->gateway;
261
262
				$new_gateway = $old_gateway;
263
264
				$mepr_options = MeprOptions::fetch();
265
266
				$mepr_gateways = $mepr_options->payment_methods();
267
268
				foreach ( $mepr_gateways as $mepr_gateway ) {
269
					// Check valid gateway.
270
					if ( ! ( $mepr_gateway instanceof \MeprBaseRealGateway ) ) {
271
						continue;
272
					}
273
274
					// Check payment method.
275
					$payment_method = \str_replace( 'pronamic_pay_', '', $mepr_gateway->key );
276
277
					if ( $payment_method !== $payment->get_method() ) {
278
						continue;
279
					}
280
281
					// Set gateway, as payment method matches with this gateway.
282
					$new_gateway = $mepr_gateway->id;
283
284
					$memberpress_subscription->gateway = $new_gateway;
285
286
					$memberpress_subscription->store();
287
288
					// Set expires at to subscription expiration date.
289
					$expires_at = $memberpress_subscription->expires_at;
290
				}
291
292
				$memberpress_transaction                  = new MeprTransaction();
293
				$memberpress_transaction->created_at      = $payment->post->post_date_gmt;
0 ignored issues
show
Bug Best Practice introduced by
The property created_at does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
294
				$memberpress_transaction->user_id         = $first_txn->user_id;
295
				$memberpress_transaction->product_id      = $first_txn->product_id;
296
				$memberpress_transaction->coupon_id       = $first_txn->coupon_id;
297
				$memberpress_transaction->gateway         = $new_gateway;
298
				$memberpress_transaction->trans_num       = $trans_num;
0 ignored issues
show
Bug Best Practice introduced by
The property trans_num does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
299
				$memberpress_transaction->txn_type        = MeprTransaction::$payment_str;
0 ignored issues
show
Bug Best Practice introduced by
The property txn_type does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
300
				$memberpress_transaction->status          = MeprTransaction::$pending_str;
0 ignored issues
show
Bug Best Practice introduced by
The property status does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
301
				$memberpress_transaction->expires_at      = $expires_at;
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...
302
				$memberpress_transaction->subscription_id = $memberpress_subscription->id;
0 ignored issues
show
Bug Best Practice introduced by
The property subscription_id does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
303
304
				$memberpress_transaction->set_gross( $payment->get_total_amount()->get_value() );
305
306
				$memberpress_transaction->store();
307
308
				// Set source ID.
309
				$payment->set_meta( 'source_id', $memberpress_transaction->id );
310
311
				$payment->source_id = $memberpress_transaction->id;
312
313
				if ( MeprSubscription::$active_str === $memberpress_subscription->status && $old_gateway === $new_gateway ) {
314
					/*
315
					 * We create a 'confirmed' 'subscription_confirmation'
316
					 * transaction for a grace period of 15 days.
317
					 *
318
					 * Transactions of type "subscription_confirmation" with a
319
					 * status of "confirmed" are hidden in the UI, and are used
320
					 * as a way to provide free trial periods and the 24 hour
321
					 * grace period on a recurring subscription signup.
322
					 *
323
					 * @link https://docs.memberpress.com/article/219-where-is-data-stored.
324
					 */
325
					$subscription_confirmation                  = new MeprTransaction();
326
					$subscription_confirmation->created_at      = $payment->post->post_date_gmt;
327
					$subscription_confirmation->user_id         = $first_txn->user_id;
328
					$subscription_confirmation->product_id      = $first_txn->product_id;
329
					$subscription_confirmation->coupon_id       = $first_txn->coupon_id;
330
					$subscription_confirmation->gateway         = $new_gateway;
331
					$subscription_confirmation->trans_num       = $trans_num;
332
					$subscription_confirmation->txn_type        = MeprTransaction::$subscription_confirmation_str;
333
					$subscription_confirmation->status          = MeprTransaction::$confirmed_str;
334
					$subscription_confirmation->subscription_id = $memberpress_subscription->id;
335
					$subscription_confirmation->expires_at      = MeprUtils::ts_to_mysql_date( strtotime( $payment->post->post_date_gmt ) + MeprUtils::days( 15 ), 'Y-m-d 23:59:59' );
336
337
					$subscription_confirmation->set_subtotal( 0.00 );
338
339
					$subscription_confirmation->store();
340
				}
341
			}
342
		}
343
344
		$should_update = ! MemberPress::transaction_has_status(
345
			$memberpress_transaction,
346
			array(
347
				MeprTransaction::$failed_str,
348
				MeprTransaction::$complete_str,
349
			)
350
		);
351
352
		// Allow successful recurring payments to update failed transaction.
353
		if ( $payment->get_recurring() && PaymentStatus::SUCCESS === $payment->get_status() && MeprTransaction::$failed_str === $memberpress_transaction->status ) {
354
			$should_update = true;
355
		}
356
357
		if ( $should_update ) {
358
			$gateway = new Gateway();
359
360
			$gateway->pronamic_payment = $payment;
361
			$gateway->mp_txn           = $memberpress_transaction;
362
363
			switch ( $payment->get_status() ) {
364
				case PaymentStatus::FAILURE:
365
					$gateway->record_payment_failure();
366
367
					// Set subscription 'On Hold' to prevent subsequent
368
					// successful subscriptions from awaking subscription.
369
					if ( ! $payment->get_recurring() ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $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...
370
						$subscription = $payment->get_subscription();
371
372
						if ( null !== $subscription ) {
373
							$subscription->set_status( SubscriptionStatus::ON_HOLD );
374
						}
375
					}
376
377
					break;
378
				case PaymentStatus::CANCELLED:
379
				case PaymentStatus::EXPIRED:
380
					$gateway->record_payment_failure();
381
382
					break;
383
				case PaymentStatus::SUCCESS:
384
					if ( $payment->get_recurring() ) {
385
						$gateway->record_subscription_payment();
386
					} else {
387
						$gateway->record_payment();
388
					}
389
390
					break;
391
				case PaymentStatus::OPEN:
392
				default:
393
					break;
394
			}
395
		}
396
	}
397
398
	/**
399
	 * Subscription deleted.
400
	 *
401
	 * @param int $subscription_id MemberPress subscription id.
402
	 * @return void
403
	 */
404
	public function subscription_pre_delete( $subscription_id ) {
405
		$subscription = get_pronamic_subscription_by_meta( '_pronamic_subscription_source_id', $subscription_id );
406
407
		if ( ! $subscription ) {
408
			return;
409
		}
410
411
		// Add note.
412
		$note = sprintf(
413
			/* translators: %s: MemberPress */
414
			__( '%s subscription deleted.', 'pronamic_ideal' ),
415
			__( 'MemberPress', 'pronamic_ideal' )
416
		);
417
418
		$subscription->add_note( $note );
419
420
		// The status of canceled or completed subscriptions will not be changed automatically.
421
		if ( ! in_array( $subscription->get_status(), array( SubscriptionStatus::CANCELLED, SubscriptionStatus::COMPLETED ), true ) ) {
422
			$subscription->set_status( SubscriptionStatus::CANCELLED );
423
424
			$subscription->save();
425
		}
426
	}
427
428
	/**
429
	 * Subscription email parameters.
430
	 *
431
	 * @param array<string, string> $params                   Email parameters.
432
	 * @param MeprSubscription      $memberpress_subscription MemberPress subscription.
433
	 * @return array<string, string>
434
	 */
435
	public function subscription_email_params( $params, MeprSubscription $memberpress_subscription ) {
436
		$subscriptions = \get_pronamic_subscriptions_by_source( 'memberpress', $memberpress_subscription->id );
437
438
		if ( empty( $subscriptions ) ) {
439
			return $params;
440
		}
441
442
		$subscription = reset( $subscriptions );
443
444
		// Add parameters.
445
		$next_payment_date = $subscription->get_next_payment_date();
446
447
		return \array_merge(
448
			$params,
449
			array(
450
				'pronamic_subscription_id'           => (string) $subscription->get_id(),
451
				'pronamic_subscription_cancel_url'   => $subscription->get_cancel_url(),
452
				'pronamic_subscription_renewal_url'  => $subscription->get_renewal_url(),
453
				'pronamic_subscription_renewal_date' => null === $next_payment_date ? '' : \date_i18n( \get_option( 'date_format' ), $next_payment_date->getTimestamp() ),
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format') can also be of type false; however, parameter $format of date_i18n() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

453
				'pronamic_subscription_renewal_date' => null === $next_payment_date ? '' : \date_i18n( /** @scrutinizer ignore-type */ \get_option( 'date_format' ), $next_payment_date->getTimestamp() ),
Loading history...
454
			)
455
		);
456
	}
457
458
	/**
459
	 * Transaction email parameters.
460
	 *
461
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/helpers/MeprTransactionsHelper.php#L233
462
	 * @param array<string, string> $params      Parameters.
463
	 * @param MeprTransaction       $transaction MemberPress transaction.
464
	 * @return array<string, string>
465
	 */
466
	public function transaction_email_params( $params, MeprTransaction $transaction ) {
467
		$payments = \get_pronamic_payments_by_source( 'memberpress', $transaction->id );
468
469
		if ( null === $payments ) {
0 ignored issues
show
introduced by
The condition null === $payments is always false.
Loading history...
470
			return $params;
471
		}
472
473
		$payment = \reset( $payments );
474
475
		if ( false === $payment ) {
476
			return $params;
477
		}
478
479
		// Get subscription.
480
		$periods = $payment->get_periods();
481
482
		if ( null === $periods ) {
483
			return $params;
484
		}
485
486
		$period = \reset( $periods );
487
488
		if ( false === $period ) {
489
			return $params;
490
		}
491
492
		$subscription = $period->get_phase()->get_subscription();
493
494
		// Add parameters.
495
		$memberpress_subscription = new MeprSubscription( $subscription->get_source_id() );
496
497
		return $this->subscription_email_params( $params, $memberpress_subscription );
498
	}
499
500
	/**
501
	 * Source text.
502
	 *
503
	 * @param string  $text    Source text.
504
	 * @param Payment $payment Payment to create the source text for.
505
	 *
506
	 * @return string
507
	 */
508
	public function source_text( $text, Payment $payment ) {
509
		$text = __( 'MemberPress', 'pronamic_ideal' ) . '<br />';
510
511
		$text .= sprintf(
512
			'<a href="%s">%s</a>',
513
			add_query_arg(
514
				array(
515
					'page'   => 'memberpress-trans',
516
					'action' => 'edit',
517
					'id'     => $payment->source_id,
518
				),
519
				admin_url( 'admin.php' )
520
			),
521
			/* translators: %s: payment source id */
522
			sprintf( __( 'Transaction %s', 'pronamic_ideal' ), $payment->source_id )
523
		);
524
525
		return $text;
526
	}
527
528
	/**
529
	 * Subscription source text.
530
	 *
531
	 * @param string       $text         Source text.
532
	 * @param Subscription $subscription Subscription to create the source text for.
533
	 *
534
	 * @return string
535
	 */
536
	public function subscription_source_text( $text, Subscription $subscription ) {
537
		$text = __( 'MemberPress', 'pronamic_ideal' ) . '<br />';
538
539
		$text .= sprintf(
540
			'<a href="%s">%s</a>',
541
			add_query_arg(
542
				array(
543
					'page'         => 'memberpress-subscriptions',
544
					'subscription' => $subscription->source_id,
545
				),
546
				admin_url( 'admin.php' )
547
			),
548
			/* translators: %s: payment source id */
549
			sprintf( __( 'Subscription %s', 'pronamic_ideal' ), $subscription->source_id )
550
		);
551
552
		return $text;
553
	}
554
555
	/**
556
	 * Source description.
557
	 *
558
	 * @param string  $description Description.
559
	 * @param Payment $payment     Payment to create the description for.
560
	 *
561
	 * @return string
562
	 */
563
	public function source_description( $description, Payment $payment ) {
564
		return __( 'MemberPress Transaction', 'pronamic_ideal' );
565
	}
566
567
	/**
568
	 * Subscription source description.
569
	 *
570
	 * @param string       $description  Description.
571
	 * @param Subscription $subscription Subscription to create the description for.
572
	 *
573
	 * @return string
574
	 */
575
	public function subscription_source_description( $description, Subscription $subscription ) {
576
		return __( 'MemberPress Subscription', 'pronamic_ideal' );
577
	}
578
579
	/**
580
	 * Source URL.
581
	 *
582
	 * @param string  $url     URL.
583
	 * @param Payment $payment The payment to create the source URL for.
584
	 *
585
	 * @return string
586
	 */
587
	public function source_url( $url, Payment $payment ) {
588
		$url = add_query_arg(
589
			array(
590
				'page'   => 'memberpress-trans',
591
				'action' => 'edit',
592
				'id'     => $payment->source_id,
593
			),
594
			admin_url( 'admin.php' )
595
		);
596
597
		return $url;
598
	}
599
600
	/**
601
	 * Subscription source URL.
602
	 *
603
	 * @param string       $url          URL.
604
	 * @param Subscription $subscription Subscription.
605
	 *
606
	 * @return string
607
	 */
608
	public function subscription_source_url( $url, Subscription $subscription ) {
609
		$url = add_query_arg(
610
			array(
611
				'page'         => 'memberpress-subscriptions',
612
				'subscription' => $subscription->source_id,
613
			),
614
			admin_url( 'admin.php' )
615
		);
616
617
		return $url;
618
	}
619
620
	/**
621
	 * MemberPress update subscription.
622
	 *
623
	 * @link https://github.com/wp-premium/memberpress-basic/blob/1.3.18/app/controllers/MeprSubscriptionsCtrl.php#L92-L111
624
	 * @link https://github.com/wp-premium/memberpress-basic/blob/1.3.18/app/models/MeprSubscription.php#L100-L123
625
	 * @link https://github.com/wp-premium/memberpress-basic/blob/1.3.18/app/models/MeprSubscription.php#L112
626
	 * @link https://github.com/wp-premium/memberpress/blob/1.9.21/app/models/MeprSubscription.php#L122
627
	 * @param string           $status_old               Old status identifier.
628
	 * @param string           $status_new               New status identifier.
629
	 * @param MeprSubscription $memberpress_subscription MemberPress subscription object.
630
	 * @return void
631
	 */
632
	public function memberpress_subscription_transition_status( $status_old, $status_new, $memberpress_subscription ) {
633
		$subscription = get_pronamic_subscription_by_meta( '_pronamic_subscription_source_id', $memberpress_subscription->id );
634
635
		if ( empty( $subscription ) ) {
636
			return;
637
		}
638
639
		$status = SubscriptionStatuses::transform( $status_new );
640
641
		if ( null === $status ) {
642
			return;
643
		}
644
645
		$subscription->set_status( $status );
646
647
		$subscription->save();
648
	}
649
}
650