Passed
Push — master ( 0cc6c6...451f1a )
by Brian
06:48 queued 27s
created

WPInv_Ajax::file_upload()   C

Complexity

Conditions 11
Paths 192

Size

Total Lines 60
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 31
c 0
b 0
f 0
nc 192
nop 0
dl 0
loc 60
rs 6.55

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
/**
3
 * Contains the ajax handlers.
4
 *
5
 * @since 1.0.0
6
 * @package Invoicing
7
 */
8
 
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * WPInv_Ajax class.
13
 */
14
class WPInv_Ajax {
15
16
    /**
17
	 * Hook in ajax handlers.
18
	 */
19
	public static function init() {
20
		add_action( 'init', array( __CLASS__, 'define_ajax' ), 0 );
21
		add_action( 'template_redirect', array( __CLASS__, 'do_wpinv_ajax' ), 0 );
22
		self::add_ajax_events();
23
    }
24
25
    /**
26
	 * Set GetPaid AJAX constant and headers.
27
	 */
28
	public static function define_ajax() {
29
30
		if ( ! empty( $_GET['wpinv-ajax'] ) ) {
31
			getpaid_maybe_define_constant( 'DOING_AJAX', true );
32
			getpaid_maybe_define_constant( 'WPInv_DOING_AJAX', true );
33
			if ( ! WP_DEBUG || ( WP_DEBUG && ! WP_DEBUG_DISPLAY ) ) {
34
				/** @scrutinizer ignore-unhandled */ @ini_set( 'display_errors', 0 );
35
			}
36
			$GLOBALS['wpdb']->hide_errors();
37
		}
38
39
    }
40
    
41
    /**
42
	 * Send headers for GetPaid Ajax Requests.
43
	 *
44
	 * @since 1.0.18
45
	 */
46
	private static function wpinv_ajax_headers() {
47
		if ( ! headers_sent() ) {
48
			send_origin_headers();
49
			send_nosniff_header();
50
			nocache_headers();
51
			header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
52
			header( 'X-Robots-Tag: noindex' );
53
			status_header( 200 );
54
		}
55
    }
56
    
57
    /**
58
	 * Check for GetPaid Ajax request and fire action.
59
	 */
60
	public static function do_wpinv_ajax() {
61
		global $wp_query;
62
63
		if ( ! empty( $_GET['wpinv-ajax'] ) ) {
64
			$wp_query->set( 'wpinv-ajax', sanitize_text_field( wp_unslash( $_GET['wpinv-ajax'] ) ) );
0 ignored issues
show
Bug introduced by
It seems like wp_unslash($_GET['wpinv-ajax']) can also be of type array; however, parameter $str of sanitize_text_field() 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

64
			$wp_query->set( 'wpinv-ajax', sanitize_text_field( /** @scrutinizer ignore-type */ wp_unslash( $_GET['wpinv-ajax'] ) ) );
Loading history...
65
		}
66
67
		$action = $wp_query->get( 'wpinv-ajax' );
68
69
		if ( $action ) {
70
			self::wpinv_ajax_headers();
71
			$action = sanitize_text_field( $action );
72
			do_action( 'wpinv_ajax_' . $action );
73
			wp_die();
74
		}
75
76
    }
77
78
    /**
79
	 * Hook in ajax methods.
80
	 */
81
    public static function add_ajax_events() {
82
83
        // array( 'event' => is_frontend )
84
        $ajax_events = array(
85
            'add_note'                    => false,
86
            'delete_note'                 => false,
87
            'get_states_field'            => true,
88
            'get_aui_states_field'        => true,
89
            'payment_form'                => true,
90
            'get_payment_form'            => true,
91
            'get_payment_form_states_field' => true,
92
            'get_invoicing_items'         => false,
93
            'get_customers'               => false,
94
            'get_invoice_items'           => false,
95
            'add_invoice_items'           => false,
96
            'admin_add_invoice_item'      => false,
97
            'recalculate_full_prices'     => false,
98
            'edit_invoice_item'           => false,
99
            'create_invoice_item'         => false,
100
            'remove_invoice_item'         => false,
101
            'get_billing_details'         => false,
102
            'recalculate_invoice_totals'  => false,
103
            'check_new_user_email'        => false,
104
            'run_tool'                    => false,
105
            'payment_form_refresh_prices' => true,
106
            'file_upload'                 => true,
107
        );
108
109
        foreach ( $ajax_events as $ajax_event => $nopriv ) {
110
            add_action( 'wp_ajax_wpinv_' . $ajax_event, array( __CLASS__, $ajax_event ) );
111
            add_action( 'wp_ajax_getpaid_' . $ajax_event, array( __CLASS__, $ajax_event ) );
112
113
            if ( $nopriv ) {
114
                add_action( 'wp_ajax_nopriv_wpinv_' . $ajax_event, array( __CLASS__, $ajax_event ) );
115
                add_action( 'wp_ajax_nopriv_getpaid_' . $ajax_event, array( __CLASS__, $ajax_event ) );
116
                add_action( 'wpinv_ajax_' . $ajax_event, array( __CLASS__, $ajax_event ) );
117
            }
118
        }
119
    }
120
    
121
    public static function add_note() {
122
        check_ajax_referer( 'add-invoice-note', '_nonce' );
123
124
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
125
            die(-1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
126
        }
127
128
        $post_id   = absint( $_POST['post_id'] );
129
        $note      = wp_kses_post( trim( stripslashes( $_POST['note'] ) ) );
130
        $note_type = sanitize_text_field( $_POST['note_type'] );
131
132
        $is_customer_note = $note_type == 'customer' ? 1 : 0;
133
134
        if ( $post_id > 0 ) {
135
            $note_id = wpinv_insert_payment_note( $post_id, $note, $is_customer_note );
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_insert_payment_note() has been deprecated. ( Ignorable by Annotation )

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

135
            $note_id = /** @scrutinizer ignore-deprecated */ wpinv_insert_payment_note( $post_id, $note, $is_customer_note );
Loading history...
136
137
            if ( $note_id > 0 && !is_wp_error( $note_id ) ) {
138
                wpinv_get_invoice_note_line_item( $note_id );
139
            }
140
        }
141
142
        die();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
143
    }
144
145
    public static function delete_note() {
146
        check_ajax_referer( 'delete-invoice-note', '_nonce' );
147
148
        if ( !wpinv_current_user_can_manage_invoicing() ) {
149
            die(-1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
150
        }
151
152
        $note_id = (int)$_POST['note_id'];
153
154
        if ( $note_id > 0 ) {
155
            wp_delete_comment( $note_id, true );
156
        }
157
158
        die();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
159
    }
160
    
161
    public static function get_states_field() {
162
        echo wpinv_get_states_field();
163
        
164
        die();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
165
    }
166
167
    /**
168
     * Retrieves a given user's billing address.
169
     */
170
    public static function get_billing_details() {
171
172
        // Verify nonce.
173
        check_ajax_referer( 'wpinv-nonce' );
174
175
        // Can the user manage the plugin?
176
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
177
            die(-1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
178
        }
179
180
        // Do we have a user id?
181
        $user_id = $_GET['user_id'];
182
183
        if ( empty( $user_id ) || ! is_numeric( $user_id ) ) {
184
            die(-1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
185
        }
186
187
        // Fetch the billing details.
188
        $billing_details    = wpinv_get_user_address( $user_id );
189
        $billing_details    = apply_filters( 'wpinv_ajax_billing_details', $billing_details, $user_id );
190
191
        // unset the user id and email.
192
        $to_ignore = array( 'user_id', 'email' );
193
194
        foreach ( $to_ignore as $key ) {
195
            if ( isset( $billing_details[ $key ] ) ) {
196
                unset( $billing_details[ $key ] );
197
            }
198
        }
199
200
        wp_send_json_success( $billing_details );
201
202
    }
203
204
    /**
205
     * Checks if a new users email is valid.
206
     */
207
    public static function check_new_user_email() {
208
209
        // Verify nonce.
210
        check_ajax_referer( 'wpinv-nonce' );
211
212
        // Can the user manage the plugin?
213
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
214
            die(-1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
215
        }
216
217
        // We need an email address.
218
        if ( empty( $_GET['email'] ) ) {
219
            _e( "Provide the new user's email address", 'invoicing' );
220
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
221
        }
222
223
        // Ensure the email is valid.
224
        $email = sanitize_text_field( $_GET['email'] );
225
        if ( ! is_email( $email ) ) {
226
            _e( 'Invalid email address', 'invoicing' );
227
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
228
        }
229
230
        // And it does not exist.
231
        $id = email_exists( $email );
232
        if ( $id ) {
233
            wp_send_json_success( compact( 'id' ) );
234
        }
235
236
        wp_send_json_success( true );
237
    }
238
    
239
    public static function run_tool() {
240
        check_ajax_referer( 'wpinv-nonce', '_nonce' );
241
        if ( !wpinv_current_user_can_manage_invoicing() ) {
242
            die(-1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
243
        }
244
        
245
        $tool = sanitize_text_field( $_POST['tool'] );
246
        
247
        do_action( 'wpinv_run_tool' );
248
        
249
        if ( !empty( $tool ) ) {
250
            do_action( 'wpinv_tool_' . $tool );
251
        }
252
    }
253
254
    /**
255
     * Retrieves the markup for a payment form.
256
     */
257
    public static function get_payment_form() {
258
        global $getpaid_force_checkbox;
259
260
        // Check nonce.
261
        check_ajax_referer( 'getpaid_form_nonce' );
262
263
        // Is the request set up correctly?
264
		if ( empty( $_GET['form'] ) && empty( $_GET['item'] ) && empty( $_GET['invoice'] ) ) {
265
			echo aui()->alert(
266
				array(
267
					'type'    => 'warning',
268
					'content' => __( 'No payment form or item provided', 'invoicing' ),
269
				)
270
            );
271
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
272
        }
273
274
        // Payment form or button?
275
		if ( ! empty( $_GET['form'] ) ) {
276
            $form = urldecode( $_GET['form'] );
277
278
            if ( false !== strpos( $form, '|' ) ) {
279
                $form_pos = strpos( $form, '|' );
280
                $_items   = getpaid_convert_items_to_array( substr( $form, $form_pos + 1 ) );
281
                $form     = substr( $form, 0, $form_pos );
282
283
                // Retrieve appropriate payment form.
284
                $payment_form = new GetPaid_Payment_Form( $form );
285
                $payment_form = $payment_form->exists() ? $payment_form : new GetPaid_Payment_Form( wpinv_get_default_payment_form() );
286
287
                $items    = array();
288
                $item_ids = array();
289
290
                foreach ( $_items as $item_id => $qty ) {
291
                    if ( ! in_array( $item_id, $item_ids ) ) {
292
                        $item = new GetPaid_Form_Item( $item_id );
293
                        $item->set_quantity( $qty );
294
295
                        if ( 0 == $qty ) {
296
                            $item->set_allow_quantities( true );
297
                            $item->set_is_required( false );
298
                            $getpaid_force_checkbox = true;
299
                        }
300
301
                        $item_ids[] = $item->get_id();
302
                        $items[]    = $item;
303
                    }
304
                }
305
306
                if ( ! $payment_form->is_default() ) {
307
308
                    foreach ( $payment_form->get_items() as $item ) {
309
                        if ( ! in_array( $item->get_id(), $item_ids ) ) {
310
                            $item_ids[] = $item->get_id();
311
                            $items[]    = $item;
312
                        }
313
                    }
314
315
                }
316
317
                $payment_form->set_items( $items );
318
                $extra_items     = esc_attr( getpaid_convert_items_to_string( $_items ) );
319
                $extra_items_key = md5( NONCE_KEY . AUTH_KEY . $extra_items );
320
                $extra_items     = "<input type='hidden' name='getpaid-form-items' value='$extra_items' />";
321
                $extra_items    .= "<input type='hidden' name='getpaid-form-items-key' value='$extra_items_key' />";
322
                $payment_form->display( $extra_items );
323
                $getpaid_force_checkbox = false;
324
325
            } else {
326
                getpaid_display_payment_form( $form );
327
            }
328
329
		} else if( ! empty( $_GET['invoice'] ) ) {
330
		    getpaid_display_invoice_payment_form( urldecode( $_GET['invoice'] ) );
331
        } else {
332
			$items = getpaid_convert_items_to_array( urldecode( $_GET['item'] ) );
333
		    getpaid_display_item_payment_form( $items );
334
        }
335
336
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
337
338
    }
339
340
    /**
341
     * Payment forms.
342
     *
343
     * @since 1.0.18
344
     */
345
    public static function payment_form() {
346
347
        // Check nonce.
348
        check_ajax_referer( 'getpaid_form_nonce' );
349
350
        // ... form fields...
351
        if ( empty( $_POST['getpaid_payment_form_submission'] ) ) {
352
            _e( 'Error: Reload the page and try again.', 'invoicing' );
353
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
354
        }
355
356
        // Process the payment form.
357
        $checkout_class = apply_filters( 'getpaid_checkout_class', 'GetPaid_Checkout' );
358
        $checkout       = new $checkout_class( new GetPaid_Payment_Form_Submission() );
359
        $checkout->process_checkout();
360
361
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
362
    }
363
364
    /**
365
     * Payment forms.
366
     *
367
     * @since 1.0.18
368
     */
369
    public static function get_payment_form_states_field() {
370
371
        if ( empty( $_GET['country'] ) || empty( $_GET['form'] ) ) {
372
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
373
        }
374
375
        $elements = getpaid_get_payment_form_elements( $_GET['form'] );
376
377
        if ( empty( $elements ) ) {
378
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
379
        }
380
381
        $address_fields = array();
382
        foreach ( $elements as $element ) {
383
            if ( 'address' === $element['type'] ) {
384
                $address_fields = $element;
385
                break;
386
            }
387
        }
388
389
        if ( empty( $address_fields ) ) {
390
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
391
        }
392
393
        foreach ( $address_fields['fields'] as $address_field ) {
394
395
            if ( 'wpinv_state' == $address_field['name'] ) {
396
397
                $wrap_class  = getpaid_get_form_element_grid_class( $address_field );
398
                $wrap_class  = esc_attr( "$wrap_class getpaid-address-field-wrapper" );
399
                $placeholder = empty( $address_field['placeholder'] ) ? '' : esc_attr( $address_field['placeholder'] );
400
                $description = empty( $address_field['description'] ) ? '' : wp_kses_post( $address_field['description'] );
401
                $value       = is_user_logged_in() ? get_user_meta( get_current_user_id(), '_wpinv_state', true ) : '';
402
                $label       = empty( $address_field['label'] ) ? '' : wp_kses_post( $address_field['label'] );
403
404
                if ( ! empty( $address_field['required'] ) ) {
405
                    $label .= "<span class='text-danger'> *</span>";
406
                }
407
408
                $html = getpaid_get_states_select_markup (
409
                    sanitize_text_field( $_GET['country'] ),
410
                    $value,
411
                    $placeholder,
412
                    $label,
413
                    $description,
414
                    ! empty( $address_field['required'] ),
415
                    $wrap_class,
416
                    wpinv_clean( $_GET['name'] )
417
                );
418
419
                wp_send_json_success( $html );
420
                exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
421
422
            }
423
424
        }
425
    
426
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
427
    }
428
429
    /**
430
     * Recalculates invoice totals.
431
     */
432
    public static function recalculate_invoice_totals() {
433
434
        // Verify nonce.
435
        check_ajax_referer( 'wpinv-nonce' );
436
437
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
438
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
439
        }
440
441
        // We need an invoice.
442
        if ( empty( $_POST['post_id'] ) ) {
443
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
444
        }
445
446
        // Fetch the invoice.
447
        $invoice = new WPInv_Invoice( wpinv_clean( $_POST['post_id'] ) );
448
449
        // Ensure it exists.
450
        if ( ! $invoice->get_id() ) {
451
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
452
        }
453
454
        // Maybe set the country, state, currency.
455
        foreach ( array( 'country', 'state', 'currency', 'vat_number', 'discount_code' ) as $key ) {
456
            if ( isset( $_POST[ $key ] ) ) {
457
                $method = "set_$key";
458
                $invoice->$method( sanitize_text_field( $_POST[ $key ] ) );
459
            }
460
        }
461
462
        // Maybe disable taxes.
463
        $invoice->set_disable_taxes( ! empty( $_POST['taxes'] ) );
464
465
        // Discount code.
466
        if ( ! $invoice->is_paid() && ! $invoice->is_refunded() ) {
467
            $discount = new WPInv_Discount( $invoice->get_discount_code() );
468
            if ( $discount->exists() ) {
469
                $invoice->add_discount( getpaid_calculate_invoice_discount( $invoice, $discount ) );
470
            } else {
471
                $invoice->remove_discount( 'discount_code' );
472
            }
473
        }
474
475
        // Recalculate totals.
476
        $invoice->recalculate_total();
477
478
        $total        = wpinv_price( $invoice->get_total(), $invoice->get_currency() );
479
        $suscriptions = getpaid_get_invoice_subscriptions( $invoice );
480
        if ( is_a( $suscriptions, 'WPInv_Subscription' ) && $invoice->is_recurring() && $invoice->is_parent() && $invoice->get_total() != $invoice->get_recurring_total() ) {
481
            $recurring_total = wpinv_price( $invoice->get_recurring_total(), $invoice->get_currency() );
482
            $total          .= '<small class="form-text text-muted">' . sprintf( __( 'Recurring Price: %s', 'invoicing' ), $recurring_total ) . '</small>';
483
        }
484
485
        $totals = array(
486
            'subtotal' => wpinv_price( $invoice->get_subtotal(), $invoice->get_currency() ),
487
            'discount' => wpinv_price( $invoice->get_total_discount(), $invoice->get_currency() ),
488
            'tax'      => wpinv_price( $invoice->get_total_tax(), $invoice->get_currency() ),
489
            'total'    => $total,
490
        );
491
492
        $totals = apply_filters( 'getpaid_invoice_totals', $totals, $invoice );
493
494
        wp_send_json_success( compact( 'totals' ) );
495
    }
496
497
    /**
498
     * Get items belonging to a given invoice.
499
     */
500
    public static function get_invoice_items() {
501
502
        // Verify nonce.
503
        check_ajax_referer( 'wpinv-nonce' );
504
505
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
506
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
507
        }
508
509
        // We need an invoice and items.
510
        if ( empty( $_POST['post_id'] ) ) {
511
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
512
        }
513
514
        // Fetch the invoice.
515
        $invoice = new WPInv_Invoice( wpinv_clean( $_POST['post_id'] ) );
516
517
        // Ensure it exists.
518
        if ( ! $invoice->get_id() ) {
519
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
520
        }
521
522
        // Return an array of invoice items.
523
        $items = array();
524
525
        foreach ( $invoice->get_items() as $item ) {
526
            $items[] = $item->prepare_data_for_invoice_edit_ajax(  $invoice->get_currency(), $invoice->is_renewal()  );
527
        }
528
529
        wp_send_json_success( compact( 'items' ) );
530
    }
531
532
    /**
533
     * Edits an invoice item.
534
     */
535
    public static function edit_invoice_item() {
536
537
        // Verify nonce.
538
        check_ajax_referer( 'wpinv-nonce' );
539
540
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
541
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
542
        }
543
544
        // We need an invoice and item details.
545
        if ( empty( $_POST['post_id'] ) || empty( $_POST['data'] ) ) {
546
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
547
        }
548
549
        // Fetch the invoice.
550
        $invoice = new WPInv_Invoice( wpinv_clean( $_POST['post_id'] ) );
551
552
        // Ensure it exists and its not been paid for.
553
        if ( ! $invoice->get_id() || $invoice->is_paid() || $invoice->is_refunded() ) {
554
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
555
        }
556
557
        // Format the data.
558
        $data = wp_kses_post_deep( wp_unslash( wp_list_pluck( $_POST['data'], 'value', 'field' ) ) );
559
560
        // Ensure that we have an item id.
561
        if ( empty( $data['id'] ) ) {
562
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
563
        }
564
565
        // Abort if the invoice does not have the specified item.
566
        $item = $invoice->get_item( (int) $data['id'] );
567
568
        if ( empty( $item ) ) {
569
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
570
        }
571
572
        // Update the item.
573
        $item->set_price( getpaid_standardize_amount( $data['price'] ) );
574
        $item->set_name( sanitize_text_field( $data['name'] ) );
575
        $item->set_description( wp_kses_post( $data['description'] ) );
576
        $item->set_quantity( floatval( $data['quantity'] ) );
577
578
        // Add it to the invoice.
579
        $error = $invoice->add_item( $item );
580
        $alert = false;
581
        if ( is_wp_error( $error ) ) {
582
            $alert = $error->get_error_message();
583
        }
584
585
        // Update totals.
586
        $invoice->recalculate_total();
587
588
        // Save the invoice.
589
        $invoice->save();
590
591
        // Return an array of invoice items.
592
        $items = array();
593
594
        foreach ( $invoice->get_items() as $item ) {
595
            $items[] = $item->prepare_data_for_invoice_edit_ajax(  $invoice->get_currency()  );
596
        }
597
598
        wp_send_json_success( compact( 'items', 'alert' ) );
599
    }
600
601
    /**
602
     * Creates an invoice item.
603
     */
604
    public static function create_invoice_item() {
605
606
        // Verify nonce.
607
        check_ajax_referer( 'wpinv-nonce' );
608
609
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
610
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
611
        }
612
613
        // We need an invoice and item details.
614
        if ( empty( $_POST['invoice_id'] ) || empty( $_POST['_wpinv_quick'] ) ) {
615
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
616
        }
617
618
        // Fetch the invoice.
619
        $invoice = new WPInv_Invoice( wpinv_clean( $_POST['invoice_id'] ) );
620
621
        // Ensure it exists and its not been paid for.
622
        if ( ! $invoice->get_id() || $invoice->is_paid() || $invoice->is_refunded() ) {
623
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
624
        }
625
626
        // Format the data.
627
        $data = wp_unslash( $_POST['_wpinv_quick'] );
628
629
        $item = new WPInv_Item();
630
        $item->set_price( getpaid_standardize_amount( $data['price'] ) );
631
        $item->set_name( sanitize_text_field( $data['name'] ) );
632
        $item->set_description( wp_kses_post( $data['description'] ) );
633
        $item->set_type( sanitize_text_field( $data['type'] ) );
634
        $item->set_vat_rule( sanitize_text_field( $data['vat_rule'] ) );
635
        $item->set_vat_class( sanitize_text_field( $data['vat_class'] ) );
636
        $item->set_status( 'publish' );
637
        $item->save();
638
639
        if ( ! $item->exists() ) {
640
            $alert = __( 'Could not create invoice item. Please try again.', 'invoicing' );
641
            wp_send_json_success( compact( 'alert' ) );
642
        }
643
644
        $item = new GetPaid_Form_Item( $item->get_id() );
645
        $item->set_quantity( floatval( $data['qty'] ) );
646
647
        // Add it to the invoice.
648
        $error = $invoice->add_item( $item );
649
        $alert = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $alert is dead and can be removed.
Loading history...
650
651
        if ( is_wp_error( $error ) ) {
652
            $alert = $error->get_error_message();
653
            wp_send_json_success( compact( 'alert' ) );
654
         }
655
656
        // Update totals.
657
        $invoice->recalculate_total();
658
659
        // Save the invoice.
660
        $invoice->save();
661
662
        // Save the invoice.
663
        $invoice->recalculate_total();
664
        $invoice->save();
665
        ob_start();
666
        GetPaid_Meta_Box_Invoice_Items::output_row( GetPaid_Meta_Box_Invoice_Items::get_columns( $invoice ), $item, $invoice );
667
        $row = ob_get_clean();
668
        wp_send_json_success( compact( 'row' ) );
669
    }
670
671
    /**
672
     * Deletes an invoice item.
673
     */
674
    public static function remove_invoice_item() {
675
676
        // Verify nonce.
677
        check_ajax_referer( 'wpinv-nonce' );
678
679
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
680
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
681
        }
682
683
        // We need an invoice and an item.
684
        if ( empty( $_POST['post_id'] ) || empty( $_POST['item_id'] ) ) {
685
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
686
        }
687
688
        // Fetch the invoice.
689
        $invoice = new WPInv_Invoice( wpinv_clean( $_POST['post_id'] ) );
690
691
        // Ensure it exists and its not been paid for.
692
        if ( ! $invoice->get_id() || $invoice->is_paid() || $invoice->is_refunded() ) {
693
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
694
        }
695
696
        // Abort if the invoice does not have the specified item.
697
        $item = $invoice->get_item( (int) $_POST['item_id'] );
698
699
        if ( empty( $item ) ) {
700
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
701
        }
702
703
        $invoice->remove_item( (int) $_POST['item_id'] );
704
705
        // Update totals.
706
        $invoice->recalculate_total();
707
708
        // Save the invoice.
709
        $invoice->save();
710
711
        // Return an array of invoice items.
712
        $items = array();
713
714
        foreach ( $invoice->get_items() as $item ) {
715
            $items[] = $item->prepare_data_for_invoice_edit_ajax(  $invoice->get_currency()  );
716
        }
717
718
        wp_send_json_success( compact( 'items' ) );
719
    }
720
721
    /**
722
     * Adds an item to an invoice.
723
     */
724
    public static function recalculate_full_prices() {
725
726
        // Verify nonce.
727
        check_ajax_referer( 'wpinv-nonce' );
728
729
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
730
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
731
        }
732
733
        // We need an invoice and item.
734
        if ( empty( $_POST['post_id'] ) ) {
735
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
736
        }
737
738
        // Fetch the invoice.
739
        $invoice = new WPInv_Invoice( wpinv_clean( $_POST['post_id'] ) );
740
        $alert   = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $alert is dead and can be removed.
Loading history...
741
742
        // Ensure it exists and its not been paid for.
743
        if ( ! $invoice->get_id() || $invoice->is_paid() || $invoice->is_refunded() ) {
744
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
745
        }
746
747
        $invoice->set_items( array() );
748
749
        if ( ! empty( $_POST['getpaid_items'] ) ) {
750
751
            foreach ( $_POST['getpaid_items'] as $item_id => $args ) {
752
                $item = new GetPaid_Form_Item( $item_id );
753
754
                if ( $item->exists() ) {
755
                    $item->set_price( getpaid_standardize_amount( $args['price'] ) );
756
                    $item->set_quantity( floatval( $args['quantity'] ) );
757
                    $item->set_name( sanitize_text_field( $args['name'] ) );
758
                    $item->set_description( wp_kses_post( $args['description'] ) );
759
                    $invoice->add_item( $item );
760
                }
761
            }
762
763
        }
764
765
        $invoice->set_disable_taxes( ! empty( $_POST['disable_taxes'] ) );
766
767
        // Maybe set the country, state, currency.
768
        foreach ( array( 'wpinv_country', 'wpinv_state', 'wpinv_currency', 'wpinv_vat_number', 'wpinv_discount_code' ) as $key ) {
769
            if ( isset( $_POST[ $key ] ) ) {
770
                $_key   = str_replace( 'wpinv_', '', $key );
771
                $method = "set_$_key";
772
                $invoice->$method( sanitize_text_field( $_POST[ $key ] ) );
773
            }
774
        }
775
776
        $discount = new WPInv_Discount( $invoice->get_discount_code() );
777
        if ( $discount->exists() ) {
778
            $invoice->add_discount( getpaid_calculate_invoice_discount( $invoice, $discount ) );
779
        } else {
780
            $invoice->remove_discount( 'discount_code' );
781
        }
782
783
        // Save the invoice.
784
        $invoice->recalculate_total();
785
        $invoice->save();
786
        ob_start();
787
        GetPaid_Meta_Box_Invoice_Items::output( get_post( $invoice->get_id() ), $invoice );
788
        $table = ob_get_clean();
789
        wp_send_json_success( compact( 'table' ) );
790
    }
791
792
    /**
793
     * Adds an item to an invoice.
794
     */
795
    public static function admin_add_invoice_item() {
796
797
        // Verify nonce.
798
        check_ajax_referer( 'wpinv-nonce' );
799
800
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
801
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
802
        }
803
804
        // We need an invoice and item.
805
        if ( empty( $_POST['post_id'] ) || empty( $_POST['item_id'] ) ) {
806
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
807
        }
808
809
        // Fetch the invoice.
810
        $invoice = new WPInv_Invoice( wpinv_clean( $_POST['post_id'] ) );
811
        $alert   = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $alert is dead and can be removed.
Loading history...
812
813
        // Ensure it exists and its not been paid for.
814
        if ( ! $invoice->get_id() || $invoice->is_paid() || $invoice->is_refunded() ) {
815
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
816
        }
817
818
        // Add the item.
819
        $item  = new GetPaid_Form_Item( (int) $_POST['item_id'] );
820
        $error = $invoice->add_item( $item );
821
822
        if ( is_wp_error( $error ) ) {
823
            $alert = $error->get_error_message();
824
            wp_send_json_success( compact( 'alert' ) );
825
        }
826
827
        // Save the invoice.
828
        $invoice->recalculate_total();
829
        $invoice->save();
830
        ob_start();
831
        GetPaid_Meta_Box_Invoice_Items::output_row( GetPaid_Meta_Box_Invoice_Items::get_columns( $invoice ), $item, $invoice );
832
        $row = ob_get_clean();
833
        wp_send_json_success( compact( 'row' ) );
834
    }
835
836
    /**
837
     * Adds a items to an invoice.
838
     */
839
    public static function add_invoice_items() {
840
841
        // Verify nonce.
842
        check_ajax_referer( 'wpinv-nonce' );
843
844
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
845
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
846
        }
847
848
        // We need an invoice and items.
849
        if ( empty( $_POST['post_id'] ) || empty( $_POST['items'] ) ) {
850
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
851
        }
852
853
        // Fetch the invoice.
854
        $invoice = new WPInv_Invoice( wpinv_clean( $_POST['post_id'] ) );
855
        $alert   = false;
856
857
        // Ensure it exists and its not been paid for.
858
        if ( ! $invoice->get_id() || $invoice->is_paid() || $invoice->is_refunded() ) {
859
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
860
        }
861
862
        // Add the items.
863
        foreach ( $_POST['items'] as $data ) {
864
865
            $item = new GetPaid_Form_Item( (int) $data[ 'id' ] );
866
867
            if ( is_numeric( $data[ 'qty' ] ) && (float) $data[ 'qty' ] > 0 ) {
868
                $item->set_quantity( floatval( $data[ 'qty' ] ) );
869
            }
870
871
            if ( $item->get_id() > 0 ) {
872
                $error = $invoice->add_item( $item );
873
874
                if ( is_wp_error( $error ) ) {
875
                    $alert = $error->get_error_message();
876
                }
877
878
            }
879
880
        }
881
882
        // Save the invoice.
883
        $invoice->recalculate_total();
884
        $invoice->save();
885
886
        // Return an array of invoice items.
887
        $items = array();
888
889
        foreach ( $invoice->get_items() as $item ) {
890
            $items[] = $item->prepare_data_for_invoice_edit_ajax( $invoice->get_currency() );
891
        }
892
893
        wp_send_json_success( compact( 'items', 'alert' ) );
894
    }
895
896
    /**
897
     * Retrieves items that should be added to an invoice.
898
     */
899
    public static function get_invoicing_items() {
900
901
        // Verify nonce.
902
        check_ajax_referer( 'wpinv-nonce' );
903
904
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
905
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
906
        }
907
908
        // We need a search term.
909
        if ( empty( $_GET['search'] ) ) {
910
            wp_send_json_success( array() );
911
        }
912
913
        // Retrieve items.
914
        $item_args = array(
915
            'post_type'      => 'wpi_item',
916
            'orderby'        => 'title',
917
            'order'          => 'ASC',
918
            'posts_per_page' => -1,
919
            'post_status'    => array( 'publish' ),
920
            's'              => trim( $_GET['search'] ),
921
            'meta_query'     => array(
922
                array(
923
                    'key'       => '_wpinv_type',
924
                    'compare'   => '!=',
925
                    'value'     => 'package'
926
                )
927
            )
928
        );
929
930
        $items = get_posts( apply_filters( 'getpaid_ajax_invoice_items_query_args', $item_args ) );
931
        $data  = array();
932
933
        $is_payment_form = ( ! empty( $_GET['post_id'] ) && 'wpi_payment_form' == get_post_type( $_GET['post_id'] ) );
934
935
        foreach ( $items as $item ) {
936
            $item      = new GetPaid_Form_Item( $item );
937
            $data[] = array(
938
                'id'        => (int) $item->get_id(),
939
                'text'      => strip_tags( $item->get_name() ),
940
                'form_data' => $is_payment_form ? $item->prepare_data_for_use( false ) : '',
941
            );
942
        }
943
944
        wp_send_json_success( $data );
945
946
    }
947
948
    /**
949
     * Retrieves items that should be added to an invoice.
950
     */
951
    public static function get_customers() {
952
953
        // Verify nonce.
954
        check_ajax_referer( 'wpinv-nonce' );
955
956
        if ( ! wpinv_current_user_can_manage_invoicing() ) {
957
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
958
        }
959
960
        // We need a search term.
961
        if ( empty( $_GET['search'] ) ) {
962
            wp_send_json_success( array() );
963
        }
964
965
        // Retrieve customers.
966
    
967
        $customer_args = array(
968
            'fields'         => array( 'ID', 'user_email', 'display_name' ),
969
            'orderby'        => 'display_name',
970
            'search'         => '*' . sanitize_text_field( $_GET['search'] ) . '*',
971
            'search_columns' => array( 'user_login', 'user_email', 'display_name' ),
972
        );
973
974
        $customers = get_users( apply_filters( 'getpaid_ajax_invoice_customers_query_args', $customer_args ) );
975
        $data      = array();
976
977
        foreach ( $customers as $customer ) {
978
            $data[] = array(
979
                'id'        => (int) $customer->ID,
980
                'text'      => strip_tags( sprintf( _x( '%1$s (%2$s)', 'user dropdown', 'invoicing' ), $customer->display_name, $customer->user_email ) ),
981
            );
982
        }
983
984
        wp_send_json_success( $data );
985
986
    }
987
988
    /**
989
     * Retrieves the states field for AUI forms.
990
     */
991
    public static function get_aui_states_field() {
992
993
        // Verify nonce.
994
        check_ajax_referer( 'wpinv-nonce' );
995
996
        // We need a country.
997
        if ( empty( $_GET['country'] ) ) {
998
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
999
        }
1000
1001
        $states = wpinv_get_country_states( sanitize_text_field( $_GET['country'] ) );
1002
        $state  = isset( $_GET['state'] ) ? sanitize_text_field( $_GET['state'] ) : wpinv_get_default_state();
1003
        $name   = isset( $_GET['name'] ) ? sanitize_text_field( $_GET['name'] ) : 'wpinv_state';
1004
        $class  = isset( $_GET['class'] ) ? sanitize_text_field( $_GET['class'] ) : 'form-control-sm';
1005
1006
        if ( empty( $states ) ) {
1007
1008
            $html = aui()->input(
1009
                array(
1010
                    'type'        => 'text',
1011
                    'id'          => 'wpinv_state',
1012
                    'name'        => $name,
1013
                    'label'       => __( 'State', 'invoicing' ),
1014
                    'label_type'  => 'vertical',
1015
                    'placeholder' => __( 'State', 'invoicing' ),
1016
                    'class'       => $class,
1017
                    'value'       => $state,
1018
                )
1019
            );
1020
1021
        } else {
1022
1023
            $html = aui()->select(
1024
                array(
1025
                    'id'          => 'wpinv_state',
1026
                    'name'        => $name,
1027
                    'label'       => __( 'State', 'invoicing' ),
1028
                    'label_type'  => 'vertical',
1029
                    'placeholder' => __( 'Select a state', 'invoicing' ),
1030
                    'class'       => $class,
1031
                    'value'       => $state,
1032
                    'options'     => $states,
1033
                    'data-allow-clear' => 'false',
1034
                    'select2'          => true,
1035
                )
1036
            );
1037
1038
        }
1039
1040
        wp_send_json_success(
1041
            array(
1042
                'html'   => $html,
1043
                'select' => ! empty ( $states )
1044
            )
1045
        );
1046
1047
    }
1048
1049
    /**
1050
     * Refresh prices.
1051
     *
1052
     * @since 1.0.19
1053
     */
1054
    public static function payment_form_refresh_prices() {
1055
1056
        // Check nonce.
1057
        check_ajax_referer( 'getpaid_form_nonce' );
1058
1059
        // ... form fields...
1060
        if ( empty( $_POST['getpaid_payment_form_submission'] ) ) {
1061
            _e( 'Error: Reload the page and try again.', 'invoicing' );
1062
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1063
        }
1064
1065
        // Load the submission.
1066
        $submission = new GetPaid_Payment_Form_Submission();
1067
1068
        // Do we have an error?
1069
        if ( ! empty( $submission->last_error ) ) {
1070
            wp_send_json_error(
1071
                array(
1072
                    'code'  => $submission->last_error_code,
1073
                    'error' => $submission->last_error
1074
                )
1075
            );
1076
        }
1077
1078
        // Prepare the response.
1079
        $response = new GetPaid_Payment_Form_Submission_Refresh_Prices( $submission );
1080
1081
        // Filter the response.
1082
        $response = apply_filters( 'getpaid_payment_form_ajax_refresh_prices', $response->response, $submission );
1083
1084
        wp_send_json_success( $response );
1085
    }
1086
1087
    /**
1088
	 * Handles file uploads.
1089
	 *
1090
	 * @since       1.0.0
1091
	 * @return      void
1092
	 */
1093
	public static function file_upload() {
1094
1095
        // Check nonce.
1096
        check_ajax_referer( 'getpaid_form_nonce' );
1097
1098
        if ( empty( $_POST['form_id'] ) || empty( $_POST['field_name'] ) || empty( $_FILES['file'] ) ) {
1099
            wp_die( __( 'Bad Request', 'invoicing' ), 400 );
1100
        }
1101
1102
        // Fetch form.
1103
        $form = new GetPaid_Payment_Form( intval( $_POST['form_id'] ) );
1104
1105
        if ( ! $form->is_active() ) {
1106
            wp_send_json_error( __( 'Payment form not active', 'invoicing' ) );
1107
        }
1108
1109
        // Fetch appropriate field.
1110
        $upload_field = current( wp_list_filter( $form->get_elements(), array( 'id' => sanitize_text_field( $_POST['field_name'] ) ) ) );
1111
        if ( empty( $upload_field ) ) {
1112
            wp_send_json_error( __( 'Invalid upload field.', 'invoicing' ) );
1113
        }
1114
1115
        // Prepare allowed file types.
1116
        $file_types = isset( $upload_field['file_types'] ) ? $upload_field['file_types'] : array( 'jpg|jpeg|jpe', 'gif', 'png' );
1117
        $all_types  = getpaid_get_allowed_mime_types();
1118
        $mime_types = array();
1119
1120
        foreach ( $file_types as $file_type ) {
1121
            if ( isset( $all_types[ $file_type ] ) ) {
1122
                $mime_types[] = $all_types[ $file_type ];
1123
            }
1124
        }
1125
1126
        if ( ! in_array( $_FILES['file']['type'], $mime_types ) ) {
1127
            wp_send_json_error( __( 'Unsupported file type.', 'invoicing' ) );
1128
        }
1129
1130
        // Upload file.
1131
        $file_name = explode( '.', strtolower( $_FILES['file']['name'] ) );
1132
        $file_name = uniqid( 'getpaid-' ) . '.' . array_pop( $file_name );
1133
1134
        $uploaded = wp_upload_bits(
1135
            $file_name,
1136
            null,
1137
            file_get_contents( $_FILES["file"]["tmp_name"] )
1138
        );
1139
1140
        if ( ! empty( $uploaded['error'] ) ) {
1141
            wp_send_json_error( $uploaded['error'] );
1142
        }
1143
1144
        // Retrieve response.
1145
        $response = sprintf(
1146
            '<input type="hidden" name="%s[%s]" value="%s" />',
1147
            esc_attr( $_POST['field_name'] ),
1148
            esc_attr( $uploaded['url'] ),
1149
            esc_attr( strtolower( $_FILES['file']['name'] ) )
1150
        );
1151
1152
        wp_send_json_success( $response );
1153
1154
	}
1155
1156
}
1157
1158
WPInv_Ajax::init();