Passed
Push — master ( 7abbad...7a9f16 )
by Brian
11:26
created

GetPaid_Payment_Form_Submission   F

Complexity

Total Complexity 101

Size/Duplication

Total Lines 940
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 215
c 3
b 0
f 0
dl 0
loc 940
rs 2
wmc 101

51 Methods

Rating   Name   Duplication   Size   Complexity  
A get_fee() 0 2 1
A get_shipping() 0 2 1
B process_taxes() 0 36 10
A has_subscription_group() 0 2 3
A is_required_field_set() 0 2 2
A get_invoice() 0 2 1
A get_recurring_tax() 0 2 1
A remove_tax() 0 6 2
A get_currency() 0 2 2
A has_discount_code() 0 2 1
A use_taxes() 0 9 3
A has_shipping() 0 2 1
A format_amount() 0 2 1
A get_items() 0 2 1
A get_discount() 0 2 1
A should_collect_payment_details() 0 10 3
A __construct() 0 9 2
A add_fee() 0 11 2
A get_tax() 0 2 1
A get_recurring_subtotal() 0 7 2
A get_subtotal() 0 7 2
A has_billing_email() 0 3 2
A has_fees() 0 2 1
A get_data() 0 2 1
A process_payment_form() 0 15 3
A get_payment_form() 0 2 1
A add_tax() 0 10 2
A get_recurring_discount() 0 2 1
A get_billing_email() 0 2 1
A load_data() 0 46 4
A get_fees() 0 2 1
B process_invoice() 0 50 9
A add_item() 0 16 4
A process_fees() 0 9 2
A get_total() 0 3 1
A get_field() 0 2 1
A get_discounts() 0 2 1
A get_discount_code() 0 2 2
A get_taxes() 0 2 1
A process_items() 0 9 2
A get_recurring_total() 0 3 1
A is_initial_fetch() 0 2 1
A process_discount() 0 11 2
A get_recurring_fee() 0 2 1
A remove_item() 0 11 3
A remove_fee() 0 11 3
A has_invoice() 0 2 1
A remove_discount() 0 6 2
A add_discount() 0 4 1
A get_recurring_shipping() 0 2 1
A has_multiple_subscription_groups() 0 2 2

How to fix   Complexity   

Complex Class

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

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
/**
7
 * Payment form submission class
8
 *
9
 */
10
class GetPaid_Payment_Form_Submission {
11
12
    /**
13
	 * Submission ID
14
	 *
15
	 * @var string
16
	 */
17
	public $id = null;
18
19
	/**
20
	 * The raw submission data.
21
	 *
22
	 * @var array
23
	 */
24
	protected $data = null;
25
26
	/**
27
	 * Submission totals
28
	 *
29
	 * @var array
30
	 */
31
	protected $totals = array(
32
33
		'subtotal'      => array(
34
			'initial'   => 0,
35
			'recurring' => 0,
36
		),
37
38
		'discount'      => array(
39
			'initial'   => 0,
40
			'recurring' => 0,
41
		),
42
43
		'fees'          => array(
44
			'initial'   => 0,
45
			'recurring' => 0,
46
		),
47
48
		'taxes'         => array(
49
			'initial'   => 0,
50
			'recurring' => 0,
51
		),
52
53
		'shipping'         => array(
54
			'initial'   => 0,
55
			'recurring' => 0,
56
		),
57
58
	);
59
60
	/**
61
	 * Sets the associated payment form.
62
	 *
63
	 * @var GetPaid_Payment_Form
64
	 */
65
    protected $payment_form = null;
66
67
    /**
68
	 * The country for the submission.
69
	 *
70
	 * @var string
71
	 */
72
	public $country = null;
73
74
    /**
75
	 * The state for the submission.
76
	 *
77
	 * @since 1.0.19
78
	 * @var string
79
	 */
80
	public $state = null;
81
82
	/**
83
	 * The invoice associated with the submission.
84
	 *
85
	 * @var WPInv_Invoice
86
	 */
87
	protected $invoice = null;
88
89
	/**
90
	 * The recurring item for the submission.
91
	 *
92
	 * @var int
93
	 */
94
	public $has_recurring = 0;
95
96
	/**
97
	 * An array of fees for the submission.
98
	 *
99
	 * @var array
100
	 */
101
	protected $fees = array();
102
103
	/**
104
	 * An array of discounts for the submission.
105
	 *
106
	 * @var array
107
	 */
108
	protected $discounts = array();
109
110
	/**
111
	 * An array of taxes for the submission.
112
	 *
113
	 * @var array
114
	 */
115
	protected $taxes = array();
116
117
	/**
118
	 * An array of items for the submission.
119
	 *
120
	 * @var GetPaid_Form_Item[]
121
	 */
122
	protected $items = array();
123
124
	/**
125
	 * The last error.
126
	 *
127
	 * @var string
128
	 */
129
	public $last_error = null;
130
131
	/**
132
	 * The last error code.
133
	 *
134
	 * @var string
135
	 */
136
	public $last_error_code = null;
137
138
    /**
139
	 * Class constructor.
140
	 *
141
	 */
142
	public function __construct() {
143
144
		// Set the state and country to the default state and country.
145
		$this->country = wpinv_default_billing_country();
146
		$this->state   = wpinv_get_default_state();
147
148
		// Do we have an actual submission?
149
		if ( isset( $_POST['getpaid_payment_form_submission'] ) ) {
150
			$this->load_data( $_POST );
151
		}
152
153
	}
154
155
	/**
156
	 * Loads submission data.
157
	 *
158
	 * @param array $data
159
	 */
160
	public function load_data( $data ) {
161
162
		// Remove slashes from the submitted data...
163
		$data       = wp_kses_post_deep( wp_unslash( $data ) );
164
165
		// Allow plugins to filter the data.
166
		$data       = apply_filters( 'getpaid_submission_data', $data, $this );
167
168
		// Cache it...
169
		$this->data = $data;
170
171
		// Then generate a unique id from the data.
172
		$this->id   = md5( wp_json_encode( $data ) );
0 ignored issues
show
Bug introduced by
It seems like wp_json_encode($data) can also be of type false; however, parameter $string of md5() 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

172
		$this->id   = md5( /** @scrutinizer ignore-type */ wp_json_encode( $data ) );
Loading history...
173
174
		// Finally, process the submission.
175
		try {
176
177
			// Each process is passed an instance of the class (with reference)
178
			// and should throw an Exception whenever it encounters one.
179
			$processors = apply_filters(
180
				'getpaid_payment_form_submission_processors',
181
				array(
182
					array( $this, 'process_payment_form' ),
183
					array( $this, 'process_invoice' ),
184
					array( $this, 'process_fees' ),
185
					array( $this, 'process_items' ),
186
					array( $this, 'process_discount' ),
187
					array( $this, 'process_taxes' ),
188
				),
189
				$this		
190
			);
191
192
			foreach ( $processors as $processor ) {
193
				call_user_func_array( $processor, array( &$this ) );
194
			}
195
196
		} catch( GetPaid_Payment_Exception $e ) {
197
			$this->last_error      = $e->getMessage();
198
			$this->last_error_code = $e->getErrorCode();
199
		} catch ( Exception $e ) {
200
			$this->last_error      = $e->getMessage();
201
			$this->last_error_code = $e->getCode();
202
		}
203
204
		// Fired when we are done processing a submission.
205
		do_action_ref_array( 'getpaid_process_submission', array( &$this ) );
206
207
	}
208
209
	/*
210
	|--------------------------------------------------------------------------
211
	| Payment Forms.
212
	|--------------------------------------------------------------------------
213
	|
214
	| Functions for dealing with the submission's payment form. Ensure that the
215
	| submission has an active payment form etc.
216
    */
217
218
	/**
219
	 * Prepares the submission's payment form.
220
	 *
221
	 * @since 1.0.19
222
	 */
223
	public function process_payment_form() {
224
225
		// Every submission needs an active payment form.
226
		if ( empty( $this->data['form_id'] ) ) {
227
			throw new Exception( __( 'Missing payment form', 'invoicing' ) );
228
		}
229
230
		// Fetch the payment form.
231
		$this->payment_form = new GetPaid_Payment_Form( $this->data['form_id'] );
232
233
		if ( ! $this->payment_form->is_active() ) {
234
			throw new Exception( __( 'Payment form not active', 'invoicing' ) );
235
		}
236
237
		do_action_ref_array( 'getpaid_submissions_process_payment_form', array( &$this ) );
238
	}
239
240
    /**
241
	 * Returns the payment form.
242
	 *
243
	 * @since 1.0.19
244
	 * @return GetPaid_Payment_Form
245
	 */
246
	public function get_payment_form() {
247
		return $this->payment_form;
248
	}
249
250
	/*
251
	|--------------------------------------------------------------------------
252
	| Invoices.
253
	|--------------------------------------------------------------------------
254
	|
255
	| Functions for dealing with the submission's invoice. Some submissions
256
	| might be for an existing invoice.
257
	*/
258
259
	/**
260
	 * Prepares the submission's invoice.
261
	 *
262
	 * @since 1.0.19
263
	 */
264
	public function process_invoice() {
265
266
		// Abort if there is no invoice.
267
		if ( empty( $this->data['invoice_id'] ) ) {
268
			return;
269
		}
270
271
		// If the submission is for an existing invoice, ensure that it exists
272
		// and that it is not paid for.
273
		$invoice = wpinv_get_invoice( $this->data['invoice_id'] );
274
275
        if ( empty( $invoice ) ) {
276
			throw new Exception( __( 'Invalid invoice', 'invoicing' ) );
277
		}
278
279
		if ( $invoice->is_paid() ) {
280
			throw new Exception( __( 'This invoice is already paid for.', 'invoicing' ) );
281
		}
282
283
		$this->payment_form->invoice = $invoice;
284
		if ( ! $this->payment_form->is_default() ) {
285
286
			$items    = array();
287
			$item_ids = array();
288
	
289
			foreach ( $invoice->get_items() as $item ) {
290
				if ( ! in_array( $item->get_id(), $item_ids ) ) {
291
					$item_ids[] = $item->get_id();
292
					$items[]    = $item;
293
				}
294
			}
295
	
296
			foreach ( $this->payment_form->get_items() as $item ) {
297
				if ( ! in_array( $item->get_id(), $item_ids ) ) {
298
					$item_ids[] = $item->get_id();
299
					$items[]    = $item;
300
				}
301
			}
302
	
303
			$this->payment_form->set_items( $items );
304
	
305
		} else {
306
			$this->payment_form->set_items( $invoice->get_items() );
307
		}
308
309
		$this->country = $invoice->get_country();
310
		$this->state   = $invoice->get_state();
311
		$this->invoice = $invoice;
312
313
		do_action_ref_array( 'getpaid_submissions_process_invoice', array( &$this ) );
314
	}
315
316
	/**
317
	 * Returns the associated invoice.
318
	 *
319
	 * @since 1.0.19
320
	 * @return WPInv_Invoice
321
	 */
322
	public function get_invoice() {
323
		return $this->invoice;
324
	}
325
326
	/**
327
	 * Checks whether there is an invoice associated with this submission.
328
	 *
329
	 * @since 1.0.19
330
	 * @return bool
331
	 */
332
	public function has_invoice() {
333
		return ! empty( $this->invoice );
334
	}
335
336
	/*
337
	|--------------------------------------------------------------------------
338
	| Items.
339
	|--------------------------------------------------------------------------
340
	|
341
	| Functions for dealing with the submission's items. Submissions can only have one
342
	| recurring item. But can have an unlimited number of non-recurring items.
343
	*/
344
345
	/**
346
	 * Prepares the submission's items.
347
	 *
348
	 * @since 1.0.19
349
	 */
350
	public function process_items() {
351
352
		$processor = new GetPaid_Payment_Form_Submission_Items( $this );
353
354
		foreach ( $processor->items as $item ) {
355
			$this->add_item( $item );
356
		}
357
358
		do_action_ref_array( 'getpaid_submissions_process_items', array( &$this ) );
359
	}
360
361
	/**
362
	 * Adds an item to the submission.
363
	 *
364
	 * @since 1.0.19
365
	 * @param GetPaid_Form_Item $item
366
	 */
367
	public function add_item( $item ) {
368
369
		// Make sure that it is available for purchase.
370
		if ( ! $item->can_purchase() || isset( $this->items[ $item->get_id() ] ) ) {
371
			return;
372
		}
373
374
		// Each submission can only contain one recurring item.
375
		if ( $item->is_recurring() ) {
376
			$this->has_recurring = $item->get_id();
377
		}
378
379
		// Update the items and totals.
380
		$this->items[ $item->get_id() ]         = $item;
381
		$this->totals['subtotal']['initial']   += $item->get_sub_total();
382
		$this->totals['subtotal']['recurring'] += $item->get_recurring_sub_total();
383
384
	}
385
386
	/**
387
	 * Removes a specific item.
388
	 * 
389
	 * You should not call this method after the discounts and taxes
390
	 * have been calculated.
391
	 *
392
	 * @since 1.0.19
393
	 */
394
	public function remove_item( $item_id ) {
395
396
		if ( isset( $this->items[ $item_id ] ) ) {
397
			$this->totals['subtotal']['initial']   -= $this->items[ $item_id ]->get_sub_total();
398
			$this->totals['subtotal']['recurring'] -= $this->items[ $item_id ]->get_recurring_sub_total();
399
400
			if ( $this->items[ $item_id ]->is_recurring() ) {
401
				$this->has_recurring = 0;
402
			}
403
404
			unset( $this->items[ $item_id ] );
405
		}
406
407
	}
408
409
	/**
410
	 * Returns the subtotal.
411
	 *
412
	 * @since 1.0.19
413
	 */
414
	public function get_subtotal() {
415
416
		if ( wpinv_prices_include_tax() ) {
417
			return $this->totals['subtotal']['initial'] - $this->totals['taxes']['initial'];
418
		}
419
420
		return $this->totals['subtotal']['initial'];
421
	}
422
423
	/**
424
	 * Returns the recurring subtotal.
425
	 *
426
	 * @since 1.0.19
427
	 */
428
	public function get_recurring_subtotal() {
429
430
		if ( wpinv_prices_include_tax() ) {
431
			return $this->totals['subtotal']['recurring'] - $this->totals['taxes']['recurring'];
432
		}
433
434
		return $this->totals['subtotal']['recurring'];
435
	}
436
437
	/**
438
	 * Returns all items.
439
	 *
440
	 * @since 1.0.19
441
	 * @return GetPaid_Form_Item[]
442
	 */
443
	public function get_items() {
444
		return $this->items;
445
	}
446
447
	/**
448
	 * Checks if there's a single subscription group in the submission.
449
	 *
450
	 * @since 2.3.0
451
	 * @return bool
452
	 */
453
	public function has_subscription_group() {
454
		return $this->has_recurring && getpaid_should_group_subscriptions( $this ) && 1 == count( getpaid_get_subscription_groups( $this ) );
455
	}
456
457
	/**
458
	 * Checks if there are multipe subscription groups in the submission.
459
	 *
460
	 * @since 2.3.0
461
	 * @return bool
462
	 */
463
	public function has_multiple_subscription_groups() {
464
		return $this->has_recurring && 1 < count( getpaid_get_subscription_groups( $this ) );
465
	}
466
467
	/*
468
	|--------------------------------------------------------------------------
469
	| Taxes
470
	|--------------------------------------------------------------------------
471
	|
472
	| Functions for dealing with submission taxes. Taxes can be recurring
473
	| or only one-time.
474
    */
475
476
	/**
477
	 * Prepares the submission's taxes.
478
	 *
479
	 * @since 1.0.19
480
	 */
481
	public function process_taxes() {
482
483
		// Abort if we're not using taxes.
484
		if ( ! $this->use_taxes() ) {
485
			return;
486
		}
487
488
		// If a custom country && state has been passed in, use it to calculate taxes.
489
		$country = $this->get_field( 'wpinv_country', 'billing' );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $country is correct as $this->get_field('wpinv_country', 'billing') targeting GetPaid_Payment_Form_Submission::get_field() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

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

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

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

Loading history...
490
		if ( ! empty( $country ) ) {
491
			$this->country = $country;
492
		}
493
494
		$state = $this->get_field( 'wpinv_state', 'billing' );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $state is correct as $this->get_field('wpinv_state', 'billing') targeting GetPaid_Payment_Form_Submission::get_field() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

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

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

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

Loading history...
495
		if ( ! empty( $state ) ) {
496
			$this->state = $state;
497
		}
498
499
		// Confirm if the provided country and the ip country are similar.
500
		$address_confirmed = $this->get_field( 'confirm-address' );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $address_confirmed is correct as $this->get_field('confirm-address') targeting GetPaid_Payment_Form_Submission::get_field() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

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

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

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

Loading history...
501
		if ( isset( $_POST['billing']['country'] ) && wpinv_should_validate_vat_number() && getpaid_get_ip_country() != $this->country && empty( $address_confirmed ) ) {
502
			throw new Exception( __( 'The country of your current location must be the same as the country of your billing location or you must confirm the billing address is your home country.', 'invoicing' ) );
503
		}
504
505
		// Abort if the country is not taxable.
506
		if ( ! wpinv_is_country_taxable( $this->country ) ) {
507
			return;
508
		}
509
510
		$processor = new GetPaid_Payment_Form_Submission_Taxes( $this );
511
512
		foreach ( $processor->taxes as $tax ) {
513
			$this->add_tax( $tax );
514
		}
515
516
		do_action_ref_array( 'getpaid_submissions_process_taxes', array( &$this ) );
517
	}
518
519
	/**
520
	 * Adds a tax to the submission.
521
	 *
522
	 * @param array $tax An array of tax details. name, initial_tax, and recurring_tax are required.
523
	 * @since 1.0.19
524
	 */
525
	public function add_tax( $tax ) {
526
527
		if ( wpinv_round_tax_per_tax_rate() ) {
528
			$tax['initial_tax']   = wpinv_round_amount( $tax['initial_tax'] );
529
			$tax['recurring_tax'] = wpinv_round_amount( $tax['recurring_tax'] );
530
		}
531
532
		$this->taxes[ $tax['name'] ]         = $tax;
533
		$this->totals['taxes']['initial']   += wpinv_sanitize_amount( $tax['initial_tax'] );
534
		$this->totals['taxes']['recurring'] += wpinv_sanitize_amount( $tax['recurring_tax'] );
535
536
	}
537
538
	/**
539
	 * Removes a specific tax.
540
	 *
541
	 * @since 1.0.19
542
	 */
543
	public function remove_tax( $tax_name ) {
544
545
		if ( isset( $this->taxes[ $tax_name ] ) ) {
546
			$this->totals['taxes']['initial']   -= $this->taxes[ $tax_name ]['initial_tax'];
547
			$this->totals['taxes']['recurring'] -= $this->taxes[ $tax_name ]['recurring_tax'];
548
			unset( $this->taxes[ $tax_name ] );
549
		}
550
551
	}
552
553
	/**
554
	 * Whether or not we'll use taxes for the submission.
555
	 *
556
	 * @since 1.0.19
557
	 */
558
	public function use_taxes() {
559
560
		$use_taxes = wpinv_use_taxes();
561
562
		if ( $this->has_invoice() && ! $this->invoice->is_taxable() ) {
563
			$use_taxes = false;
564
		}
565
566
		return apply_filters( 'getpaid_submission_use_taxes', $use_taxes, $this );
567
568
	}
569
570
	/**
571
	 * Returns the tax.
572
	 *
573
	 * @since 1.0.19
574
	 */
575
	public function get_tax() {
576
		return $this->totals['taxes']['initial'];
577
	}
578
579
	/**
580
	 * Returns the recurring tax.
581
	 *
582
	 * @since 1.0.19
583
	 */
584
	public function get_recurring_tax() {
585
		return $this->totals['taxes']['recurring'];
586
	}
587
588
	/**
589
	 * Returns all taxes.
590
	 *
591
	 * @since 1.0.19
592
	 */
593
	public function get_taxes() {
594
		return $this->taxes;
595
	}
596
597
	/*
598
	|--------------------------------------------------------------------------
599
	| Discounts
600
	|--------------------------------------------------------------------------
601
	|
602
	| Functions for dealing with submission discounts. Discounts can be recurring
603
	| or only one-time. They also do not have to come from a discount code.
604
    */
605
606
	/**
607
	 * Prepares the submission's discount.
608
	 *
609
	 * @since 1.0.19
610
	 */
611
	public function process_discount() {
612
613
		$initial_total    = $this->get_subtotal() + $this->get_fee() + $this->get_tax();
614
		$recurring_total  = $this->get_recurring_subtotal() + $this->get_recurring_fee() + $this->get_recurring_tax();
615
		$processor        = new GetPaid_Payment_Form_Submission_Discount( $this, $initial_total, $recurring_total );
616
617
		foreach ( $processor->discounts as $discount ) {
618
			$this->add_discount( $discount );
619
		}
620
621
		do_action_ref_array( 'getpaid_submissions_process_discounts', array( &$this ) );
622
	}
623
624
	/**
625
	 * Adds a discount to the submission.
626
	 *
627
	 * @param array $discount An array of discount details. name, initial_discount, and recurring_discount are required. Include discount_code if the discount is from a discount code.
628
	 * @since 1.0.19
629
	 */
630
	public function add_discount( $discount ) {
631
		$this->discounts[ $discount['name'] ]   = $discount;
632
		$this->totals['discount']['initial']   += wpinv_sanitize_amount( $discount['initial_discount'] );
633
		$this->totals['discount']['recurring'] += wpinv_sanitize_amount( $discount['recurring_discount'] );
634
	}
635
636
	/**
637
	 * Removes a discount from the submission.
638
	 *
639
	 * @since 1.0.19
640
	 */
641
	public function remove_discount( $name ) {
642
643
		if ( isset( $this->discounts[ $name ] ) ) {
644
			$this->totals['discount']['initial']   -= $this->discounts[ $name ]['initial_discount'];
645
			$this->totals['discount']['recurring'] -= $this->discounts[ $name ]['recurring_discount'];
646
			unset( $this->discounts[ $name ] );
647
		}
648
649
	}
650
651
	/**
652
	 * Checks whether there is a discount code associated with this submission.
653
	 *
654
	 * @since 1.0.19
655
	 * @return bool
656
	 */
657
	public function has_discount_code() {
658
		return ! empty( $this->discounts['discount_code'] );
659
	}
660
661
	/**
662
	 * Returns the discount code.
663
	 *
664
	 * @since 1.0.19
665
	 * @return string
666
	 */
667
	public function get_discount_code() {
668
		return $this->has_discount_code() ? $this->discounts['discount_code']['discount_code'] : '';
669
	}
670
671
	/**
672
	 * Returns the discount.
673
	 *
674
	 * @since 1.0.19
675
	 */
676
	public function get_discount() {
677
		return $this->totals['discount']['initial'];
678
	}
679
680
	/**
681
	 * Returns the recurring discount.
682
	 *
683
	 * @since 1.0.19
684
	 */
685
	public function get_recurring_discount() {
686
		return $this->totals['discount']['recurring'];
687
	}
688
689
	/**
690
	 * Returns all discounts.
691
	 *
692
	 * @since 1.0.19
693
	 */
694
	public function get_discounts() {
695
		return $this->discounts;
696
	}
697
698
	/*
699
	|--------------------------------------------------------------------------
700
	| Fees
701
	|--------------------------------------------------------------------------
702
	|
703
	| Functions for dealing with submission fees. Fees can be recurring
704
	| or only one-time. Price input and Price select elements are treated as 
705
	| fees.
706
    */
707
708
	/**
709
	 * Prepares the submission's fees.
710
	 *
711
	 * @since 1.0.19
712
	 */
713
	public function process_fees() {
714
715
		$fees_processor = new GetPaid_Payment_Form_Submission_Fees( $this );
716
717
		foreach ( $fees_processor->fees as $fee ) {
718
			$this->add_fee( $fee );
719
		}
720
721
		do_action_ref_array( 'getpaid_submissions_process_fees', array( &$this ) );
722
	}
723
724
	/**
725
	 * Adds a fee to the submission.
726
	 *
727
	 * @param array $fee An array of fee details. name, initial_fee, and recurring_fee are required.
728
	 * @since 1.0.19
729
	 */
730
	public function add_fee( $fee ) {
731
732
		if ( $fee['name'] == 'shipping' ) {
733
			$this->totals['shipping']['initial']   += wpinv_sanitize_amount( $fee['initial_fee'] );
734
			$this->totals['shipping']['recurring'] += wpinv_sanitize_amount( $fee['recurring_fee'] );
735
			return;
736
		}
737
738
		$this->fees[ $fee['name'] ]         = $fee;
739
		$this->totals['fees']['initial']   += wpinv_sanitize_amount( $fee['initial_fee'] );
740
		$this->totals['fees']['recurring'] += wpinv_sanitize_amount( $fee['recurring_fee'] );
741
742
	}
743
744
	/**
745
	 * Removes a fee from the submission.
746
	 *
747
	 * @since 1.0.19
748
	 */
749
	public function remove_fee( $name ) {
750
751
		if ( isset( $this->fees[ $name ] ) ) {
752
			$this->totals['fees']['initial']   -= $this->fees[ $name ]['initial_fee'];
753
			$this->totals['fees']['recurring'] -= $this->fees[ $name ]['recurring_fee'];
754
			unset( $this->fees[ $name ] );
755
		}
756
757
		if ( 'shipping' == $name ) {
758
			$this->totals['shipping']['initial']   = 0;
759
			$this->totals['shipping']['recurring'] = 0;
760
		}
761
762
	}
763
764
	/**
765
	 * Returns the fees.
766
	 *
767
	 * @since 1.0.19
768
	 */
769
	public function get_fee() {
770
		return $this->totals['fees']['initial'];
771
	}
772
773
	/**
774
	 * Returns the recurring fees.
775
	 *
776
	 * @since 1.0.19
777
	 */
778
	public function get_recurring_fee() {
779
		return $this->totals['fees']['recurring'];
780
	}
781
782
	/**
783
	 * Returns all fees.
784
	 *
785
	 * @since 1.0.19
786
	 */
787
	public function get_fees() {
788
		return $this->fees;
789
	}
790
791
	/**
792
	 * Checks if there are any fees for the form.
793
	 *
794
	 * @return bool
795
	 * @since 1.0.19
796
	 */
797
	public function has_fees() {
798
		return count( $this->fees ) !== 0;
799
	}
800
801
	/*
802
	|--------------------------------------------------------------------------
803
	| MISC
804
	|--------------------------------------------------------------------------
805
	|
806
	| Extra submission functions.
807
    */
808
809
	/**
810
	 * Returns the shipping amount.
811
	 *
812
	 * @since 1.0.19
813
	 */
814
	public function get_shipping() {
815
		return $this->totals['shipping']['initial'];
816
	}
817
818
	/**
819
	 * Returns the recurring shipping.
820
	 *
821
	 * @since 1.0.19
822
	 */
823
	public function get_recurring_shipping() {
824
		return $this->totals['shipping']['recurring'];
825
	}
826
827
	/**
828
	 * Checks if there are any shipping fees for the form.
829
	 *
830
	 * @return bool
831
	 * @since 1.0.19
832
	 */
833
	public function has_shipping() {
834
		return apply_filters( 'getpaid_payment_form_has_shipping', false, $this );
835
	}
836
837
	/**
838
	 * Checks if this is the initial fetch.
839
	 *
840
	 * @return bool
841
	 * @since 1.0.19
842
	 */
843
	public function is_initial_fetch() {
844
		return empty( $this->data['initial_state'] );
845
	}
846
847
	/**
848
	 * Returns the total amount to collect for this submission.
849
	 *
850
	 * @since 1.0.19
851
	 */
852
	public function get_total() {
853
		$total = $this->get_subtotal() + $this->get_fee() + $this->get_tax() + $this->get_shipping() - $this->get_discount();
854
		return max( $total, 0 );
855
	}
856
857
	/**
858
	 * Returns the recurring total amount to collect for this submission.
859
	 *
860
	 * @since 1.0.19
861
	 */
862
	public function get_recurring_total() {
863
		$total = $this->get_recurring_subtotal() + $this->get_recurring_fee() + $this->get_recurring_tax() + $this->get_recurring_shipping() - $this->get_recurring_discount();
864
		return max( $total, 0 );
865
	}
866
867
	/**
868
	 * Whether payment details should be collected for this submission.
869
	 *
870
	 * @since 1.0.19
871
	 */
872
	public function should_collect_payment_details() {
873
		$initial   = $this->get_total();
874
		$recurring = $this->get_recurring_total();
875
876
		if ( $this->has_recurring == 0 ) {
877
			$recurring = 0;
878
		}
879
880
		$collect = $initial > 0 || $recurring > 0;
881
		return apply_filters( 'getpaid_submission_should_collect_payment_details', $collect, $this  );
882
	}
883
884
	/**
885
	 * Returns the billing email of the user.
886
	 *
887
	 * @since 1.0.19
888
	 */
889
	public function get_billing_email() {
890
		return apply_filters( 'getpaid_get_submission_billing_email', $this->get_field( 'billing_email' ), $this  );
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->get_field('billing_email') targeting GetPaid_Payment_Form_Submission::get_field() 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...
891
	}
892
893
	/**
894
	 * Checks if the submitter has a billing email.
895
	 *
896
	 * @since 1.0.19
897
	 */
898
	public function has_billing_email() {
899
		$billing_email = $this->get_billing_email();
900
		return ! empty( $billing_email ) && is_email( $billing_email );
901
	}
902
903
	/**
904
	 * Returns the appropriate currency for the submission.
905
	 *
906
	 * @since 1.0.19
907
	 * @return string
908
	 */
909
	public function get_currency() {
910
		return $this->has_invoice() ? $this->invoice->get_currency() : wpinv_get_currency();
911
    }
912
913
    /**
914
	 * Returns the raw submission data.
915
	 *
916
	 * @since 1.0.19
917
	 * @return array
918
	 */
919
	public function get_data() {
920
		return $this->data;
921
	}
922
923
	/**
924
	 * Returns a field from the submission data
925
	 *
926
	 * @param string $field
927
	 * @since 1.0.19
928
	 * @return mixed|null
929
	 */
930
	public function get_field( $field, $sub_array_key = null ) {
931
		return getpaid_get_array_field( $this->data, $field, $sub_array_key );
932
	}
933
934
	/**
935
	 * Checks if a required field is set.
936
	 *
937
	 * @since 1.0.19
938
	 */
939
	public function is_required_field_set( $field ) {
940
		return empty( $field['required'] ) || ! empty( $this->data[ $field['id'] ] );
941
	}
942
943
	/**
944
	 * Formats an amount
945
	 *
946
	 * @since 1.0.19
947
	 */
948
	public function format_amount( $amount ) {
949
		return wpinv_price( $amount, $this->get_currency() );
950
	}
951
952
}
953