Passed
Pull Request — master (#815)
by Kiran
05:40
created

GetPaid_Bank_Transfer_Gateway   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 431
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 174
dl 0
loc 431
rs 8.96
c 1
b 0
f 0
wmc 43

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 1
A admin_settings() 0 64 2
A email_instructions() 0 13 5
A process_payment() 0 17 3
B bank_details() 0 47 6
A get_country_locale() 0 54 2
A thankyou_page() 0 13 4
A process_addons() 0 8 2
A force_is_payment_form_invoice() 0 6 2
B invoice_paid() 0 36 10
A maybe_renew_subscription() 0 19 6

How to fix   Complexity   

Complex Class

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

1
<?php
2
/**
3
 * Bank transfer payment gateway
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * Bank transfer Payment Gateway class.
11
 *
12
 */
13
class GetPaid_Bank_Transfer_Gateway extends GetPaid_Payment_Gateway {
14
15
    /**
16
	 * Payment method id.
17
	 *
18
	 * @var string
19
	 */
20
    public $id = 'bank_transfer';
21
22
	/**
23
	 * An array of features that this gateway supports.
24
	 *
25
	 * @var array
26
	 */
27
	protected $supports = array(
28
		'subscription',
29
		'addons',
30
		'single_subscription_group',
31
		'multiple_subscription_groups',
32
		'subscription_date_change',
33
		'subscription_bill_times_change',
34
	);
35
36
    /**
37
	 * Payment method order.
38
	 *
39
	 * @var int
40
	 */
41
	public $order = 8;
42
43
	/**
44
	 * Bank transfer instructions.
45
	 */
46
	public $instructions;
47
48
	/**
49
	 * Locale array.
50
	 */
51
	public $locale;
52
53
    /**
54
	 * Class constructor.
55
	 */
56
	public function __construct() {
57
        parent::__construct();
58
59
        $this->title                = __( 'Direct bank transfer', 'invoicing' );
60
        $this->method_title         = __( 'Bank transfer', 'invoicing' );
61
        $this->checkout_button_text = __( 'Proceed', 'invoicing' );
62
        $this->instructions         = apply_filters( 'wpinv_bank_instructions', $this->get_option( 'info' ) );
63
64
		add_action( 'wpinv_receipt_end', array( $this, 'thankyou_page' ) );
65
		add_action( 'getpaid_invoice_line_items', array( $this, 'thankyou_page' ), 40 );
66
		add_action( 'wpinv_pdf_content_billing', array( $this, 'thankyou_page' ), 11 );
67
		add_action( 'wpinv_email_invoice_details', array( $this, 'email_instructions' ), 10, 3 );
68
		add_action( 'getpaid_should_renew_subscription', array( $this, 'maybe_renew_subscription' ), 12, 2 );
69
		add_action( 'getpaid_invoice_status_publish', array( $this, 'invoice_paid' ), 20 );
70
71
    }
72
73
    /**
74
	 * Process Payment.
75
	 *
76
	 * @param WPInv_Invoice $invoice Invoice.
77
	 * @param array $submission_data Posted checkout fields.
78
	 * @param GetPaid_Payment_Form_Submission $submission Checkout submission.
79
	 * @return array
80
	 */
81
	public function process_payment( $invoice, $submission_data, $submission ) {
82
83
        // Add a transaction id.
84
        $invoice->set_transaction_id( $invoice->generate_key( 'bt_' ) );
85
86
        // Set it as pending payment.
87
        if ( ! $invoice->needs_payment() ) {
88
            $invoice->mark_paid();
89
        } elseif ( ! $invoice->is_paid() ) {
90
            $invoice->set_status( 'wpi-onhold' );
91
        }
92
93
        // Save it.
94
        $invoice->save();
95
96
        // Send to the success page.
97
        wpinv_send_to_success_page( array( 'invoice_key' => $invoice->get_key() ) );
98
99
    }
100
101
    /**
102
	 * Output for the order received page.
103
	 *
104
	 * @param WPInv_Invoice $invoice Invoice.
105
	 */
106
	public function thankyou_page( $invoice ) {
107
108
        if ( 'bank_transfer' === $invoice->get_gateway() && $invoice->needs_payment() ) {
109
110
			echo '<div class="mt-4 mb-2 getpaid-bank-transfer-details">' . PHP_EOL;
111
112
            if ( ! empty( $this->instructions ) ) {
113
                echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) );
114
			}
115
116
			$this->bank_details( $invoice );
117
118
			echo '</div>';
119
120
        }
121
122
	}
123
124
    /**
125
	 * Add content to the WPI emails.
126
	 *
127
	 * @param WPInv_Invoice $invoice Invoice.
128
	 * @param string     $email_type Email format: plain text or HTML.
129
	 * @param bool     $sent_to_admin Sent to admin.
130
	 */
131
	public function email_instructions( $invoice, $email_type, $sent_to_admin ) {
132
133
		if ( ! $sent_to_admin && 'bank_transfer' === $invoice->get_gateway() && $invoice->needs_payment() ) {
134
135
			echo '<div class="wpi-email-row getpaid-bank-transfer-details">';
136
137
			if ( $this->instructions ) {
138
				echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) . PHP_EOL );
0 ignored issues
show
Bug introduced by
It seems like $this->instructions can also be of type true; however, parameter $text of wptexturize() 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

138
				echo wp_kses_post( wpautop( wptexturize( /** @scrutinizer ignore-type */ $this->instructions ) ) . PHP_EOL );
Loading history...
139
            }
140
141
			$this->bank_details( $invoice );
142
143
			echo '</div>';
144
145
		}
146
147
    }
148
149
    /**
150
	 * Get bank details and place into a list format.
151
	 *
152
	 * @param WPInv_Invoice $invoice Invoice.
153
	 */
154
	protected function bank_details( $invoice ) {
155
156
		// Get the invoice country and country $locale.
157
		$country = $invoice->get_country();
158
		$locale  = $this->get_country_locale();
159
160
		// Get shortcode label in the $locale array and use appropriate one.
161
		$sortcode = isset( $locale[ $country ]['sortcode']['label'] ) ? $locale[ $country ]['sortcode']['label'] : __( 'Sort code', 'invoicing' );
162
163
        $bank_fields = array(
164
            'ac_name'   => __( 'Account Name', 'invoicing' ),
165
            'ac_no'     => __( 'Account Number', 'invoicing' ),
166
            'bank_name' => __( 'Bank Name', 'invoicing' ),
167
            'ifsc'      => __( 'IFSC code', 'invoicing' ),
168
            'iban'      => __( 'IBAN', 'invoicing' ),
169
            'bic'       => __( 'BIC/Swift code', 'invoicing' ),
170
            'sort_code' => $sortcode,
171
        );
172
173
        $bank_info = array();
174
175
        foreach ( $bank_fields as $field => $label ) {
176
            $value = $this->get_option( $field );
177
178
            if ( ! empty( $value ) ) {
179
                $bank_info[ $field ] = array(
180
					'label' => $label,
181
					'value' => $value,
182
				);
183
            }
184
		}
185
186
        $bank_info = apply_filters( 'wpinv_bank_info', $bank_info, $invoice );
187
188
        if ( empty( $bank_info ) ) {
189
            return;
190
        }
191
192
		echo '<h3 class="getpaid-bank-transfer-title"> ' . esc_html( apply_filters( 'wpinv_receipt_bank_details_title', __( 'Bank Details', 'invoicing' ), $invoice ) ) . '</h3>' . PHP_EOL;
193
194
		echo '<table class="table table-bordered getpaid-bank-transfer-details">' . PHP_EOL;
195
196
		foreach ( $bank_info as $key => $data ) {
197
			echo "<tr class='getpaid-bank-transfer-" . esc_attr( $key ) . "'><th class='font-weight-bold'>" . wp_kses_post( $data['label'] ) . "</th><td class='w-75'>" . wp_kses_post( wptexturize( $data['value'] ) ) . '</td></tr>' . PHP_EOL;
198
		}
199
200
		echo '</table>';
201
202
    }
203
204
    /**
205
	 * Get country locale if localized.
206
	 *
207
	 * @return array
208
	 */
209
	public function get_country_locale() {
210
211
		if ( empty( $this->locale ) ) {
212
213
			// Locale information to be used - only those that are not 'Sort Code'.
214
			$this->locale = apply_filters(
215
				'getpaid_get_bank_transfer_locale',
216
				array(
217
					'AU' => array(
218
						'sortcode' => array(
219
							'label' => __( 'BSB', 'invoicing' ),
220
						),
221
					),
222
					'CA' => array(
223
						'sortcode' => array(
224
							'label' => __( 'Bank transit number', 'invoicing' ),
225
						),
226
					),
227
					'IN' => array(
228
						'sortcode' => array(
229
							'label' => __( 'IFSC', 'invoicing' ),
230
						),
231
					),
232
					'IT' => array(
233
						'sortcode' => array(
234
							'label' => __( 'Branch sort', 'invoicing' ),
235
						),
236
					),
237
					'NZ' => array(
238
						'sortcode' => array(
239
							'label' => __( 'Bank code', 'invoicing' ),
240
						),
241
					),
242
					'SE' => array(
243
						'sortcode' => array(
244
							'label' => __( 'Bank code', 'invoicing' ),
245
						),
246
					),
247
					'US' => array(
248
						'sortcode' => array(
249
							'label' => __( 'Routing number', 'invoicing' ),
250
						),
251
					),
252
					'ZA' => array(
253
						'sortcode' => array(
254
							'label' => __( 'Branch code', 'invoicing' ),
255
						),
256
					),
257
				)
258
			);
259
260
		}
261
262
		return $this->locale;
263
264
	}
265
266
	/**
267
	 * Filters the gateway settings.
268
	 *
269
	 * @param array $admin_settings
270
	 */
271
	public function admin_settings( $admin_settings ) {
272
273
        $admin_settings['bank_transfer_desc']['std']    = __( "Make your payment directly into our bank account. Please use your Invoice Number as the payment reference. Your invoice won't be processed until the funds have cleared in our account.", 'invoicing' );
274
		$admin_settings['bank_transfer_active']['desc'] = __( 'Enable bank transfer', 'invoicing' );
275
276
		$locale  = $this->get_country_locale();
277
278
		// Get sortcode label in the $locale array and use appropriate one.
279
		$country  = wpinv_default_billing_country();
280
		$sortcode = isset( $locale[ $country ]['sortcode']['label'] ) ? $locale[ $country ]['sortcode']['label'] : __( 'Sort code', 'invoicing' );
281
282
		$admin_settings['bank_transfer_ac_name'] = array(
283
            'type' => 'text',
284
            'id'   => 'bank_transfer_ac_name',
285
            'name' => __( 'Account Name', 'invoicing' ),
286
		);
287
288
		$admin_settings['bank_transfer_ac_no'] = array(
289
            'type' => 'text',
290
            'id'   => 'bank_transfer_ac_no',
291
            'name' => __( 'Account Number', 'invoicing' ),
292
		);
293
294
		$admin_settings['bank_transfer_bank_name'] = array(
295
            'type' => 'text',
296
            'id'   => 'bank_transfer_bank_name',
297
            'name' => __( 'Bank Name', 'invoicing' ),
298
		);
299
300
		$admin_settings['bank_transfer_ifsc'] = array(
301
            'type' => 'text',
302
            'id'   => 'bank_transfer_ifsc',
303
            'name' => __( 'IFSC Code', 'invoicing' ),
304
		);
305
306
		$admin_settings['bank_transfer_iban'] = array(
307
            'type' => 'text',
308
            'id'   => 'bank_transfer_iban',
309
            'name' => __( 'IBAN', 'invoicing' ),
310
		);
311
312
		$admin_settings['bank_transfer_bic'] = array(
313
            'type' => 'text',
314
            'id'   => 'bank_transfer_bic',
315
            'name' => __( 'BIC/Swift Code', 'invoicing' ),
316
		);
317
318
		$admin_settings['bank_transfer_sort_code'] = array(
319
			'type' => 'text',
320
			'id'   => 'bank_transfer_sort_code',
321
			'name' => $sortcode,
322
		);
323
324
		$admin_settings['bank_transfer_info'] = array(
325
            'id'   => 'bank_transfer_info',
326
            'name' => __( 'Instructions', 'invoicing' ),
327
            'desc' => __( 'Instructions that will be added to the thank you page and emails.', 'invoicing' ),
328
            'type' => 'textarea',
329
            'std'  => __( "Make your payment directly into our bank account. Please use your Invoice Number as the payment reference. Your invoice won't be processed until the funds have cleared in our account.", 'invoicing' ),
330
            'cols' => 50,
331
            'rows' => 5,
332
        );
333
334
		return $admin_settings;
335
	}
336
337
	/**
338
	 * Processes invoice addons.
339
	 *
340
	 * @param WPInv_Invoice $invoice
341
	 * @param GetPaid_Form_Item[] $items
342
	 * @return WPInv_Invoice
343
	 */
344
	public function process_addons( $invoice, $items ) {
345
346
        foreach ( $items as $item ) {
347
            $invoice->add_item( $item );
348
        }
349
350
        $invoice->recalculate_total();
351
        $invoice->save();
352
	}
353
354
	/**
355
	 * (Maybe) renews a bank transfer subscription profile.
356
	 *
357
	 *
358
	 * @param WPInv_Subscription $subscription
359
	 */
360
	public function maybe_renew_subscription( $subscription, $parent_invoice ) {
361
		// Ensure its our subscription && it's active.
362
		if ( ! empty( $parent_invoice ) && $this->id === $parent_invoice->get_gateway() && $subscription->has_status( 'active trialling' ) ) {
363
			add_filter( 'getpaid_invoice_notifications_is_payment_form_invoice', array( $this, 'force_is_payment_form_invoice' ), 10, 2 );
364
365
			$invoice = $subscription->create_payment();
366
367
			if ( ! empty( $invoice ) ) {
368
				$is_logged_in = is_user_logged_in();
369
370
				// Cron run.
371
				if ( ! $is_logged_in ) {
372
					$note = wp_sprintf( __( 'Renewal %1$s created with the status "%2$s".', 'invoicing' ), $invoice->get_invoice_quote_type(), wpinv_status_nicename( $invoice->get_status(), $invoice ) );
373
374
					$invoice->add_note( $note, false, $is_logged_in, ! $is_logged_in );
375
				}
376
			}
377
378
			remove_filter( 'getpaid_invoice_notifications_is_payment_form_invoice', array( $this, 'force_is_payment_form_invoice' ), 10, 2 );
0 ignored issues
show
Unused Code introduced by
The call to remove_filter() has too many arguments starting with 2. ( Ignorable by Annotation )

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

378
			/** @scrutinizer ignore-call */ 
379
   remove_filter( 'getpaid_invoice_notifications_is_payment_form_invoice', array( $this, 'force_is_payment_form_invoice' ), 10, 2 );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
379
		}
380
	}
381
382
	/**
383
	 * Process a bank transfer payment.
384
	 *
385
	 *
386
     * @param WPInv_Invoice $invoice
387
	 */
388
	public function invoice_paid( $invoice ) {
389
390
		// Abort if not paid by bank transfer.
391
		if ( $this->id !== $invoice->get_gateway() || ! $invoice->is_recurring() ) {
392
			return;
393
		}
394
395
		// Is it a parent payment?
396
		if ( 0 == $invoice->get_parent_id() ) {
397
398
			// (Maybe) activate subscriptions.
399
			$subscriptions = getpaid_get_invoice_subscriptions( $invoice );
400
401
			if ( ! empty( $subscriptions ) ) {
402
				$subscriptions = is_array( $subscriptions ) ? $subscriptions : array( $subscriptions );
0 ignored issues
show
introduced by
The condition is_array($subscriptions) is always false.
Loading history...
403
404
				foreach ( $subscriptions as $subscription ) {
405
					if ( $subscription->exists() ) {
406
						$duration = strtotime( $subscription->get_expiration() ) - strtotime( $subscription->get_date_created() );
407
						$expiry   = gmdate( 'Y-m-d H:i:s', ( current_time( 'timestamp' ) + $duration ) );
408
409
						$subscription->set_next_renewal_date( $expiry );
410
						$subscription->set_date_created( current_time( 'mysql' ) );
411
						$subscription->set_profile_id( 'bt_sub_' . $invoice->get_id() . '_' . $subscription->get_id() );
412
						$subscription->activate();
413
					}
414
				}
415
			}
416
		} else {
417
418
			$subscription = getpaid_get_subscription( $invoice->get_subscription_id() );
419
420
			// Renew the subscription.
421
			if ( $subscription && $subscription->exists() ) {
422
				$subscription->add_payment( array(), $invoice );
423
				$subscription->renew( strtotime( $invoice->get_date_created() ) );
424
			}
425
		}
426
427
    }
428
429
	/**
430
	 * Force created from payment false to allow email for auto renewal generation invoice.
431
	 *
432
	 * @since 2.8.11
433
	 *
434
	 * @param bool $is_payment_form_invoice True when invoice created via payment form else false.
435
	 * @param int  $invoice Invoice ID.
436
	 * @return bool True when invoice created via payment form else false.
437
	 */
438
	public function force_is_payment_form_invoice( $is_payment_form_invoice, $invoice ) {
0 ignored issues
show
Unused Code introduced by
The parameter $invoice is not used and could be removed. ( Ignorable by Annotation )

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

438
	public function force_is_payment_form_invoice( $is_payment_form_invoice, /** @scrutinizer ignore-unused */ $invoice ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
439
		if ( $is_payment_form_invoice ) {
440
			$is_payment_form_invoice = false;
441
		}
442
443
		return $is_payment_form_invoice;
444
	}
445
446
}
447