Passed
Push — master ( 91cade...03e35c )
by Brian
04:25
created

GetPaid_Paypal_Gateway_IPN_Handler   F

Complexity

Total Complexity 60

Size/Duplication

Total Lines 469
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 169
dl 0
loc 469
rs 3.6
c 3
b 0
f 1
wmc 60

15 Methods

Rating   Name   Duplication   Size   Complexity  
A verify_ipn() 0 33 6
A __construct() 0 3 1
A get_ipn_invoice() 0 15 3
A ipn_txn_cart() 0 2 1
C ipn_txn_web_accept() 0 64 14
A validate_ipn_amount() 0 10 2
A ipn_txn_subscr_failed() 0 12 2
B ipn_txn_subscr_payment() 0 57 8
A ipn_txn_recurring_payment_suspended_due_to_max_failed_payment() 0 12 2
B validate_ipn() 0 41 7
A ipn_txn_subscr_cancel() 0 12 2
A validate_ipn_currency() 0 11 2
A ipn_txn_subscr_signup() 0 37 5
A ipn_txn_subscr_eot() 0 12 2
A validate_ipn_receiver_email() 0 13 3

How to fix   Complexity   

Complex Class

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

1
<?php
2
/**
3
 * Paypal payment gateway IPN handler
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * Paypal Payment Gateway IPN handler class.
11
 *
12
 */
13
class GetPaid_Paypal_Gateway_IPN_Handler {
14
15
	/**
16
	 * Payment method id.
17
	 *
18
	 * @var string
19
	 */
20
	protected $id = 'paypal';
21
22
	/**
23
	 * Payment method object.
24
	 *
25
	 * @var GetPaid_Paypal_Gateway
26
	 */
27
	protected $gateway;
28
29
	/**
30
	 * Class constructor.
31
	 *
32
	 * @param GetPaid_Paypal_Gateway $gateway
33
	 */
34
	public function __construct( $gateway ) {
35
		$this->gateway = $gateway;
36
		$this->verify_ipn();
37
	}
38
39
	/**
40
	 * Processes ipns and marks payments as complete.
41
	 *
42
	 * @return void
43
	 */
44
	public function verify_ipn() {
45
46
		wpinv_error_log( 'GetPaid PayPal IPN Handler', false );
47
48
		// Validate the IPN.
49
		if ( empty( $_POST ) || ! $this->validate_ipn() ) {
50
			wp_die( 'PayPal IPN Request Failure', 500 );
51
		}
52
53
		// Process the IPN.
54
		$posted  = wp_unslash( $_POST );
55
		$invoice = $this->get_ipn_invoice( $posted );
56
57
		// Abort if it was not paid by our gateway.
58
		if ( $this->id != $invoice->get_gateway() ) {
59
			wpinv_error_log( 'Aborting, Invoice was not paid via PayPal', false );
60
			wp_die( 'Invoice not paid via PayPal', 200 );
61
		}
62
63
		$posted['payment_status'] = isset( $posted['payment_status'] ) ? sanitize_key( strtolower( $posted['payment_status'] ) ) : '';
64
		$posted['txn_type']       = sanitize_key( strtolower( $posted['txn_type'] ) );
65
66
		wpinv_error_log( 'Payment status:' . $posted['payment_status'], false );
67
		wpinv_error_log( 'IPN Type:' . $posted['txn_type'], false );
68
69
		if ( method_exists( $this, 'ipn_txn_' . $posted['txn_type'] ) ) {
70
			call_user_func( array( $this, 'ipn_txn_' . $posted['txn_type'] ), $invoice, $posted );
71
			wpinv_error_log( 'Done processing IPN', false );
72
			wp_die( 'Processed', 200 );
73
		}
74
75
		wpinv_error_log( 'Aborting, Unsupported IPN type:' . $posted['txn_type'], false );
76
		wp_die( 'Unsupported IPN type', 200 );
77
78
	}
79
80
	/**
81
	 * Retrieves IPN Invoice.
82
	 *
83
	 * @param array $posted
84
	 * @return WPInv_Invoice
85
	 */
86
	protected function get_ipn_invoice( $posted ) {
87
88
		wpinv_error_log( 'Retrieving PayPal IPN Response Invoice', false );
89
90
		if ( ! empty( $posted['custom'] ) ) {
91
			$invoice = new WPInv_Invoice( $posted['custom'] );
92
93
			if ( $invoice->exists() ) {
94
				wpinv_error_log( 'Found invoice #' . $invoice->get_number(), false );
95
				return $invoice;
96
			}
97
		}
98
99
		wpinv_error_log( 'Could not retrieve the associated invoice.', false );
100
		wp_die( 'Could not retrieve the associated invoice.', 200 );
101
	}
102
103
	/**
104
	 * Check PayPal IPN validity.
105
	 */
106
	protected function validate_ipn() {
107
108
		wpinv_error_log( 'Validating PayPal IPN response', false );
109
110
		// Retrieve the associated invoice.
111
		$posted  = wp_unslash( $_POST );
112
		$invoice = $this->get_ipn_invoice( $posted );
113
114
		if ( $this->gateway->is_sandbox( $invoice ) ) {
115
			wpinv_error_log( $posted, 'Invoice was processed in sandbox hence logging the posted data', false );
116
		}
117
118
		// Validate the IPN.
119
		$posted['cmd'] = '_notify-validate';
120
121
		// Send back post vars to paypal.
122
		$params = array(
123
			'body'        => $posted,
124
			'timeout'     => 60,
125
			'httpversion' => '1.1',
126
			'compress'    => false,
127
			'decompress'  => false,
128
			'user-agent'  => 'GetPaid/' . WPINV_VERSION,
129
		);
130
131
		// Post back to get a response.
132
		$response = wp_safe_remote_post( $this->gateway->is_sandbox( $invoice ) ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr', $params );
133
134
		// Check to see if the request was valid.
135
		if ( ! is_wp_error( $response ) && $response['response']['code'] < 300 && strstr( $response['body'], 'VERIFIED' ) ) {
136
			wpinv_error_log( 'Received valid response from PayPal IPN: ' . $response['body'], false );
137
			return true;
138
		}
139
140
		if ( is_wp_error( $response ) ) {
141
			wpinv_error_log( $response->get_error_message(), 'Received invalid response from PayPal IPN' );
142
			return false;
143
		}
144
145
		wpinv_error_log( $response['body'], 'Received invalid response from PayPal IPN' );
146
		return false;
147
148
	}
149
150
	/**
151
	 * Check currency from IPN matches the invoice.
152
	 *
153
	 * @param WPInv_Invoice $invoice          Invoice object.
154
	 * @param string   $currency currency to validate.
155
	 */
156
	protected function validate_ipn_currency( $invoice, $currency ) {
157
158
		if ( strtolower( $invoice->get_currency() ) !== strtolower( $currency ) ) {
159
160
			/* translators: %s: currency code. */
161
			$invoice->update_status( 'wpi-processing', sprintf( __( 'Validation error: PayPal currencies do not match (code %s).', 'invoicing' ), $currency ) );
162
163
			wpinv_error_log( "Currencies do not match: {$currency} instead of {$invoice->get_currency()}", 'IPN Error', __FILE__, __LINE__, true );
164
		}
165
166
		wpinv_error_log( $currency, 'Validated IPN Currency', false );
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $file of wpinv_error_log(). ( Ignorable by Annotation )

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

166
		wpinv_error_log( $currency, 'Validated IPN Currency', /** @scrutinizer ignore-type */ false );
Loading history...
167
	}
168
169
	/**
170
	 * Check payment amount from IPN matches the invoice.
171
	 *
172
	 * @param WPInv_Invoice $invoice          Invoice object.
173
	 * @param float   $amount amount to validate.
174
	 */
175
	protected function validate_ipn_amount( $invoice, $amount ) {
176
		if ( number_format( $invoice->get_total(), 2, '.', '' ) !== number_format( $amount, 2, '.', '' ) ) {
177
178
			/* translators: %s: Amount. */
179
			$invoice->update_status( 'wpi-processing', sprintf( __( 'Validation error: PayPal amounts do not match (gross %s).', 'invoicing' ), $amount ) );
180
181
			wpinv_error_log( "Amounts do not match: {$amount} instead of {$invoice->get_total()}", 'IPN Error', __FILE__, __LINE__, true );
182
		}
183
184
		wpinv_error_log( $amount, 'Validated IPN Amount', false );
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $file of wpinv_error_log(). ( Ignorable by Annotation )

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

184
		wpinv_error_log( $amount, 'Validated IPN Amount', /** @scrutinizer ignore-type */ false );
Loading history...
185
	}
186
187
	/**
188
	 * Verify receiver email from PayPal.
189
	 *
190
	 * @param WPInv_Invoice $invoice          Invoice object.
191
	 * @param string   $receiver_email Email to validate.
192
	 */
193
	protected function validate_ipn_receiver_email( $invoice, $receiver_email ) {
194
		$paypal_email = wpinv_get_option( 'paypal_email' );
195
196
		if ( $receiver_email && strcasecmp( trim( $receiver_email ), trim( $paypal_email ) ) !== 0 ) {
0 ignored issues
show
Bug introduced by
It seems like $paypal_email can also be of type false; however, parameter $string of trim() 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

196
		if ( $receiver_email && strcasecmp( trim( $receiver_email ), trim( /** @scrutinizer ignore-type */ $paypal_email ) ) !== 0 ) {
Loading history...
197
			wpinv_record_gateway_error( 'IPN Error', "IPN Response is for another account: {$receiver_email}. Your email is {$paypal_email}" );
198
199
			/* translators: %s: email address . */
200
			$invoice->update_status( 'wpi-processing', sprintf( __( 'Validation error: PayPal IPN response from a different email address (%s).', 'invoicing' ), $receiver_email ) );
201
202
			return wpinv_error_log( "IPN Response is for another account: {$receiver_email}. Your email is {$paypal_email}", 'IPN Error', __FILE__, __LINE__, true );
203
		}
204
205
		wpinv_error_log( 'Validated PayPal Email', false );
206
	}
207
208
	/**
209
	 * Handles one time payments.
210
	 *
211
	 * @param WPInv_Invoice $invoice  Invoice object.
212
	 * @param array    $posted Posted data.
213
	 */
214
	protected function ipn_txn_web_accept( $invoice, $posted ) {
215
216
		// Collect payment details
217
		$payment_status = strtolower( $posted['payment_status'] );
218
		$business_email = isset( $posted['business'] ) && is_email( $posted['business'] ) ? trim( $posted['business'] ) : trim( $posted['receiver_email'] );
219
220
		$this->validate_ipn_receiver_email( $invoice, $business_email );
221
		$this->validate_ipn_currency( $invoice, $posted['mc_currency'] );
222
223
		// Update the transaction id.
224
		if ( ! empty( $posted['txn_id'] ) ) {
225
			$invoice->set_transaction_id( wpinv_clean( $posted['txn_id'] ) );
226
			$invoice->save();
227
		}
228
229
		$invoice->add_system_note( __( 'Processing invoice IPN', 'invoicing' ) );
230
231
		// Process a refund.
232
		if ( 'refunded' === $payment_status || 'reversed' === $payment_status ) {
233
234
			update_post_meta( $invoice->get_id(), 'refunded_remotely', 1 );
235
236
			if ( ! $invoice->is_refunded() ) {
237
				$invoice->update_status( 'wpi-refunded', $posted['reason_code'] );
238
			}
239
240
			return wpinv_error_log( $posted['reason_code'], false );
241
		}
242
243
		// Process payments.
244
		if ( 'completed' === $payment_status ) {
245
246
			if ( $invoice->is_paid() && 'wpi_processing' != $invoice->get_status() ) {
247
				return wpinv_error_log( 'Aborting, Invoice #' . $invoice->get_number() . ' is already paid.', false );
248
			}
249
250
			$this->validate_ipn_amount( $invoice, $posted['mc_gross'] );
251
252
			$note = '';
253
254
			if ( ! empty( $posted['mc_fee'] ) ) {
255
				$note = sprintf( __( 'PayPal Transaction Fee %s.', 'invoicing' ), sanitize_text_field( $posted['mc_fee'] ) );
256
			}
257
258
			if ( ! empty( $posted['payer_status'] ) ) {
259
				$note = ' ' . sprintf( __( 'Buyer status %s.', 'invoicing' ), sanitize_text_field( $posted['payer_status'] ) );
260
			}
261
262
			$invoice->mark_paid( ( ! empty( $posted['txn_id'] ) ? sanitize_text_field( $posted['txn_id'] ) : '' ), trim( $note ) );
263
			return wpinv_error_log( 'Invoice marked as paid.', false );
264
265
		}
266
267
		// Pending payments.
268
		if ( 'pending' === $payment_status ) {
269
270
			/* translators: %s: pending reason. */
271
			$invoice->update_status( 'wpi-onhold', sprintf( __( 'Payment pending (%s).', 'invoicing' ), $posted['pending_reason'] ) );
272
273
			return wpinv_error_log( 'Invoice marked as "payment held".', false );
274
		}
275
276
		/* translators: %s: payment status. */
277
		$invoice->update_status( 'wpi-failed', sprintf( __( 'Payment %s via IPN.', 'invoicing' ), sanitize_text_field( $posted['payment_status'] ) ) );
278
279
	}
280
281
	/**
282
	 * Handles one time payments.
283
	 *
284
	 * @param WPInv_Invoice $invoice  Invoice object.
285
	 * @param array    $posted Posted data.
286
	 */
287
	protected function ipn_txn_cart( $invoice, $posted ) {
288
		$this->ipn_txn_web_accept( $invoice, $posted );
289
	}
290
291
	/**
292
	 * Handles subscription sign ups.
293
	 *
294
	 * @param WPInv_Invoice $invoice  Invoice object.
295
	 * @param array    $posted Posted data.
296
	 */
297
	protected function ipn_txn_subscr_signup( $invoice, $posted ) {
298
299
		wpinv_error_log( 'Processing subscription signup', false );
300
301
		// Make sure the invoice has a subscription.
302
		$subscription = getpaid_get_invoice_subscription( $invoice );
303
304
		if ( empty( $subscription ) ) {
305
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
306
		}
307
308
		wpinv_error_log( 'Found subscription #' . $subscription->get_id(), false );
309
310
		// Validate the IPN.
311
		$business_email = isset( $posted['business'] ) && is_email( $posted['business'] ) ? trim( $posted['business'] ) : trim( $posted['receiver_email'] );
312
		$this->validate_ipn_receiver_email( $invoice, $business_email );
313
		$this->validate_ipn_currency( $invoice, $posted['mc_currency'] );
314
315
		// Activate the subscription.
316
		$duration = strtotime( $subscription->get_expiration() ) - strtotime( $subscription->get_date_created() );
317
		$subscription->set_date_created( current_time( 'mysql' ) );
318
		$subscription->set_expiration( date( 'Y-m-d H:i:s', ( current_time( 'timestamp' ) + $duration ) ) );
319
		$subscription->set_profile_id( sanitize_text_field( $posted['subscr_id'] ) );
320
		$subscription->activate();
321
322
		// Set the transaction id.
323
		if ( ! empty( $posted['txn_id'] ) ) {
324
			$invoice->add_note( sprintf( __( 'PayPal Transaction ID: %s', 'invoicing' ), $posted['txn_id'] ), false, false, true );
325
			$invoice->set_transaction_id( $posted['txn_id'] );
326
		}
327
328
		// Update the payment status.
329
		$invoice->mark_paid();
330
331
		$invoice->add_note( sprintf( __( 'PayPal Subscription ID: %s', 'invoicing' ), $posted['subscr_id'] ), false, false, true );
332
333
		wpinv_error_log( 'Subscription started.', false );
334
	}
335
336
	/**
337
	 * Handles subscription renewals.
338
	 *
339
	 * @param WPInv_Invoice $invoice  Invoice object.
340
	 * @param array    $posted Posted data.
341
	 */
342
	protected function ipn_txn_subscr_payment( $invoice, $posted ) {
343
344
		// Make sure the invoice has a subscription.
345
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
346
347
		if ( empty( $subscription ) ) {
348
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Bug introduced by
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
349
		}
350
351
		wpinv_error_log( 'Found subscription #' . $subscription->get_id(), false );
352
353
		// PayPal sends a subscr_payment for the first payment too.
354
		$date_completed = getpaid_format_date( $invoice->get_date_completed() );
355
		$date_created   = getpaid_format_date( $invoice->get_date_created() );
356
		$today_date     = getpaid_format_date( current_time( 'mysql' ) );
357
		$payment_date   = getpaid_format_date( $posted['payment_date'] );
358
		$subscribe_date = getpaid_format_date( $subscription->get_date_created() );
359
		$dates          = array_filter( compact( 'date_completed', 'date_created', 'subscribe_date' ) );
360
361
		foreach ( $dates as $date ) {
362
363
			if ( $date !== $today_date && $date !== $payment_date ) {
364
				continue;
365
			}
366
367
			if ( ! empty( $posted['txn_id'] ) ) {
368
				$invoice->set_transaction_id( sanitize_text_field( $posted['txn_id'] ) );
369
				$invoice->add_note( wp_sprintf( __( 'PayPal Transaction ID: %s', 'invoicing' ), sanitize_text_field( $posted['txn_id'] ) ), false, false, true );
370
			}
371
372
			return $invoice->mark_paid();
373
374
		}
375
376
		wpinv_error_log( 'Processing subscription renewal payment for the invoice ' . $invoice->get_id(), false );
377
378
		// Abort if the payment is already recorded.
379
		if ( wpinv_get_id_by_transaction_id( $posted['txn_id'] ) ) {
380
			return wpinv_error_log( 'Aborting, Transaction ' . $posted['txn_id'] . ' has already been processed', false );
381
		}
382
383
		$args = array(
384
			'transaction_id' => $posted['txn_id'],
385
			'gateway'        => $this->id,
386
		);
387
388
		$invoice = wpinv_get_invoice( $subscription->add_payment( $args ) );
389
390
		if ( empty( $invoice ) ) {
391
			return;
392
		}
393
394
		$invoice->add_note( wp_sprintf( __( 'PayPal Transaction ID: %s', 'invoicing' ), $posted['txn_id'] ), false, false, true );
395
		$invoice->add_note( wp_sprintf( __( 'PayPal Subscription ID: %s', 'invoicing' ), $posted['subscr_id'] ), false, false, true );
396
397
		$subscription->renew();
398
		wpinv_error_log( 'Subscription renewed.', false );
399
400
	}
401
402
	/**
403
	 * Handles subscription cancelations.
404
	 *
405
	 * @param WPInv_Invoice $invoice  Invoice object.
406
	 */
407
	protected function ipn_txn_subscr_cancel( $invoice ) {
408
409
		// Make sure the invoice has a subscription.
410
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
411
412
		if ( empty( $subscription ) ) {
413
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Bug introduced by
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
414
		}
415
416
		wpinv_error_log( 'Processing subscription cancellation for the invoice ' . $invoice->get_id(), false );
417
		$subscription->cancel();
418
		wpinv_error_log( 'Subscription cancelled.', false );
419
420
	}
421
422
	/**
423
	 * Handles subscription completions.
424
	 *
425
	 * @param WPInv_Invoice $invoice  Invoice object.
426
	 * @param array    $posted Posted data.
427
	 */
428
	protected function ipn_txn_subscr_eot( $invoice ) {
429
430
		// Make sure the invoice has a subscription.
431
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
432
433
		if ( empty( $subscription ) ) {
434
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Bug introduced by
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
435
		}
436
437
		wpinv_error_log( 'Processing subscription end of life for the invoice ' . $invoice->get_id(), false );
438
		$subscription->complete();
439
		wpinv_error_log( 'Subscription completed.', false );
440
441
	}
442
443
	/**
444
	 * Handles subscription fails.
445
	 *
446
	 * @param WPInv_Invoice $invoice  Invoice object.
447
	 * @param array    $posted Posted data.
448
	 */
449
	protected function ipn_txn_subscr_failed( $invoice ) {
450
451
		// Make sure the invoice has a subscription.
452
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
453
454
		if ( empty( $subscription ) ) {
455
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Bug introduced by
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
456
		}
457
458
		wpinv_error_log( 'Processing subscription payment failure for the invoice ' . $invoice->get_id(), false );
459
		$subscription->failing();
460
		wpinv_error_log( 'Subscription marked as failing.', false );
461
462
	}
463
464
	/**
465
	 * Handles subscription suspensions.
466
	 *
467
	 * @param WPInv_Invoice $invoice  Invoice object.
468
	 * @param array    $posted Posted data.
469
	 */
470
	protected function ipn_txn_recurring_payment_suspended_due_to_max_failed_payment( $invoice ) {
471
472
		// Make sure the invoice has a subscription.
473
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
474
475
		if ( empty( $subscription ) ) {
476
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Bug introduced by
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
477
		}
478
479
		wpinv_error_log( 'Processing subscription cancellation due to max failed payment for the invoice ' . $invoice->get_id(), false );
480
		$subscription->cancel();
481
		wpinv_error_log( 'Subscription cancelled.', false );
482
	}
483
484
}
485