Completed
Push — master ( e3a5fe...3adadd )
by Roy
05:10
created

process_subscription_payment()   F

Complexity

Conditions 19
Paths 479

Size

Total Lines 86
Code Lines 45

Duplication

Lines 86
Ratio 100 %

Importance

Changes 0
Metric Value
cc 19
eloc 45
nc 479
nop 4
dl 86
loc 86
rs 3.1946
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
/**
7
 * Compatibility class for Subscriptions.
8
 *
9
 * @extends WC_Gateway_Stripe_Sepa
10
 */
11
class WC_Stripe_Sepa_Subs_Compat extends WC_Gateway_Stripe_Sepa {
12
	/**
13
	 * Constructor
14
	 */
15 View Code Duplication
	public function __construct() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
16
		parent::__construct();
17
18
		if ( class_exists( 'WC_Subscriptions_Order' ) ) {
19
			add_action( 'woocommerce_scheduled_subscription_payment_' . $this->id, array( $this, 'scheduled_subscription_payment' ), 10, 2 );
20
			add_action( 'wcs_resubscribe_order_created', array( $this, 'delete_resubscribe_meta' ), 10 );
21
			add_action( 'wcs_renewal_order_created', array( $this, 'delete_renewal_meta' ), 10 );
22
			add_action( 'woocommerce_subscription_failing_payment_method_updated_stripe', array( $this, 'update_failing_payment_method' ), 10, 2 );
23
24
			// Display the credit card used for a subscription in the "My Subscriptions" table.
25
			add_filter( 'woocommerce_my_subscriptions_payment_method', array( $this, 'maybe_render_subscription_payment_method' ), 10, 2 );
26
27
			// Allow store managers to manually set Stripe as the payment method on a subscription.
28
			add_filter( 'woocommerce_subscription_payment_meta', array( $this, 'add_subscription_payment_meta' ), 10, 2 );
29
			add_filter( 'woocommerce_subscription_validate_payment_meta', array( $this, 'validate_subscription_payment_meta' ), 10, 2 );
30
			add_filter( 'wc_stripe_display_save_payment_method_checkbox', array( $this, 'maybe_hide_save_checkbox' ) );
31
		}
32
	}
33
34
	/**
35
	 * Handles the return from processing the payment for Stripe Checkout.
36
	 *
37
	 * @since 4.1.0
38
	 */
39
	public function stripe_checkout_return_handler() {
40
		return parent::stripe_checkout_return_handler();
41
	}
42
43
	/**
44
	 * Checks to see if we need to hide the save checkbox field.
45
	 * Because when cart contains a subs product, it will save regardless.
46
	 *
47
	 * @since 4.0.0
48
	 * @version 4.0.0
49
	 */
50
	public function maybe_hide_save_checkbox( $display_tokenization ) {
51
		if ( WC_Subscriptions_Cart::cart_contains_subscription() ) {
52
			return false;
53
		}
54
55
		return $display_tokenization;
56
	}
57
58
	/**
59
	 * Is $order_id a subscription?
60
	 * @param  int  $order_id
61
	 * @return boolean
62
	 */
63
	public function has_subscription( $order_id ) {
64
		return ( function_exists( 'wcs_order_contains_subscription' ) && ( wcs_order_contains_subscription( $order_id ) || wcs_is_subscription( $order_id ) || wcs_order_contains_renewal( $order_id ) ) );
65
	}
66
67
	/**
68
	 * Checks if page is pay for order and change subs payment page.
69
	 *
70
	 * @since 4.1.0
71
	 * @return bool
72
	 */
73
	public function is_subs_change_payment() {
74
		return ( isset( $_GET['pay_for_order'] ) && isset( $_GET['change_payment_method'] ) );
75
	}
76
77
	/**
78
	 * Updates other subscription sources.
79
	 *
80
	 * @since 3.1.0
81
	 * @version 4.0.0
82
	 */
83 View Code Duplication
	public function save_source_to_order( $order, $source ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84
		parent::save_source_to_order( $order, $source );
85
86
		$order_id  = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id();
87
88
		// Also store it on the subscriptions being purchased or paid for in the order.
89
		if ( function_exists( 'wcs_order_contains_subscription' ) && wcs_order_contains_subscription( $order_id ) ) {
90
			$subscriptions = wcs_get_subscriptions_for_order( $order_id );
91
		} elseif ( function_exists( 'wcs_order_contains_renewal' ) && wcs_order_contains_renewal( $order_id ) ) {
92
			$subscriptions = wcs_get_subscriptions_for_renewal_order( $order_id );
93
		} else {
94
			$subscriptions = array();
95
		}
96
97
		foreach ( $subscriptions as $subscription ) {
98
			$subscription_id = WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id();
99
			update_post_meta( $subscription_id, '_stripe_customer_id', $source->customer );
100
			update_post_meta( $subscription_id, '_stripe_source_id', $source->source );
101
		}
102
	}
103
104
	/**
105
	 * Process the payment based on type.
106
	 * @param  int $order_id
107
	 * @return array
108
	 */
109 View Code Duplication
	public function process_payment( $order_id, $retry = true, $force_save_source = false, $previous_error = false ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
110
		if ( $this->has_subscription( $order_id ) ) {
111
			if ( $this->is_subs_change_payment() ) {
112
				return $this->change_subs_payment_method( $order_id );
113
			}
114
115
			// Regular payment with force customer enabled
116
			return parent::process_payment( $order_id, $retry, true, $previous_error );
117
		} else {
118
			return parent::process_payment( $order_id, $retry, $force_save_source, $previous_error );
119
		}
120
	}
121
122
	/**
123
	 * Scheduled_subscription_payment function.
124
	 *
125
	 * @param $amount_to_charge float The amount to charge.
126
	 * @param $renewal_order WC_Order A WC_Order object created to record the renewal payment.
127
	 */
128
	public function scheduled_subscription_payment( $amount_to_charge, $renewal_order ) {
129
		$this->process_subscription_payment( $amount_to_charge, $renewal_order, true, false );
130
	}
131
132
	/**
133
	 * Process_subscription_payment function.
134
	 *
135
	 * @since 3.0
136
	 * @since 4.0.4 Add third parameter flag to retry.
137
	 * @since 4.1.0 Add fourth parameter to log previous errors.
138
	 * @param float $amount
139
	 * @param mixed $renewal_order
140
	 * @param bool $retry Should we retry the process?
141
	 * @param object $previous_error
142
	 */
143 View Code Duplication
	public function process_subscription_payment( $amount = 0.0, $renewal_order, $retry = true, $previous_error ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
		try {
145
			if ( $amount * 100 < WC_Stripe_Helper::get_minimum_amount() ) {
146
				/* translators: minimum amount */
147
				return new WP_Error( 'stripe_error', sprintf( __( 'Sorry, the minimum allowed order total is %1$s to use this payment method.', 'woocommerce-gateway-stripe' ), wc_price( WC_Stripe_Helper::get_minimum_amount() / 100 ) ) );
148
			}
149
150
			$order_id = WC_Stripe_Helper::is_pre_30() ? $renewal_order->id : $renewal_order->get_id();
151
152
			// Get source from order
153
			$prepared_source = $this->prepare_order_source( $renewal_order );
154
			$source_object   = $prepared_source->source_object;
155
156
			if ( ! $prepared_source->customer ) {
157
				return new WP_Error( 'stripe_error', __( 'Customer not found', 'woocommerce-gateway-stripe' ) );
158
			}
159
160
			WC_Stripe_Logger::log( "Info: Begin processing subscription payment for order {$order_id} for the amount of {$amount}" );
161
162
			/* If we're doing a retry and source is chargeable, we need to pass
163
			 * a different idempotency key and retry for success.
164
			 */
165
			if ( is_object( $source_object ) && empty( $source_object->error ) && $this->need_update_idempotency_key( $source_object, $previous_error ) ) {
166
				add_filter( 'wc_stripe_idempotency_key', array( $this, 'change_idempotency_key' ), 10, 2 );
167
			}
168
169
			if ( ( $this->is_no_such_source_error( $previous_error ) || $this->is_no_linked_source_error( $previous_error ) ) && apply_filters( 'wc_stripe_use_default_customer_source', true ) ) {
170
				// Passing empty source will charge customer default.
171
				$prepared_source->source = '';
172
			}
173
174
			$request            = $this->generate_payment_request( $renewal_order, $prepared_source );
175
			$request['capture'] = 'true';
176
			$request['amount']  = WC_Stripe_Helper::get_stripe_amount( $amount, $request['currency'] );
177
			$response           = WC_Stripe_API::request( $request );
178
179
			if ( ! empty( $response->error ) ) {
180
				// We want to retry.
181
				if ( $this->is_retryable_error( $response->error ) ) {
182
					if ( $retry ) {
183
						// Don't do anymore retries after this.
184
						if ( 5 <= $this->retry_interval ) {
185
							return $this->process_subscription_payment( $amount, $renewal_order, false, $response->error );
186
						}
187
188
						sleep( $this->retry_interval );
189
190
						$this->retry_interval++;
191
192
						return $this->process_subscription_payment( $amount, $renewal_order, true, $response->error );
193
					} else {
194
						$localized_message = __( 'Sorry, we are unable to process your payment at this time. Please retry later.', 'woocommerce-gateway-stripe' );
195
						$renewal_order->add_order_note( $localized_message );
196
						throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
197
					}
198
				}
199
200
				$localized_messages = WC_Stripe_Helper::get_localized_messages();
201
202
				if ( 'card_error' === $response->error->type ) {
203
					$localized_message = isset( $localized_messages[ $response->error->code ] ) ? $localized_messages[ $response->error->code ] : $response->error->message;
204
				} else {
205
					$localized_message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message;
206
				}
207
208
				$renewal_order->add_order_note( $localized_message );
209
210
				throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
211
			}
212
213
			do_action( 'wc_gateway_stripe_process_payment', $response, $renewal_order );
214
215
			$this->process_response( $response, $renewal_order );
216
		} catch ( WC_Stripe_Exception $e ) {
217
			WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
218
219
			do_action( 'wc_gateway_stripe_process_payment_error', $e, $renewal_order );
220
221
			/* translators: error message */
222
			$renewal_order->update_status( 'failed' );
223
224
			if ( $renewal_order->has_status( array( 'pending', 'failed' ) ) ) {
225
				$this->send_failed_order_email( $order_id );
0 ignored issues
show
Bug introduced by
The variable $order_id does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
226
			}
227
		}
228
	}
229
230
	/**
231
	 * Don't transfer Stripe customer/token meta to resubscribe orders.
232
	 * @param int $resubscribe_order The order created for the customer to resubscribe to the old expired/cancelled subscription
233
	 */
234 View Code Duplication
	public function delete_resubscribe_meta( $resubscribe_order ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
235
		delete_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $resubscribe_order->id : $resubscribe_order->get_id() ), '_stripe_customer_id' );
0 ignored issues
show
Bug introduced by
The method get_id cannot be called on $resubscribe_order (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
236
		delete_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $resubscribe_order->id : $resubscribe_order->get_id() ), '_stripe_source_id' );
0 ignored issues
show
Bug introduced by
The method get_id cannot be called on $resubscribe_order (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
237
		// For BW compat will remove in future
238
		delete_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $resubscribe_order->id : $resubscribe_order->get_id() ), '_stripe_card_id' );
0 ignored issues
show
Bug introduced by
The method get_id cannot be called on $resubscribe_order (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
239
		$this->delete_renewal_meta( $resubscribe_order );
240
	}
241
242
	/**
243
	 * Don't transfer Stripe fee/ID meta to renewal orders.
244
	 * @param int $resubscribe_order The order created for the customer to resubscribe to the old expired/cancelled subscription
0 ignored issues
show
Bug introduced by
There is no parameter named $resubscribe_order. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
245
	 */
246
	public function delete_renewal_meta( $renewal_order ) {
247
		WC_Stripe_Helper::delete_stripe_fee( $renewal_order );
248
		WC_Stripe_Helper::delete_stripe_net( $renewal_order );
249
250
		return $renewal_order;
251
	}
252
253
	/**
254
	 * Update the customer_id for a subscription after using Stripe to complete a payment to make up for
255
	 * an automatic renewal payment which previously failed.
256
	 *
257
	 * @access public
258
	 * @param WC_Subscription $subscription The subscription for which the failing payment method relates.
259
	 * @param WC_Order $renewal_order The order which recorded the successful payment (to make up for the failed automatic payment).
260
	 * @return void
261
	 */
262 View Code Duplication
	public function update_failing_payment_method( $subscription, $renewal_order ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
263
		if ( WC_Stripe_Helper::is_pre_30() ) {
264
			update_post_meta( $subscription->id, '_stripe_customer_id', $renewal_order->stripe_customer_id );
265
			update_post_meta( $subscription->id, '_stripe_source_id', $renewal_order->stripe_source_id );
266
267
		} else {
268
			update_post_meta( $subscription->get_id(), '_stripe_customer_id', $renewal_order->get_meta( '_stripe_customer_id', true ) );
269
			update_post_meta( $subscription->get_id(), '_stripe_source_id', $renewal_order->get_meta( '_stripe_source_id', true ) );
270
		}
271
	}
272
273
	/**
274
	 * Include the payment meta data required to process automatic recurring payments so that store managers can
275
	 * manually set up automatic recurring payments for a customer via the Edit Subscriptions screen in 2.0+.
276
	 *
277
	 * @since 2.5
278
	 * @param array $payment_meta associative array of meta data required for automatic payments
279
	 * @param WC_Subscription $subscription An instance of a subscription object
280
	 * @return array
281
	 */
282 View Code Duplication
	public function add_subscription_payment_meta( $payment_meta, $subscription ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
283
		$source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_source_id', true );
284
285
		// For BW compat will remove in future.
286
		if ( empty( $source_id ) ) {
287
			$source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_card_id', true );
288
289
			// Take this opportunity to update the key name.
290
			WC_Stripe_Helper::is_pre_30() ? update_post_meta( $subscription->id, '_stripe_source_id', $source_id ) : update_post_meta( $subscription->get_id(), '_stripe_source_id', $source_id );
291
		}
292
293
		$payment_meta[ $this->id ] = array(
294
			'post_meta' => array(
295
				'_stripe_customer_id' => array(
296
					'value' => get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_customer_id', true ),
297
					'label' => 'Stripe Customer ID',
298
				),
299
				'_stripe_source_id' => array(
300
					'value' => $source_id,
301
					'label' => 'Stripe Source ID',
302
				),
303
			),
304
		);
305
		return $payment_meta;
306
	}
307
308
	/**
309
	 * Validate the payment meta data required to process automatic recurring payments so that store managers can
310
	 * manually set up automatic recurring payments for a customer via the Edit Subscriptions screen in 2.0+.
311
	 *
312
	 * @since 2.5
313
	 * @param string $payment_method_id The ID of the payment method to validate
314
	 * @param array $payment_meta associative array of meta data required for automatic payments
315
	 * @return array
316
	 */
317 View Code Duplication
	public function validate_subscription_payment_meta( $payment_method_id, $payment_meta ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
318
		if ( $this->id === $payment_method_id ) {
319
320
			if ( ! isset( $payment_meta['post_meta']['_stripe_customer_id']['value'] ) || empty( $payment_meta['post_meta']['_stripe_customer_id']['value'] ) ) {
321
				throw new Exception( __( 'A "Stripe Customer ID" value is required.', 'woocommerce-gateway-stripe' ) );
322
			} elseif ( 0 !== strpos( $payment_meta['post_meta']['_stripe_customer_id']['value'], 'cus_' ) ) {
323
				throw new Exception( __( 'Invalid customer ID. A valid "Stripe Customer ID" must begin with "cus_".', 'woocommerce-gateway-stripe' ) );
324
			}
325
326
			if (
327
				( ! empty( $payment_meta['post_meta']['_stripe_source_id']['value'] )
328
				&& 0 !== strpos( $payment_meta['post_meta']['_stripe_source_id']['value'], 'card_' ) )
329
				&& ( ! empty( $payment_meta['post_meta']['_stripe_source_id']['value'] )
330
				&& 0 !== strpos( $payment_meta['post_meta']['_stripe_source_id']['value'], 'src_' ) ) ) {
331
332
				throw new Exception( __( 'Invalid source ID. A valid source "Stripe Source ID" must begin with "src_" or "card_".', 'woocommerce-gateway-stripe' ) );
333
			}
334
		}
335
	}
336
337
	/**
338
	 * Render the payment method used for a subscription in the "My Subscriptions" table
339
	 *
340
	 * @since 1.7.5
341
	 * @param string $payment_method_to_display the default payment method text to display
342
	 * @param WC_Subscription $subscription the subscription details
343
	 * @return string the subscription payment method
344
	 */
345
	public function maybe_render_subscription_payment_method( $payment_method_to_display, $subscription ) {
346
		$customer_user = WC_Stripe_Helper::is_pre_30() ? $subscription->customer_user : $subscription->get_customer_id();
347
348
		// bail for other payment methods
349 View Code Duplication
		if ( ( WC_Stripe_Helper::is_pre_30() ? $subscription->payment_method : $subscription->get_payment_method() ) !== $this->id || ! $customer_user ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
350
			return $payment_method_to_display;
351
		}
352
353
		$stripe_source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_source_id', true );
354
355
		// For BW compat will remove in future.
356
		if ( empty( $stripe_source_id ) ) {
357
			$stripe_source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_card_id', true );
358
359
			// Take this opportunity to update the key name.
360
			WC_Stripe_Helper::is_pre_30() ? update_post_meta( $subscription->id, '_stripe_source_id', $stripe_source_id ) : update_post_meta( $subscription->get_id(), '_stripe_source_id', $stripe_source_id );
361
		}
362
363
		$stripe_customer    = new WC_Stripe_Customer();
364
		$stripe_customer_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_customer_id', true );
365
366
		// If we couldn't find a Stripe customer linked to the subscription, fallback to the user meta data.
367 View Code Duplication
		if ( ! $stripe_customer_id || ! is_string( $stripe_customer_id ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
368
			$user_id            = $customer_user;
369
			$stripe_customer_id = get_user_meta( $user_id, '_stripe_customer_id', true );
370
			$stripe_source_id   = get_user_meta( $user_id, '_stripe_source_id', true );
371
372
			// For BW compat will remove in future.
373
			if ( empty( $stripe_source_id ) ) {
374
				$stripe_source_id = get_user_meta( $user_id, '_stripe_card_id', true );
375
376
				// Take this opportunity to update the key name.
377
				update_user_meta( $user_id, '_stripe_source_id', $stripe_source_id );
378
			}
379
		}
380
381
		// If we couldn't find a Stripe customer linked to the account, fallback to the order meta data.
382 View Code Duplication
		if ( ( ! $stripe_customer_id || ! is_string( $stripe_customer_id ) ) && false !== $subscription->order ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
383
			$stripe_customer_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->order->id : $subscription->get_parent_id() ), '_stripe_customer_id', true );
384
			$stripe_source_id   = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->order->id : $subscription->get_parent_id() ), '_stripe_source_id', true );
385
386
			// For BW compat will remove in future.
387
			if ( empty( $stripe_source_id ) ) {
388
				$stripe_source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->order->id : $subscription->get_parent_id() ), '_stripe_card_id', true );
389
390
				// Take this opportunity to update the key name.
391
				WC_Stripe_Helper::is_pre_30() ? update_post_meta( $subscription->order->id, '_stripe_source_id', $stripe_source_id ) : update_post_meta( $subscription->get_parent_id(), '_stripe_source_id', $stripe_source_id );
392
			}
393
		}
394
395
		$stripe_customer->set_id( $stripe_customer_id );
396
		$sources = $stripe_customer->get_sources();
397
398
		if ( $sources ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $sources of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
399
			foreach ( $sources as $source ) {
400
				if ( $source->id === $stripe_source_id ) {
401
					if ( $source->sepa_debit ) {
402
						/* translators: 1) last 4 digits of SEPA Direct Debit */
403
						$payment_method_to_display = sprintf( __( 'Via SEPA Direct Debit ending in %1$s', 'woocommerce-gateway-stripe' ), $source->sepa_debit->last4 );
404
					} else {
405
						$payment_method_to_display = __( 'N/A', 'woocommerce-gateway-stripe' );
406
					}
407
					break;
408
				}
409
			}
410
		}
411
412
		return $payment_method_to_display;
413
	}
414
}
415