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
|
|
|
); |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Sets the associated payment form. |
57
|
|
|
* |
58
|
|
|
* @var GetPaid_Payment_Form |
59
|
|
|
*/ |
60
|
|
|
protected $payment_form = null; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* The country for the submission. |
64
|
|
|
* |
65
|
|
|
* @var string |
66
|
|
|
*/ |
67
|
|
|
public $country = null; |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* The state for the submission. |
71
|
|
|
* |
72
|
|
|
* @since 1.0.19 |
73
|
|
|
* @var string |
74
|
|
|
*/ |
75
|
|
|
public $state = null; |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* The invoice associated with the submission. |
79
|
|
|
* |
80
|
|
|
* @var WPInv_Invoice |
81
|
|
|
*/ |
82
|
|
|
protected $invoice = null; |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* The recurring item for the submission. |
86
|
|
|
* |
87
|
|
|
* @var int |
88
|
|
|
*/ |
89
|
|
|
public $has_recurring = 0; |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* An array of fees for the submission. |
93
|
|
|
* |
94
|
|
|
* @var array |
95
|
|
|
*/ |
96
|
|
|
protected $fees = array(); |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* An array of discounts for the submission. |
100
|
|
|
* |
101
|
|
|
* @var array |
102
|
|
|
*/ |
103
|
|
|
protected $discounts = array(); |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* An array of taxes for the submission. |
107
|
|
|
* |
108
|
|
|
* @var array |
109
|
|
|
*/ |
110
|
|
|
protected $taxes = array(); |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* An array of items for the submission. |
114
|
|
|
* |
115
|
|
|
* @var GetPaid_Form_Item[] |
116
|
|
|
*/ |
117
|
|
|
protected $items = array(); |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* The last error. |
121
|
|
|
* |
122
|
|
|
* @var string |
123
|
|
|
*/ |
124
|
|
|
public $last_error = null; |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Class constructor. |
128
|
|
|
* |
129
|
|
|
*/ |
130
|
|
|
public function __construct() { |
131
|
|
|
|
132
|
|
|
// Set the state and country to the default state and country. |
133
|
|
|
$this->country = wpinv_default_billing_country(); |
134
|
|
|
$this->state = wpinv_get_default_state(); |
|
|
|
|
135
|
|
|
|
136
|
|
|
// Do we have an actual submission? |
137
|
|
|
if ( isset( $_POST['getpaid_payment_form_submission'] ) ) { |
138
|
|
|
$this->load_data( $_POST ); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Loads submission data. |
145
|
|
|
* |
146
|
|
|
* @param array $data |
147
|
|
|
*/ |
148
|
|
|
public function load_data( $data ) { |
149
|
|
|
|
150
|
|
|
// Remove slashes from the submitted data... |
151
|
|
|
$data = wp_unslash( $data ); |
152
|
|
|
|
153
|
|
|
// Allow plugins to filter the data. |
154
|
|
|
$data = apply_filters( 'getpaid_submission_data', $data, $this ); |
155
|
|
|
|
156
|
|
|
// Cache it... |
157
|
|
|
$this->data = $data; |
|
|
|
|
158
|
|
|
|
159
|
|
|
// Then generate a unique id from the data. |
160
|
|
|
$this->id = md5( wp_json_encode( $data ) ); |
|
|
|
|
161
|
|
|
|
162
|
|
|
// Finally, process the submission. |
163
|
|
|
try { |
164
|
|
|
|
165
|
|
|
// Each process is passed an instance of the class (with reference) |
166
|
|
|
// and should throw an Exception whenever it encounters one. |
167
|
|
|
$processors = apply_filters( |
168
|
|
|
'getpaid_payment_form_submission_processors', |
169
|
|
|
array( |
170
|
|
|
array( $this, 'process_payment_form' ), |
171
|
|
|
array( $this, 'process_invoice' ), |
172
|
|
|
array( $this, 'process_fees' ), |
173
|
|
|
array( $this, 'process_items' ), |
174
|
|
|
array( $this, 'process_taxes' ), |
175
|
|
|
array( $this, 'process_discount' ), |
176
|
|
|
), |
177
|
|
|
$this |
178
|
|
|
); |
179
|
|
|
|
180
|
|
|
foreach ( $processors as $processor ) { |
181
|
|
|
call_user_func_array( $processor, array( &$this ) ); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
} catch ( Exception $e ) { |
185
|
|
|
$this->last_error = $e->getMessage(); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
// Fired when we are done processing a submission. |
189
|
|
|
do_action_ref_array( 'getpaid_process_submission', array( &$this ) ); |
190
|
|
|
|
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/* |
194
|
|
|
|-------------------------------------------------------------------------- |
195
|
|
|
| Payment Forms. |
196
|
|
|
|-------------------------------------------------------------------------- |
197
|
|
|
| |
198
|
|
|
| Functions for dealing with the submission's payment form. Ensure that the |
199
|
|
|
| submission has an active payment form etc. |
200
|
|
|
*/ |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Prepares the submission's payment form. |
204
|
|
|
* |
205
|
|
|
* @since 1.0.19 |
206
|
|
|
*/ |
207
|
|
|
public function process_payment_form() { |
208
|
|
|
|
209
|
|
|
// Every submission needs an active payment form. |
210
|
|
|
if ( empty( $this->data['form_id'] ) ) { |
211
|
|
|
throw new Exception( __( 'Missing payment form', 'invoicing' ) ); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
// Fetch the payment form. |
215
|
|
|
$this->payment_form = new GetPaid_Payment_Form( $this->data['form_id'] ); |
216
|
|
|
|
217
|
|
|
if ( ! $this->payment_form->is_active() ) { |
218
|
|
|
throw new Exception( __( 'Payment form not active', 'invoicing' ) ); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
do_action_ref_array( 'getpaid_submissions_process_payment_form', array( &$this ) ); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* Returns the payment form. |
226
|
|
|
* |
227
|
|
|
* @since 1.0.19 |
228
|
|
|
* @return GetPaid_Payment_Form |
229
|
|
|
*/ |
230
|
|
|
public function get_payment_form() { |
231
|
|
|
return $this->payment_form; |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/* |
235
|
|
|
|-------------------------------------------------------------------------- |
236
|
|
|
| Invoices. |
237
|
|
|
|-------------------------------------------------------------------------- |
238
|
|
|
| |
239
|
|
|
| Functions for dealing with the submission's invoice. Some submissions |
240
|
|
|
| might be for an existing invoice. |
241
|
|
|
*/ |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* Prepares the submission's invoice. |
245
|
|
|
* |
246
|
|
|
* @since 1.0.19 |
247
|
|
|
*/ |
248
|
|
|
public function process_invoice() { |
249
|
|
|
|
250
|
|
|
// Abort if there is no invoice. |
251
|
|
|
if ( empty( $this->data['invoice_id'] ) ) { |
252
|
|
|
return; |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
// If the submission is for an existing invoice, ensure that it exists |
256
|
|
|
// and that it is not paid for. |
257
|
|
|
$invoice = wpinv_get_invoice( $this->data['invoice_id'] ); |
258
|
|
|
|
259
|
|
|
if ( empty( $invoice ) ) { |
260
|
|
|
throw new Exception( __( 'Invalid invoice', 'invoicing' ) ); |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
if ( $invoice->is_paid() ) { |
264
|
|
|
throw new Exception( __( 'This invoice is already paid for.', 'invoicing' ) ); |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
$this->payment_form->set_items( $invoice->get_items() ); |
268
|
|
|
$this->payment_form->invoice = $invoice; |
269
|
|
|
|
270
|
|
|
$this->country = $invoice->get_country(); |
271
|
|
|
$this->state = $invoice->get_state(); |
272
|
|
|
$this->invoice = $invoice; |
273
|
|
|
|
274
|
|
|
do_action_ref_array( 'getpaid_submissions_process_invoice', array( &$this ) ); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Returns the associated invoice. |
279
|
|
|
* |
280
|
|
|
* @since 1.0.19 |
281
|
|
|
* @return WPInv_Invoice |
282
|
|
|
*/ |
283
|
|
|
public function get_invoice() { |
284
|
|
|
return $this->invoice; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* Checks whether there is an invoice associated with this submission. |
289
|
|
|
* |
290
|
|
|
* @since 1.0.19 |
291
|
|
|
* @return bool |
292
|
|
|
*/ |
293
|
|
|
public function has_invoice() { |
294
|
|
|
return ! empty( $this->invoice ); |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/* |
298
|
|
|
|-------------------------------------------------------------------------- |
299
|
|
|
| Items. |
300
|
|
|
|-------------------------------------------------------------------------- |
301
|
|
|
| |
302
|
|
|
| Functions for dealing with the submission's items. Submissions can only have one |
303
|
|
|
| recurring item. But can have an unlimited number of non-recurring items. |
304
|
|
|
*/ |
305
|
|
|
|
306
|
|
|
/** |
307
|
|
|
* Prepares the submission's items. |
308
|
|
|
* |
309
|
|
|
* @since 1.0.19 |
310
|
|
|
*/ |
311
|
|
|
public function process_items() { |
312
|
|
|
|
313
|
|
|
$processor = new GetPaid_Payment_Form_Submission_Items( $this ); |
314
|
|
|
|
315
|
|
|
foreach ( $processor->items as $item ) { |
316
|
|
|
$this->add_item( $item ); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
do_action_ref_array( 'getpaid_submissions_process_items', array( &$this ) ); |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* Adds an item to the submission. |
324
|
|
|
* |
325
|
|
|
* @since 1.0.19 |
326
|
|
|
* @param GetPaid_Form_Item $item |
327
|
|
|
*/ |
328
|
|
|
public function add_item( $item ) { |
329
|
|
|
|
330
|
|
|
// Make sure that it is available for purchase. |
331
|
|
|
if ( ! $item->can_purchase() ) { |
332
|
|
|
return; |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
// Each submission can only contain one recurring item. |
336
|
|
|
if ( $item->is_recurring() ) { |
337
|
|
|
|
338
|
|
|
if ( $this->has_recurring != 0 ) { |
339
|
|
|
throw new Exception( __( 'You can only buy one recurring item at a time.', 'invoicing' ) ); |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
$this->has_recurring = $item->get_id(); |
343
|
|
|
|
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
// Update the items and totals. |
347
|
|
|
$this->items[ $item->get_id() ] = $item; |
348
|
|
|
$this->totals['subtotal']['initial'] += $item->get_sub_total(); |
349
|
|
|
$this->totals['subtotal']['recurring'] += $item->get_recurring_sub_total(); |
350
|
|
|
|
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
/** |
354
|
|
|
* Removes a specific item. |
355
|
|
|
* |
356
|
|
|
* You should not call this method after the discounts and taxes |
357
|
|
|
* have been calculated. |
358
|
|
|
* |
359
|
|
|
* @since 1.0.19 |
360
|
|
|
*/ |
361
|
|
|
public function remove_item( $item_id ) { |
362
|
|
|
|
363
|
|
|
if ( isset( $this->items[ $item_id ] ) ) { |
364
|
|
|
$this->totals['subtotal']['initial'] -= $this->items[ $item_id ]->get_sub_total(); |
365
|
|
|
$this->totals['subtotal']['recurring'] -= $this->items[ $item_id ]->get_recurring_sub_total(); |
366
|
|
|
|
367
|
|
|
if ( $this->items[ $item_id ]->is_recurring() ) { |
368
|
|
|
$this->has_recurring = 0; |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
unset( $this->items[ $item_id ] ); |
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* Returns the subtotal. |
378
|
|
|
* |
379
|
|
|
* @since 1.0.19 |
380
|
|
|
*/ |
381
|
|
|
public function get_subtotal() { |
382
|
|
|
return $this->totals['subtotal']['initial']; |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
/** |
386
|
|
|
* Returns the recurring subtotal. |
387
|
|
|
* |
388
|
|
|
* @since 1.0.19 |
389
|
|
|
*/ |
390
|
|
|
public function get_recurring_subtotal() { |
391
|
|
|
return $this->totals['subtotal']['recurring']; |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
/** |
395
|
|
|
* Returns all items. |
396
|
|
|
* |
397
|
|
|
* @since 1.0.19 |
398
|
|
|
* @return GetPaid_Form_Item[] |
399
|
|
|
*/ |
400
|
|
|
public function get_items() { |
401
|
|
|
return $this->items; |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
/* |
405
|
|
|
|-------------------------------------------------------------------------- |
406
|
|
|
| Taxes |
407
|
|
|
|-------------------------------------------------------------------------- |
408
|
|
|
| |
409
|
|
|
| Functions for dealing with submission taxes. Taxes can be recurring |
410
|
|
|
| or only one-time. |
411
|
|
|
*/ |
412
|
|
|
|
413
|
|
|
/** |
414
|
|
|
* Prepares the submission's taxes. |
415
|
|
|
* |
416
|
|
|
* @since 1.0.19 |
417
|
|
|
*/ |
418
|
|
|
public function process_taxes() { |
419
|
|
|
|
420
|
|
|
// Abort if we're not using taxes. |
421
|
|
|
if ( ! $this->use_taxes() ) { |
422
|
|
|
return; |
423
|
|
|
} |
424
|
|
|
|
425
|
|
|
// If a custom country && state has been passed in, use it to calculate taxes. |
426
|
|
|
if ( ! empty( $this->data['wpinv_country'] ) ) { |
427
|
|
|
$this->country = $this->data['wpinv_country']; |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
if ( ! empty( $this->data['wpinv_state'] ) ) { |
431
|
|
|
$this->country = $this->data['wpinv_state']; |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
$processor = new GetPaid_Payment_Form_Submission_Taxes( $this ); |
435
|
|
|
|
436
|
|
|
foreach ( $processor->taxes as $tax ) { |
437
|
|
|
$this->add_tax( $tax ); |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
do_action_ref_array( 'getpaid_submissions_process_taxes', array( &$this ) ); |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
/** |
444
|
|
|
* Adds a tax to the submission. |
445
|
|
|
* |
446
|
|
|
* @param array $tax An array of tax details. name, initial_tax, and recurring_tax are required. |
447
|
|
|
* @since 1.0.19 |
448
|
|
|
*/ |
449
|
|
|
public function add_tax( $tax ) { |
450
|
|
|
$this->taxes[ $tax['name'] ] = $tax; |
451
|
|
|
$this->totals['taxes']['initial'] += wpinv_sanitize_amount( $tax['initial_tax'] ); |
452
|
|
|
$this->totals['taxes']['recurring'] += wpinv_sanitize_amount( $tax['recurring_tax'] ); |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** |
456
|
|
|
* Removes a specific tax. |
457
|
|
|
* |
458
|
|
|
* @since 1.0.19 |
459
|
|
|
*/ |
460
|
|
|
public function remove_tax( $tax_name ) { |
461
|
|
|
|
462
|
|
|
if ( isset( $this->taxes[ $tax_name ] ) ) { |
463
|
|
|
$this->totals['taxes']['initial'] -= $this->taxes[ $tax_name ]['initial_tax']; |
464
|
|
|
$this->totals['taxes']['recurring'] -= $this->taxes[ $tax_name ]['recurring_tax']; |
465
|
|
|
unset( $this->taxes[ $tax_name ] ); |
466
|
|
|
} |
467
|
|
|
|
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
/** |
471
|
|
|
* Whether or not we'll use taxes for the submission. |
472
|
|
|
* |
473
|
|
|
* @since 1.0.19 |
474
|
|
|
*/ |
475
|
|
|
public function use_taxes() { |
476
|
|
|
|
477
|
|
|
$use_taxes = wpinv_use_taxes(); |
478
|
|
|
|
479
|
|
|
if ( $this->has_invoice() && ! $this->invoice->is_taxable() ) { |
480
|
|
|
$use_taxes = false; |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
return apply_filters( 'getpaid_submission_use_taxes', $use_taxes, $this ); |
484
|
|
|
|
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
/** |
488
|
|
|
* Returns the tax. |
489
|
|
|
* |
490
|
|
|
* @since 1.0.19 |
491
|
|
|
*/ |
492
|
|
|
public function get_tax() { |
493
|
|
|
return $this->totals['taxes']['initial']; |
494
|
|
|
} |
495
|
|
|
|
496
|
|
|
/** |
497
|
|
|
* Returns the recurring tax. |
498
|
|
|
* |
499
|
|
|
* @since 1.0.19 |
500
|
|
|
*/ |
501
|
|
|
public function get_recurring_tax() { |
502
|
|
|
return $this->totals['taxes']['recurring']; |
503
|
|
|
} |
504
|
|
|
|
505
|
|
|
/** |
506
|
|
|
* Returns all taxes. |
507
|
|
|
* |
508
|
|
|
* @since 1.0.19 |
509
|
|
|
*/ |
510
|
|
|
public function get_taxes() { |
511
|
|
|
return $this->taxes; |
512
|
|
|
} |
513
|
|
|
|
514
|
|
|
/* |
515
|
|
|
|-------------------------------------------------------------------------- |
516
|
|
|
| Discounts |
517
|
|
|
|-------------------------------------------------------------------------- |
518
|
|
|
| |
519
|
|
|
| Functions for dealing with submission discounts. Discounts can be recurring |
520
|
|
|
| or only one-time. They also do not have to come from a discount code. |
521
|
|
|
*/ |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* Prepares the submission's discount. |
525
|
|
|
* |
526
|
|
|
* @since 1.0.19 |
527
|
|
|
*/ |
528
|
|
|
public function process_discount() { |
529
|
|
|
|
530
|
|
|
$initial_total = $this->get_subtotal() + $this->get_fee() + $this->get_tax(); |
531
|
|
|
$recurring_total = $this->get_recurring_subtotal() + $this->get_recurring_fee() + $this->get_recurring_tax(); |
532
|
|
|
$processor = new GetPaid_Payment_Form_Submission_Discount( $this, $initial_total, $recurring_total ); |
533
|
|
|
|
534
|
|
|
foreach ( $processor->discounts as $discount ) { |
535
|
|
|
$this->add_discount( $discount ); |
536
|
|
|
} |
537
|
|
|
|
538
|
|
|
do_action_ref_array( 'getpaid_submissions_process_discounts', array( &$this ) ); |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* Adds a discount to the submission. |
543
|
|
|
* |
544
|
|
|
* @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. |
545
|
|
|
* @since 1.0.19 |
546
|
|
|
*/ |
547
|
|
|
public function add_discount( $discount ) { |
548
|
|
|
$this->discounts[ $discount['name'] ] = $discount; |
549
|
|
|
$this->totals['discount']['initial'] += wpinv_sanitize_amount( $discount['initial_discount'] ); |
550
|
|
|
$this->totals['discount']['recurring'] += wpinv_sanitize_amount( $discount['recurring_discount'] ); |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
/** |
554
|
|
|
* Removes a discount from the submission. |
555
|
|
|
* |
556
|
|
|
* @since 1.0.19 |
557
|
|
|
*/ |
558
|
|
|
public function remove_discount( $name ) { |
559
|
|
|
|
560
|
|
|
if ( isset( $this->discounts[ $name ] ) ) { |
561
|
|
|
$this->totals['discount']['initial'] -= $this->discounts[ $name ]['initial_discount']; |
562
|
|
|
$this->totals['discount']['recurring'] -= $this->discounts[ $name ]['recurring_discount']; |
563
|
|
|
unset( $this->discounts[ $name ] ); |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
} |
567
|
|
|
|
568
|
|
|
/** |
569
|
|
|
* Checks whether there is a discount code associated with this submission. |
570
|
|
|
* |
571
|
|
|
* @since 1.0.19 |
572
|
|
|
* @return bool |
573
|
|
|
*/ |
574
|
|
|
public function has_discount_code() { |
575
|
|
|
return ! empty( $this->discounts['discount_code'] ); |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
/** |
579
|
|
|
* Returns the discount code. |
580
|
|
|
* |
581
|
|
|
* @since 1.0.19 |
582
|
|
|
* @return string |
583
|
|
|
*/ |
584
|
|
|
public function get_discount_code() { |
585
|
|
|
return $this->has_discount_code() ? $this->discounts['discount_code']['discount_code'] : ''; |
586
|
|
|
} |
587
|
|
|
|
588
|
|
|
/** |
589
|
|
|
* Returns the discount. |
590
|
|
|
* |
591
|
|
|
* @since 1.0.19 |
592
|
|
|
*/ |
593
|
|
|
public function get_discount() { |
594
|
|
|
return $this->totals['discount']['initial']; |
595
|
|
|
} |
596
|
|
|
|
597
|
|
|
/** |
598
|
|
|
* Returns the recurring discount. |
599
|
|
|
* |
600
|
|
|
* @since 1.0.19 |
601
|
|
|
*/ |
602
|
|
|
public function get_recurring_discount() { |
603
|
|
|
return $this->totals['discount']['recurring']; |
604
|
|
|
} |
605
|
|
|
|
606
|
|
|
/** |
607
|
|
|
* Returns all discounts. |
608
|
|
|
* |
609
|
|
|
* @since 1.0.19 |
610
|
|
|
*/ |
611
|
|
|
public function get_discounts() { |
612
|
|
|
return $this->discounts; |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
/* |
616
|
|
|
|-------------------------------------------------------------------------- |
617
|
|
|
| Fees |
618
|
|
|
|-------------------------------------------------------------------------- |
619
|
|
|
| |
620
|
|
|
| Functions for dealing with submission fees. Fees can be recurring |
621
|
|
|
| or only one-time. Price input and Price select elements are treated as |
622
|
|
|
| fees. |
623
|
|
|
*/ |
624
|
|
|
|
625
|
|
|
/** |
626
|
|
|
* Prepares the submission's fees. |
627
|
|
|
* |
628
|
|
|
* @since 1.0.19 |
629
|
|
|
*/ |
630
|
|
|
public function process_fees() { |
631
|
|
|
|
632
|
|
|
$fees_processor = new GetPaid_Payment_Form_Submission_Fees( $this ); |
633
|
|
|
|
634
|
|
|
foreach ( $fees_processor->fees as $fee ) { |
635
|
|
|
$this->add_fee( $fee ); |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
do_action_ref_array( 'getpaid_submissions_process_fees', array( &$this ) ); |
639
|
|
|
} |
640
|
|
|
|
641
|
|
|
/** |
642
|
|
|
* Adds a fee to the submission. |
643
|
|
|
* |
644
|
|
|
* @param array $fee An array of fee details. name, initial_fee, and recurring_fee are required. |
645
|
|
|
* @since 1.0.19 |
646
|
|
|
*/ |
647
|
|
|
public function add_fee( $fee ) { |
648
|
|
|
|
649
|
|
|
$this->fees[ $fee['name'] ] = $fee; |
650
|
|
|
$this->totals['fees']['initial'] += wpinv_sanitize_amount( $fee['initial_fee'] ); |
651
|
|
|
$this->totals['fees']['recurring'] += wpinv_sanitize_amount( $fee['recurring_fee'] ); |
652
|
|
|
|
653
|
|
|
} |
654
|
|
|
|
655
|
|
|
/** |
656
|
|
|
* Removes a fee from the submission. |
657
|
|
|
* |
658
|
|
|
* @since 1.0.19 |
659
|
|
|
*/ |
660
|
|
|
public function remove_fee( $name ) { |
661
|
|
|
|
662
|
|
|
if ( isset( $this->fees[ $name ] ) ) { |
663
|
|
|
$this->totals['fees']['initial'] -= $this->fees[ $name ]['initial_fee']; |
664
|
|
|
$this->totals['fees']['recurring'] -= $this->fees[ $name ]['recurring_fee']; |
665
|
|
|
unset( $this->fees[ $name ] ); |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
} |
669
|
|
|
|
670
|
|
|
/** |
671
|
|
|
* Returns the fees. |
672
|
|
|
* |
673
|
|
|
* @since 1.0.19 |
674
|
|
|
*/ |
675
|
|
|
public function get_fee() { |
676
|
|
|
return $this->totals['fees']['initial']; |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
/** |
680
|
|
|
* Returns the recurring fees. |
681
|
|
|
* |
682
|
|
|
* @since 1.0.19 |
683
|
|
|
*/ |
684
|
|
|
public function get_recurring_fee() { |
685
|
|
|
return $this->totals['fees']['recurring']; |
686
|
|
|
} |
687
|
|
|
|
688
|
|
|
/** |
689
|
|
|
* Returns all fees. |
690
|
|
|
* |
691
|
|
|
* @since 1.0.19 |
692
|
|
|
*/ |
693
|
|
|
public function get_fees() { |
694
|
|
|
return $this->fees; |
695
|
|
|
} |
696
|
|
|
|
697
|
|
|
/** |
698
|
|
|
* Checks if there are any fees for the form. |
699
|
|
|
* |
700
|
|
|
* @return bool |
701
|
|
|
* @since 1.0.19 |
702
|
|
|
*/ |
703
|
|
|
public function has_fees() { |
704
|
|
|
return count( $this->fees ) !== 0; |
705
|
|
|
} |
706
|
|
|
|
707
|
|
|
/* |
708
|
|
|
|-------------------------------------------------------------------------- |
709
|
|
|
| MISC |
710
|
|
|
|-------------------------------------------------------------------------- |
711
|
|
|
| |
712
|
|
|
| Extra submission functions. |
713
|
|
|
*/ |
714
|
|
|
|
715
|
|
|
/** |
716
|
|
|
* Returns the total amount to collect for this submission. |
717
|
|
|
* |
718
|
|
|
* @since 1.0.19 |
719
|
|
|
*/ |
720
|
|
|
public function get_total() { |
721
|
|
|
$total = $this->get_subtotal() + $this->get_fee() + $this->get_tax() - $this->get_discount(); |
722
|
|
|
return max( $total, 0 ); |
723
|
|
|
} |
724
|
|
|
|
725
|
|
|
/** |
726
|
|
|
* Returns the recurring total amount to collect for this submission. |
727
|
|
|
* |
728
|
|
|
* @since 1.0.19 |
729
|
|
|
*/ |
730
|
|
|
public function get_recurring_total() { |
731
|
|
|
$total = $this->get_recurring_subtotal() + $this->get_recurring_fee() + $this->get_recurring_tax() - $this->get_recurring_discount(); |
732
|
|
|
return max( $total, 0 ); |
733
|
|
|
} |
734
|
|
|
|
735
|
|
|
/** |
736
|
|
|
* Whether payment details should be collected for this submission. |
737
|
|
|
* |
738
|
|
|
* @since 1.0.19 |
739
|
|
|
*/ |
740
|
|
|
public function should_collect_payment_details() { |
741
|
|
|
$initial = $this->get_total(); |
742
|
|
|
$recurring = $this->get_recurring_total(); |
743
|
|
|
|
744
|
|
|
if ( $this->has_recurring == 0 ) { |
745
|
|
|
$recurring = 0; |
746
|
|
|
} |
747
|
|
|
|
748
|
|
|
$collect = $initial > 0 || $recurring > 0; |
749
|
|
|
return apply_filters( 'getpaid_submission_should_collect_payment_details', $collect, $this ); |
750
|
|
|
} |
751
|
|
|
|
752
|
|
|
/** |
753
|
|
|
* Returns the billing email of the user. |
754
|
|
|
* |
755
|
|
|
* @since 1.0.19 |
756
|
|
|
*/ |
757
|
|
|
public function get_billing_email() { |
758
|
|
|
return apply_filters( 'getpaid_get_submission_billing_email', $this->get_field( 'billing_email' ), $this ); |
759
|
|
|
} |
760
|
|
|
|
761
|
|
|
/** |
762
|
|
|
* Checks if the submitter has a billing email. |
763
|
|
|
* |
764
|
|
|
* @since 1.0.19 |
765
|
|
|
*/ |
766
|
|
|
public function has_billing_email() { |
767
|
|
|
$billing_email = $this->get_billing_email(); |
768
|
|
|
return ! empty( $billing_email ); |
769
|
|
|
} |
770
|
|
|
|
771
|
|
|
/** |
772
|
|
|
* Returns the appropriate currency for the submission. |
773
|
|
|
* |
774
|
|
|
* @since 1.0.19 |
775
|
|
|
* @return string |
776
|
|
|
*/ |
777
|
|
|
public function get_currency() { |
778
|
|
|
return $this->has_invoice() ? $this->invoice->get_currency() : wpinv_get_currency(); |
779
|
|
|
} |
780
|
|
|
|
781
|
|
|
/** |
782
|
|
|
* Returns the raw submission data. |
783
|
|
|
* |
784
|
|
|
* @since 1.0.19 |
785
|
|
|
* @return array |
786
|
|
|
*/ |
787
|
|
|
public function get_data() { |
788
|
|
|
return $this->data; |
789
|
|
|
} |
790
|
|
|
|
791
|
|
|
/** |
792
|
|
|
* Returns a field from the submission data |
793
|
|
|
* |
794
|
|
|
* @param string $field |
795
|
|
|
* @since 1.0.19 |
796
|
|
|
* @return mixed |
797
|
|
|
*/ |
798
|
|
|
public function get_field( $field ) { |
799
|
|
|
return isset( $this->data[ $field ] ) ? $this->data[ $field ] : ''; |
800
|
|
|
} |
801
|
|
|
|
802
|
|
|
/** |
803
|
|
|
* Checks if a required field is set. |
804
|
|
|
* |
805
|
|
|
* @since 1.0.19 |
806
|
|
|
*/ |
807
|
|
|
public function is_required_field_set( $field ) { |
808
|
|
|
return empty( $field['required'] ) || ! empty( $this->data[ $field['id'] ] ); |
809
|
|
|
} |
810
|
|
|
|
811
|
|
|
/** |
812
|
|
|
* Formats an amount |
813
|
|
|
* |
814
|
|
|
* @since 1.0.19 |
815
|
|
|
*/ |
816
|
|
|
public function format_amount( $amount ) { |
817
|
|
|
return wpinv_price( $amount, $this->get_currency() ); |
818
|
|
|
} |
819
|
|
|
|
820
|
|
|
} |
821
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.