Passed
Push — develop ( fa95f9...3d441d )
by Remco
04:50
created

Extension   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 302
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 302
rs 10
c 0
b 0
f 0
wmc 30

10 Methods

Rating   Name   Duplication   Size   Complexity  
A bootstrap() 0 2 1
A memberpress_subscription_transition_status() 0 12 2
A gateway_paths() 0 4 1
B redirect_url() 0 45 6
A source_url() 0 8 1
A __construct() 0 14 1
C status_update() 0 79 13
A subscription_pre_delete() 0 21 3
A source_description() 0 2 1
A source_text() 0 15 1
1
<?php
2
/**
3
 * Extension
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2018 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 MeprOptions;
14
use MeprProduct;
15
use MeprTransaction;
16
use MeprSubscription;
17
use Pronamic\WordPress\Pay\Core\Statuses;
18
use Pronamic\WordPress\Pay\Payments\Payment;
0 ignored issues
show
Bug introduced by
The type Pronamic\WordPress\Pay\Payments\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...
19
20
/**
21
 * WordPress pay MemberPress extension
22
 *
23
 * @author  Remco Tolsma
24
 * @version 2.0.0
25
 * @since   1.0.0
26
 */
27
class Extension {
28
	/**
29
	 * The slug of this addon
30
	 *
31
	 * @var string
32
	 */
33
	const SLUG = 'memberpress';
34
35
	/**
36
	 * Bootstrap
37
	 */
38
	public static function bootstrap() {
39
		new self();
40
	}
41
42
	/**
43
	 * Constructs and initializes the MemberPress extension.
44
	 */
45
	public function __construct() {
46
		// @see https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprGatewayFactory.php#L48-50
47
		add_filter( 'mepr-gateway-paths', array( $this, 'gateway_paths' ) );
48
49
		add_filter( 'pronamic_payment_redirect_url_' . self::SLUG, array( __CLASS__, 'redirect_url' ), 10, 2 );
50
		add_action( 'pronamic_payment_status_update_' . self::SLUG, array( __CLASS__, 'status_update' ), 10, 1 );
51
52
		add_filter( 'pronamic_payment_source_text_' . self::SLUG, array( __CLASS__, 'source_text' ), 10, 2 );
53
		add_filter( 'pronamic_payment_source_description_' . self::SLUG, array( __CLASS__, 'source_description' ), 10, 2 );
54
		add_filter( 'pronamic_payment_source_url_' . self::SLUG, array( __CLASS__, 'source_url' ), 10, 2 );
55
56
		add_action( 'mepr_subscription_pre_delete', array( $this, 'subscription_pre_delete' ), 10, 1 );
57
58
		add_action( 'mepr_subscription_transition_status', array( $this, 'memberpress_subscription_transition_status' ), 10, 3 );
59
	}
60
61
	/**
62
	 * Gateway paths.
63
	 *
64
	 * @see https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/lib/MeprGatewayFactory.php#L48-50
65
	 *
66
	 * @param array $paths Array with gateway paths.
67
	 * @return array
68
	 */
69
	public function gateway_paths( $paths ) {
70
		$paths[] = dirname( __FILE__ ) . '/../gateways/';
71
72
		return $paths;
73
	}
74
75
	/**
76
	 * Payment redirect URL filter.
77
	 *
78
	 * @since 1.0.1
79
	 *
80
	 * @param string  $url     Payment redirect URL.
81
	 * @param Payment $payment Payment to redirect for.
82
	 *
83
	 * @return string
84
	 */
85
	public static function redirect_url( $url, Payment $payment ) {
86
		global $transaction;
87
88
		$transaction_id = $payment->get_source_id();
89
90
		$transaction = new MeprTransaction( $transaction_id );
91
92
		switch ( $payment->get_status() ) {
93
			case Statuses::CANCELLED:
94
			case Statuses::EXPIRED:
95
			case Statuses::FAILURE:
96
				$product = $transaction->product();
97
98
				$url = add_query_arg(
99
					array(
100
						'action'   => 'payment_form',
101
						'txn'      => $transaction->trans_num,
102
						'_wpnonce' => wp_create_nonce( 'mepr_payment_form' ),
103
					),
104
					$product->url()
105
				);
106
107
				break;
108
			case Statuses::SUCCESS:
109
				// @see https://gitlab.com/pronamic/memberpress/blob/1.2.4/app/models/MeprOptions.php#L768-782
110
				$mepr_options = MeprOptions::fetch();
111
112
				$product         = new MeprProduct( $transaction->product_id );
113
				$sanitized_title = sanitize_title( $product->post_title );
114
115
				$args = array(
116
					'membership_id' => $product->ID,
117
					'membership'    => $sanitized_title,
118
					'trans_num'     => $transaction->trans_num,
119
				);
120
121
				$url = $mepr_options->thankyou_page_url( http_build_query( $args ) );
122
123
				break;
124
			case Statuses::OPEN:
125
			default:
126
				break;
127
		}
128
129
		return $url;
130
	}
131
132
	/**
133
	 * Update lead status of the specified payment.
134
	 *
135
	 * @see https://github.com/Charitable/Charitable/blob/1.1.4/includes/gateways/class-charitable-gateway-paypal.php#L229-L357
136
	 *
137
	 * @param Payment $payment The payment whose status is updated.
138
	 */
139
	public static function status_update( Payment $payment ) {
140
		global $transaction;
141
142
		$transaction_id = $payment->get_source_id();
143
144
		$transaction = new MeprTransaction( $transaction_id );
145
146
		if ( $payment->get_recurring() ) {
147
			$sub = $transaction->subscription();
148
149
			// Same source ID and first transaction ID for recurring payment means we need to add a new transaction.
150
			if ( $payment->get_source_id() === $sub->first_txn_id ) {
151
				// First transaction.
152
				$first_txn = $sub->first_txn();
153
154
				if ( false === $first_txn || ! ( $first_txn instanceof MeprTransaction ) ) {
155
					$first_txn             = new MeprTransaction();
156
					$first_txn->user_id    = $sub->user_id;
157
					$first_txn->product_id = $sub->product_id;
158
					$first_txn->coupon_id  = $sub->coupon_id;
159
				}
160
161
				// Transaction number.
162
				$trans_num = $payment->get_transaction_id();
163
164
				if ( empty( $trans_num ) ) {
165
					$trans_num = uniqid();
166
				}
167
168
				// New transaction.
169
				$txn                  = new MeprTransaction();
170
				$txn->created_at      = $payment->post->post_date_gmt;
171
				$txn->user_id         = $first_txn->user_id;
172
				$txn->product_id      = $first_txn->product_id;
173
				$txn->coupon_id       = $first_txn->coupon_id;
174
				$txn->gateway         = $transaction->gateway;
175
				$txn->trans_num       = $trans_num;
176
				$txn->txn_type        = MeprTransaction::$payment_str;
177
				$txn->status          = MeprTransaction::$pending_str;
178
				$txn->subscription_id = $sub->id;
179
180
				$txn->set_gross( $payment->get_amount()->get_amount() );
181
182
				$txn->store();
183
184
				update_post_meta( $payment->get_id(), '_pronamic_payment_source_id', $txn->id );
185
186
				$transaction = $txn;
187
			}
188
		}
189
190
		$should_update = ! MemberPress::transaction_has_status( $transaction, array(
191
			MeprTransaction::$failed_str,
192
			MeprTransaction::$complete_str,
193
		) );
194
195
		if ( $should_update ) {
196
			$gateway = new Gateway();
197
198
			$gateway->mp_txn = $transaction;
199
200
			switch ( $payment->get_status() ) {
201
				case Statuses::CANCELLED:
202
				case Statuses::EXPIRED:
203
				case Statuses::FAILURE:
204
					$gateway->record_payment_failure();
205
206
					break;
207
				case Statuses::SUCCESS:
208
					if ( $payment->get_recurring() ) {
209
						$gateway->record_subscription_payment();
210
					} else {
211
						$gateway->record_payment();
212
					}
213
214
					break;
215
				case Statuses::OPEN:
216
				default:
217
					break;
218
			}
219
		}
220
	}
221
222
	/**
223
	 * Subscription deleted.
224
	 *
225
	 * @param int $subscription_id MemberPress subscription id.
226
	 */
227
	public function subscription_pre_delete( $subscription_id ) {
228
		$subscription = get_pronamic_subscription_by_meta( '_pronamic_subscription_memberpress_subscription_id', $subscription_id );
0 ignored issues
show
Bug introduced by
The function get_pronamic_subscription_by_meta was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

228
		$subscription = /** @scrutinizer ignore-call */ get_pronamic_subscription_by_meta( '_pronamic_subscription_memberpress_subscription_id', $subscription_id );
Loading history...
229
230
		if ( ! $subscription ) {
231
			return;
232
		}
233
234
		// Add note.
235
		$note = sprintf(
236
			/* translators: %s: MemberPress */
237
			__( '%s subscription deleted.', 'pronamic_ideal' ),
238
			__( 'MemberPress', 'pronamic_ideal' )
239
		);
240
241
		$subscription->add_note( $note );
242
243
		// The status of canceled or completed subscriptions will not be changed automatically.
244
		if ( ! in_array( $subscription->get_status(), array( Statuses::CANCELLED, Statuses::COMPLETED ), true ) ) {
245
			$subscription->set_status( Statuses::CANCELLED );
246
247
			$subscription->save();
248
		}
249
	}
250
251
	/**
252
	 * Source text.
253
	 *
254
	 * @param string  $text    Source text.
255
	 * @param Payment $payment Payment to create the source text for.
256
	 *
257
	 * @return string
258
	 */
259
	public static function source_text( $text, Payment $payment ) {
260
		$text = __( 'MemberPress', 'pronamic_ideal' ) . '<br />';
261
262
		$text .= sprintf(
263
			'<a href="%s">%s</a>',
264
			add_query_arg( array(
265
				'page'   => 'memberpress-trans',
266
				'action' => 'edit',
267
				'id'     => $payment->source_id,
268
			), admin_url( 'admin.php' ) ),
269
			/* translators: %s: payment source id */
270
			sprintf( __( 'Transaction %s', 'pronamic_ideal' ), $payment->source_id )
271
		);
272
273
		return $text;
274
	}
275
276
	/**
277
	 * Source description.
278
	 *
279
	 * @param string  $description Description.
280
	 * @param Payment $payment     Payment to create the description for.
281
	 *
282
	 * @return string
283
	 */
284
	public static function source_description( $description, Payment $payment ) {
285
		return __( 'MemberPress Transaction', 'pronamic_ideal' );
286
	}
287
288
	/**
289
	 * Source URL.
290
	 *
291
	 * @param string  $url     URL.
292
	 * @param Payment $payment The payment to create the source URL for.
293
	 *
294
	 * @return string
295
	 */
296
	public static function source_url( $url, Payment $payment ) {
297
		$url = add_query_arg( array(
298
			'page'   => 'memberpress-trans',
299
			'action' => 'edit',
300
			'id'     => $payment->source_id,
301
		), admin_url( 'admin.php' ) );
302
303
		return $url;
304
	}
305
306
	/**
307
	 * MemberPress update subscription.
308
	 *
309
	 * @link https://github.com/wp-premium/memberpress-basic/blob/1.3.18/app/controllers/MeprSubscriptionsCtrl.php#L92-L111
310
	 * @link https://github.com/wp-premium/memberpress-basic/blob/1.3.18/app/models/MeprSubscription.php#L100-L123
311
	 * @link https://github.com/wp-premium/memberpress-basic/blob/1.3.18/app/models/MeprSubscription.php#L112
312
	 *
313
	 * @param string           $status_old               Old status identifier.
314
	 * @param string           $status_new               New status identifier.
315
	 * @param MeprSubscription $memberpress_subscription MemberPress subscription object.
316
	 */
317
	public function memberpress_subscription_transition_status( $status_old, $status_new, $memberpress_subscription ) {
318
		$pronamic_subscription = get_pronamic_subscription_by_meta( '_pronamic_subscription_memberpress_subscription_id', $memberpress_subscription->id );
0 ignored issues
show
Bug introduced by
The function get_pronamic_subscription_by_meta was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

318
		$pronamic_subscription = /** @scrutinizer ignore-call */ get_pronamic_subscription_by_meta( '_pronamic_subscription_memberpress_subscription_id', $memberpress_subscription->id );
Loading history...
319
320
		if ( empty( $pronamic_subscription ) ) {
321
			return;
322
		}
323
324
		$pronamic_status = SubscriptionStatuses::transform( $status_new );
325
326
		$pronamic_subscription->set_status( $pronamic_status );
327
328
		$pronamic_subscription->save();
329
	}
330
}
331