Completed
Push — master ( 3ad42c...16627f )
by Brian
25s queued 14s
created

wpinv_gateway_settings_authorizenet()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 74
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 56
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 74
rs 8.9599

How to fix   Long Method   

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 gateway functions.
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * Returns an array of payment gateways.
11
 */
12
function wpinv_get_payment_gateways() {
13
    // Default, built-in gateways
14
    $gateways = array(
15
        'authorizenet' => array(
16
            'admin_label'    => __( 'Authorize.Net (AIM)', 'invoicing' ),
17
            'checkout_label' => __( 'Authorize.Net - Credit Card / Debit Card', 'invoicing' ),
18
            'ordering'       => 4,
19
        ),
20
    );
21
22
    $gateways = apply_filters( 'wpinv_payment_gateways', $gateways );
23
    return is_array( $gateways ) ? $gateways : array();
24
}
25
26
function wpinv_payment_gateway_titles( $all_gateways ) {
27
    global $wpinv_options;
28
29
    $gateways = array();
30
    foreach ( $all_gateways as $key => $gateway ) {
31
        if ( !empty( $wpinv_options[$key . '_title'] ) ) {
32
            $all_gateways[$key]['checkout_label'] = __( $wpinv_options[$key . '_title'], 'invoicing' );
33
        }
34
35
        $gateways[$key] = isset( $wpinv_options[$key . '_ordering'] ) ? $wpinv_options[$key . '_ordering'] : ( isset( $gateway['ordering'] ) ? $gateway['ordering'] : '' );
36
    }
37
38
    asort( $gateways );
39
40
    foreach ( $gateways as $gateway => $key ) {
41
        $gateways[$gateway] = $all_gateways[$gateway];
42
    }
43
44
    return $gateways;
45
}
46
add_filter( 'wpinv_payment_gateways', 'wpinv_payment_gateway_titles', 1000, 1 );
47
48
function wpinv_get_enabled_payment_gateways( $sort = false ) {
49
    $gateways = wpinv_get_payment_gateways();
50
    $enabled  = wpinv_get_option( 'gateways', false );
51
52
    $gateway_list = array();
53
54
    foreach ( $gateways as $key => $gateway ) {
55
        if ( isset( $enabled[ $key ] ) && $enabled[ $key ] == 1 ) {
56
            $gateway_list[ $key ] = $gateway;
57
        }
58
    }
59
60
    if ( true === $sort ) {
61
        uasort( $gateway_list, 'wpinv_sort_gateway_order' );
62
        
63
        // Reorder our gateways so the default is first
64
        $default_gateway_id = wpinv_get_default_gateway();
65
66
        if ( wpinv_is_gateway_active( $default_gateway_id ) ) {
67
            $default_gateway    = array( $default_gateway_id => $gateway_list[ $default_gateway_id ] );
68
            unset( $gateway_list[ $default_gateway_id ] );
69
70
            $gateway_list = array_merge( $default_gateway, $gateway_list );
71
        }
72
    }
73
74
    return apply_filters( 'wpinv_enabled_payment_gateways', $gateway_list );
75
}
76
77
function wpinv_sort_gateway_order( $a, $b ) {
78
    return $a['ordering'] - $b['ordering'];
79
}
80
81
function wpinv_is_gateway_active( $gateway ) {
82
    $gateways = wpinv_get_enabled_payment_gateways();
83
84
    $ret = is_array($gateways) && $gateway ?  array_key_exists( $gateway, $gateways ) : false;
85
86
    return apply_filters( 'wpinv_is_gateway_active', $ret, $gateway, $gateways );
87
}
88
89
function wpinv_get_default_gateway() {
90
    $default = wpinv_get_option( 'default_gateway', 'paypal' );
91
92
    if ( !wpinv_is_gateway_active( $default ) ) {
93
        $gateways = wpinv_get_enabled_payment_gateways();
94
        $gateways = array_keys( $gateways );
95
        $default  = reset( $gateways );
96
    }
97
98
    return apply_filters( 'wpinv_default_gateway', $default );
99
}
100
101
function wpinv_get_gateway_admin_label( $gateway ) {
102
    $gateways = wpinv_get_payment_gateways();
103
    $label    = isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ]['admin_label'] : $gateway;
104
    $payment  = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : false;
105
106
    if( $gateway == 'manual' && $payment ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payment of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
107
        if( !( (float)wpinv_payment_total( $payment ) > 0 ) ) {
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_payment_total() 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

107
        if( !( (float)/** @scrutinizer ignore-deprecated */ wpinv_payment_total( $payment ) > 0 ) ) {
Loading history...
108
            $label = __( 'Free Purchase', 'invoicing' );
109
        }
110
    }
111
112
    return apply_filters( 'wpinv_gateway_admin_label', $label, $gateway );
113
}
114
115
function wpinv_get_gateway_description( $gateway ) {
116
    global $wpinv_options;
117
118
    $description = ! empty( $wpinv_options[$gateway . '_desc'] ) ? $wpinv_options[$gateway . '_desc'] : '';
119
120
    return apply_filters( 'wpinv_gateway_description', $description, $gateway );
121
}
122
123
function wpinv_get_gateway_button_label( $gateway ) {
124
    return apply_filters( 'wpinv_gateway_' . $gateway . '_button_label', '' );
125
}
126
127
function wpinv_get_gateway_checkout_label( $gateway ) {
128
    $gateways = wpinv_get_payment_gateways();
129
    $label    = isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ]['checkout_label'] : $gateway;
130
131
    if( $gateway == 'manual' ) {
132
        $label = __( 'Manual Payment', 'invoicing' );
133
    }
134
135
    return apply_filters( 'wpinv_gateway_checkout_label', ucfirst( $label ), $gateway );
136
}
137
138
function wpinv_settings_sections_gateways( $settings ) {
139
    $gateways = wpinv_get_payment_gateways();
140
    
141
    if (!empty($gateways)) {
142
        foreach  ($gateways as $key => $gateway) {
143
            $settings[$key] = $gateway['admin_label'];
144
        }
145
    }
146
    
147
    return $settings;    
148
}
149
add_filter( 'wpinv_settings_sections_gateways', 'wpinv_settings_sections_gateways', 10, 1 );
150
151
/**
152
 * Adds GateWay settings.
153
 */
154
function wpinv_settings_gateways( $settings ) {
155
156
    // Loop through each gateway.
157
    foreach  ( wpinv_get_payment_gateways() as $key => $gateway ) {
158
159
        $gateway_settings = array(
160
161
            // Header.
162
            "{$key}_header" => array(
163
164
                'id'     => "{$key}_gateway_header",
165
                'name'   => '<h3>' . wp_sprintf( __( '%s Settings', 'invoicing' ), $gateway['admin_label'] ) . '</h3>',
166
                'custom' => $key,
167
                'type'   => 'gateway_header',
168
169
            ),
170
171
            // Activate/Deactivate a gateway.
172
            "{$key}_active" => array(
173
                'id'   => $key . '_active',
174
                'name' => __( 'Activate', 'invoicing' ),
175
                'desc' => wp_sprintf( __( 'Enable %s', 'invoicing' ), $gateway['admin_label'] ),
176
                'type' => 'checkbox',
177
            ),
178
179
            // Activate/Deactivate sandbox.
180
            "{$key}_sandbox" => array(
181
                'id'   => $key . '_sandbox',
182
                'name' => __( 'Sandbox', 'invoicing' ),
183
                'desc' => __( 'Enable sandbox to test payments', 'invoicing' ),
184
                'type' => 'checkbox',
185
            ),
186
187
            // Checkout title.
188
            "{$key}_title" => array(
189
                'id'   => $key . '_title',
190
                'name' => __( 'Checkout Title', 'invoicing' ),
191
                'std'  => isset( $gateway['checkout_label'] ) ? $gateway['checkout_label'] : '',
192
                'type' => 'text',
193
            ),
194
195
            // Checkout description.
196
            "{$key}_desc" => array(
197
                'id'   => $key . '_desc',
198
                'name' => __( 'Checkout Description', 'invoicing' ),
199
                'std'  => apply_filters( "getpaid_default_{$key}_checkout_description", '' ),
200
                'type' => 'text',
201
            ),
202
203
            // Checkout order.
204
            "{$key}_ordering" => array(
205
                'id'   => $key . '_ordering',
206
                'name' => __( 'Priority', 'invoicing' ),
207
                'std'  => apply_filters( "getpaid_default_{$key}_checkout_description", '' ),
208
                'type' => 'number',
209
                'step' => '1',
210
                'min'  => '-100000',
211
                'max'  => '100000',
212
                'std'  => isset( $gateway['ordering'] ) ? $gateway['ordering'] : '10',
213
            ),
214
215
        );
216
217
        // Maybe remove the sandbox.
218
        if ( ! apply_filters( "wpinv_{$key}_supports_sandbox", false ) ) {
219
            unset( $gateway_settings["{$key}_sandbox"] );
220
        }
221
  
222
        $gateway_settings = apply_filters( 'wpinv_gateway_settings', $gateway_settings, $key, $gateway );
223
        $gateway_settings = apply_filters( 'wpinv_gateway_settings_' . $key, $gateway_settings, $gateway );
224
        
225
        $settings[$key] = $gateway_settings;
226
    }
227
228
    return $settings;
229
230
}
231
add_filter( 'wpinv_settings_gateways', 'wpinv_settings_gateways', 10, 1 );
232
233
function wpinv_gateway_header_callback( $args ) {
234
    echo '<input type="hidden" id="wpinv_settings[save_gateway]" name="wpinv_settings[save_gateway]" value="' . esc_attr( $args['custom'] ) . '" />';
235
}
236
237
function wpinv_get_gateway_supports( $gateway ) {
238
    $gateways = wpinv_get_enabled_payment_gateways();
239
    $supports = isset( $gateways[ $gateway ]['supports'] ) ? $gateways[ $gateway ]['supports'] : array();
240
    return apply_filters( 'wpinv_gateway_supports', $supports, $gateway );
241
}
242
243
function wpinv_gateway_supports_buy_now( $gateway ) {
244
    $supports = wpinv_get_gateway_supports( $gateway );
245
    $ret = in_array( 'buy_now', $supports );
246
    return apply_filters( 'wpinv_gateway_supports_buy_now', $ret, $gateway );
247
}
248
249
function wpinv_shop_supports_buy_now() {
250
    $gateways = wpinv_get_enabled_payment_gateways();
251
    $ret      = false;
252
253
    if ( !wpinv_use_taxes()  && $gateways ) {
254
        foreach ( $gateways as $gateway_id => $gateway ) {
255
            if ( wpinv_gateway_supports_buy_now( $gateway_id ) ) {
256
                $ret = true;
257
                break;
258
            }
259
        }
260
    }
261
262
    return apply_filters( 'wpinv_shop_supports_buy_now', $ret );
263
}
264
265
266
function wpinv_show_gateways() {
267
    $gateways = wpinv_get_enabled_payment_gateways();
268
    $show_gateways = false;
269
270
    $chosen_gateway = isset( $_GET['payment-mode'] ) ? preg_replace('/[^a-zA-Z0-9-_]+/', '', $_GET['payment-mode'] ) : false;
271
272
    if ( count( $gateways ) > 1 && empty( $chosen_gateway ) ) {
273
        $show_gateways = true;
274
        if ( wpinv_get_cart_total() <= 0 ) {
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_get_cart_total() 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

274
        if ( /** @scrutinizer ignore-deprecated */ wpinv_get_cart_total() <= 0 ) {
Loading history...
275
            $show_gateways = false;
276
        }
277
    }
278
    
279
    if ( !$show_gateways && wpinv_cart_has_recurring_item() ) {
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_cart_has_recurring_item() 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

279
    if ( !$show_gateways && /** @scrutinizer ignore-deprecated */ wpinv_cart_has_recurring_item() ) {
Loading history...
280
        $show_gateways = true;
281
    }
282
283
    return apply_filters( 'wpinv_show_gateways', $show_gateways );
284
}
285
286
function wpinv_get_chosen_gateway( $invoice_id = 0 ) {
287
	$gateways = array_keys( wpinv_get_enabled_payment_gateways() );
288
289
    $chosen = false;
290
    if ( $invoice_id > 0 && $invoice = wpinv_get_invoice( $invoice_id ) ) {
291
        $chosen = $invoice->get_gateway();
292
    }
293
294
	$chosen   = isset( $_REQUEST['payment-mode'] ) ? sanitize_text_field( $_REQUEST['payment-mode'] ) : $chosen;
295
296
	if ( false !== $chosen ) {
297
		$chosen = preg_replace('/[^a-zA-Z0-9-_]+/', '', $chosen );
298
	}
299
300
	if ( ! empty ( $chosen ) ) {
301
		$enabled_gateway = urldecode( $chosen );
302
	} else if (  !empty( $invoice ) && (float)$invoice->get_subtotal() <= 0 ) {
303
		$enabled_gateway = 'manual';
304
	} else {
305
		$enabled_gateway = wpinv_get_default_gateway();
306
	}
307
    
308
    if ( !wpinv_is_gateway_active( $enabled_gateway ) && !empty( $gateways ) ) {
309
        if(wpinv_is_gateway_active( wpinv_get_default_gateway()) ){
310
            $enabled_gateway = wpinv_get_default_gateway();
311
        }else{
312
            $enabled_gateway = $gateways[0];
313
        }
314
315
    }
316
317
	return apply_filters( 'wpinv_chosen_gateway', $enabled_gateway );
318
}
319
320
function wpinv_record_gateway_error( $title = '', $message = '', $parent = 0 ) {
321
    return wpinv_error_log( $message, $title );
0 ignored issues
show
Bug introduced by
Are you sure the usage of wpinv_error_log($message, $title) is correct as it 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...
322
}
323
324
function wpinv_count_sales_by_gateway( $gateway_id = 'paypal', $status = 'publish' ) {
325
	$ret  = 0;
326
	$args = array(
327
		'meta_key'    => '_wpinv_gateway',
328
		'meta_value'  => $gateway_id,
329
		'nopaging'    => true,
330
		'post_type'   => 'wpi_invoice',
331
		'post_status' => $status,
332
		'fields'      => 'ids'
333
	);
334
335
	$payments = new WP_Query( $args );
336
337
	if( $payments )
0 ignored issues
show
introduced by
$payments is of type WP_Query, thus it always evaluated to true.
Loading history...
338
		$ret = $payments->post_count;
339
	return $ret;
340
}
341
342
function wpinv_settings_update_gateways( $input ) {
343
    global $wpinv_options;
344
    
345
    if ( !empty( $input['save_gateway'] ) ) {
346
        $gateways = wpinv_get_option( 'gateways', false );
347
        $gateways = !empty($gateways) ? $gateways : array();
348
        $gateway = $input['save_gateway'];
349
        
350
        if ( !empty( $input[$gateway . '_active'] ) ) {
351
            $gateways[$gateway] = 1;
352
        } else {
353
            if ( isset( $gateways[$gateway] ) ) {
354
                unset( $gateways[$gateway] );
355
            }
356
        }
357
        
358
        $input['gateways'] = $gateways;
359
    }
360
    
361
    if ( !empty( $input['default_gateway'] ) ) {
362
        $gateways = wpinv_get_payment_gateways();
363
        
364
        foreach ( $gateways as $key => $gateway ) {
365
            $active   = 0;
366
            if ( !empty( $input['gateways'] ) && !empty( $input['gateways'][$key] ) ) {
367
                $active = 1;
368
            }
369
            
370
            $input[$key . '_active'] = $active;
371
            
372
            if ( empty( $wpinv_options[$key . '_title'] ) ) {
373
                $input[$key . '_title'] = $gateway['checkout_label'];
374
            }
375
            
376
            if ( !isset( $wpinv_options[$key . '_ordering'] ) && isset( $gateway['ordering'] ) ) {
377
                $input[$key . '_ordering'] = $gateway['ordering'];
378
            }
379
        }
380
    }
381
    
382
    return $input;
383
}
384
add_filter( 'wpinv_settings_tab_gateways_sanitize', 'wpinv_settings_update_gateways', 10, 1 );
385
386
// PayPal Standard settings
387
function wpinv_gateway_settings_paypal( $setting ) {    
388
    $setting['paypal_active']['desc'] = $setting['paypal_active']['desc'] . ' ' . __( '( Supported Currencies: AUD, BRL, CAD, CZK, DKK, EUR, HKD, HUF, ILS, JPY, MYR, MXN, NOK, NZD, PHP, PLN, GBP, SGD, SEK, CHF, TWD, THB, USD )', 'invoicing' );
389
    $setting['paypal_desc']['std'] = __( 'Pay via PayPal: you can pay with your credit card if you don\'t have a PayPal account.', 'invoicing' );
390
    
391
    $setting['paypal_sandbox'] = array(
392
            'type' => 'checkbox',
393
            'id'   => 'paypal_sandbox',
394
            'name' => __( 'PayPal Sandbox', 'invoicing' ),
395
            'desc' => __( 'PayPal sandbox can be used to test payments.', 'invoicing' ),
396
            'std'  => 1
397
        );
398
        
399
    $setting['paypal_email'] = array(
400
            'type' => 'text',
401
            'id'   => 'paypal_email',
402
            'name' => __( 'PayPal Email', 'invoicing' ),
403
            'desc' => __( 'Please enter your PayPal account\'s email address. Ex: [email protected]', 'invoicing' ),
404
            'std' => __( '[email protected]', 'invoicing' ),
405
        );
406
    /*
407
    $setting['paypal_ipn_url'] = array(
408
            'type' => 'text',
409
            'id'   => 'paypal_ipn_url',
410
            'name' => __( 'PayPal IPN Url', 'invoicing' ),
411
            'desc' => __( 'Configure Instant Payment Notifications(IPN) url at PayPal. Ex: http://yoursite.com/?wpi-ipn=paypal', 'invoicing' ),
412
            'size' => 'large'
413
        );
414
    */
415
        
416
    return $setting;
417
}
418
add_filter( 'wpinv_gateway_settings_paypal', 'wpinv_gateway_settings_paypal', 10, 1 );
419
420
// Authorize.Net settings
421
function wpinv_gateway_settings_authorizenet( $setting ) {
422
    $setting['authorizenet_active']['desc'] = $setting['authorizenet_active']['desc'] . ' ' . __( '( Supported Currencies: AUD, CAD, CHF, DKK, EUR, GBP, JPY, NOK, NZD, PLN, SEK, USD, ZAR )', 'invoicing' );
423
    $setting['authorizenet_desc']['std'] = __( 'Pay using a Authorize.Net to process Credit card / Debit card transactions.', 'invoicing' );
424
    
425
    $setting['authorizenet_sandbox'] = array(
426
            'type' => 'checkbox',
427
            'id'   => 'authorizenet_sandbox',
428
            'name' => __( 'Authorize.Net Test Mode', 'invoicing' ),
429
            'desc' => __( 'Enable Authorize.Net test mode to test payments.', 'invoicing' ),
430
            'std'  => 1
431
        );
432
        
433
    $setting['authorizenet_login_id'] = array(
434
            'type' => 'text',
435
            'id'   => 'authorizenet_login_id',
436
            'name' => __( 'API Login ID', 'invoicing' ),
437
            'desc' => __( 'API Login ID can be obtained from Authorize.Net Account > Settings > Security Settings > General Security Settings > API Credentials & Keys. Example : 2j4rBekUnD', 'invoicing' ),
438
            'std' => '2j4rBekUnD',
439
        );
440
    
441
    $setting['authorizenet_transaction_key'] = array(
442
            'type' => 'text',
443
            'id'   => 'authorizenet_transaction_key',
444
            'name' => __( 'Transaction Key', 'invoicing' ),
445
            'desc' => __( 'Transaction Key can be obtained from Authorize.Net Account > Settings > Security Settings > General Security Settings > API Credentials & Keys. Example : 4vyBUOJgR74679xa', 'invoicing' ),
446
            'std' => '4vyBUOJgR74679xa',
447
        );
448
        
449
    $setting['authorizenet_md5_hash'] = array(
450
            'type' => 'text',
451
            'id'   => 'authorizenet_md5_hash',
452
            'name' => __( 'MD5-Hash', 'invoicing' ),
453
            'desc' => __( 'The MD5 Hash security feature allows to authenticate transaction responses from the Authorize.Net for recurring payments. It can be obtained from Authorize.Net Account > Settings > Security Settings > General Settings > MD5 Hash.', 'invoicing' ),
454
            'std' => '',
455
        );
456
457
    $setting['authorizenet_transaction_type'] = array(
458
        'id'          => 'authorizenet_transaction_type',
459
        'name'        => __( 'Transaction Type', 'invoicing' ),
460
        'desc'        => __( 'Choose transaction type.', 'invoicing' ),
461
        'type'        => 'select',
462
        'class'       => 'wpi_select2',
463
        'options'     => array(
464
            'authorize_capture' => __( 'Authorize And Capture', 'invoicing' ),
465
            'authorize_only' => __( 'Authorize Only', 'invoicing' ),
466
        ),
467
        'std'         => 'authorize_capture'
468
    );
469
470
    $setting['authorizenet_transaction_type_recurring'] = array(
471
        'id'          => 'authorizenet_transaction_type_recurring',
472
        'name'        => __( 'Transaction Type for Recurring', 'invoicing' ),
473
        'desc'        => __( 'Choose transaction type for recurring payments.', 'invoicing' ),
474
        'type'        => 'select',
475
        'class'       => 'wpi_select2',
476
        'options'     => array(
477
            'authorize_capture' => __( 'Authorize And Capture', 'invoicing' ),
478
            'authorize_only' => __( 'Authorize Only', 'invoicing' ),
479
        ),
480
        'std'         => 'authorize_only'
481
    );
482
        
483
    $setting['authorizenet_ipn_url'] = array(
484
            'type' => 'ipn_url',
485
            'id'   => 'authorizenet_ipn_url',
486
            'name' => __( 'Silent Post URL', 'invoicing' ),
487
            'std' => wpinv_get_ipn_url( 'authorizenet' ),
488
            'desc' => __( 'If you are accepting recurring payments then you must set this url at Authorize.Net Account > Settings > Transaction Format Settings > Transaction Response Settings > Silent Post URL.', 'invoicing' ),
489
            'size' => 'large',
490
            'custom' => 'authorizenet',
491
            'readonly' => true
492
        );
493
        
494
    return $setting;
495
}
496
add_filter( 'wpinv_gateway_settings_authorizenet', 'wpinv_gateway_settings_authorizenet', 10, 1 );
497
498
/**
499
 * Displays the ipn url field.
500
 */
501
function wpinv_ipn_url_callback( $args ) {
502
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
503
    
504
    $attrs = $args['readonly'] ? ' readonly' : '';
505
506
    $html = '<input style="background-color:#fefefe" type="text" ' . $attrs . ' value="' . esc_attr( $args['std'] ) . '" name="wpinv_settings[' . $sanitize_id . ']" id="wpinv_settings[' . $sanitize_id . ']" onClick="this.select()">';
507
    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']">'  . $args['desc'] . '</label>';
508
509
    echo $html;
510
}
511
512
/**
513
 * Checks if a gateway is in test mode.
514
 * 
515
 * @param string $gateway The gateway to check for.
516
 * 
517
 * @return bool
518
 */
519
function wpinv_is_test_mode( $gateway = '' ) {
520
    $sandbox = empty( $gateway ) ? false : wpinv_get_option( "{$gateway}__sandbox", false );
521
    return apply_filters( 'wpinv_is_test_mode', $sandbox, $gateway );
522
}
523
524
/**
525
 * Retrieves the ipn url.
526
 * 
527
 * @param string $gateway The gateway whose IPN url we should retrieve.
528
 * @param array $args extra args to add to the url.
529
 * 
530
 * @return string
531
 */
532
function wpinv_get_ipn_url( $gateway = false, $args = array() ) {
533
    $args = wp_parse_args(
534
        array(
535
            'wpi-listener' => 'IPN',
536
            'wpi-gateway'  => $gateway
537
        ),
538
        $args
539
    );
540
541
    return apply_filters( 'wpinv_ipn_url', add_query_arg( $args,  home_url( 'index.php' ) ), $gateway, $args );
542
543
}
544
545
function wpinv_get_post_data( $method = 'request' ) {
546
    $data       = array();
547
    $request    = $_REQUEST;
548
    
549
    if ( $method == 'post' ) {
550
        if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] != 'POST' ) {
551
            return $data;
552
        }
553
        
554
        $request = $_POST;
555
    }
556
    
557
    if ( $method == 'get' ) {
558
        if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] != 'GET' ) {
559
            return $data;
560
        }
561
        
562
        $request = $_GET;
563
    }
564
    
565
    // Set initial post data to empty string
566
    $post_data = '';
567
    
568
    // Fallback just in case post_max_size is lower than needed
569
    if ( ini_get( 'allow_url_fopen' ) ) {
570
        $post_data = file_get_contents( 'php://input' );
571
    } else {
572
        // If allow_url_fopen is not enabled, then make sure that post_max_size is large enough
573
        ini_set( 'post_max_size', '12M' );
574
    }
575
    // Start the encoded data collection with notification command
576
    $encoded_data = 'cmd=_notify-validate';
577
578
    // Get current arg separator
579
    $arg_separator = wpinv_get_php_arg_separator_output();
580
581
    // Verify there is a post_data
582
    if ( $post_data || strlen( $post_data ) > 0 ) {
583
        // Append the data
584
        $encoded_data .= $arg_separator . $post_data;
585
    } else {
586
        // Check if POST is empty
587
        if ( empty( $request ) ) {
588
            // Nothing to do
589
            return;
590
        } else {
591
            // Loop through each POST
592
            foreach ( $request as $key => $value ) {
593
                // Encode the value and append the data
594
                $encoded_data .= $arg_separator . "$key=" . urlencode( $value );
595
            }
596
        }
597
    }
598
599
    // Convert collected post data to an array
600
    wp_parse_str( $encoded_data, $data );
0 ignored issues
show
Security Variable Injection introduced by
$encoded_data can contain request data and is used in variable name context(s) leading to a potential security vulnerability.

3 paths for user data to reach this point

  1. Path: Read from $_GET, and $_GET is assigned to $request in includes/wpinv-gateway-functions.php on line 562
  1. Read from $_GET, and $_GET is assigned to $request
    in includes/wpinv-gateway-functions.php on line 562
  2. $request is assigned to $value
    in includes/wpinv-gateway-functions.php on line 592
  3. Data is passed through urlencode(), and $arg_separator . $key.'=' . urlencode($value) is assigned to $encoded_data
    in includes/wpinv-gateway-functions.php on line 594
  2. Path: Read from $_REQUEST, and $_REQUEST is assigned to $request in includes/wpinv-gateway-functions.php on line 547
  1. Read from $_REQUEST, and $_REQUEST is assigned to $request
    in includes/wpinv-gateway-functions.php on line 547
  2. $request is assigned to $value
    in includes/wpinv-gateway-functions.php on line 592
  3. Data is passed through urlencode(), and $arg_separator . $key.'=' . urlencode($value) is assigned to $encoded_data
    in includes/wpinv-gateway-functions.php on line 594
  3. Path: Read from $_POST, and $_POST is assigned to $request in includes/wpinv-gateway-functions.php on line 554
  1. Read from $_POST, and $_POST is assigned to $request
    in includes/wpinv-gateway-functions.php on line 554
  2. $request is assigned to $value
    in includes/wpinv-gateway-functions.php on line 592
  3. Data is passed through urlencode(), and $arg_separator . $key.'=' . urlencode($value) is assigned to $encoded_data
    in includes/wpinv-gateway-functions.php on line 594

Used in variable context

  1. wp_parse_str() is called
    in includes/wpinv-gateway-functions.php on line 600
  2. Enters via parameter $string
    in wordpress/wp-includes/formatting.php on line 4938
  3. parse_str() is called
    in wordpress/wp-includes/formatting.php on line 4939

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
601
602
    foreach ( $data as $key => $value ) {
603
        if ( false !== strpos( $key, 'amp;' ) ) {
604
            $new_key = str_replace( '&amp;', '&', $key );
605
            $new_key = str_replace( 'amp;', '&' , $new_key );
606
607
            unset( $data[ $key ] );
608
            $data[ $new_key ] = sanitize_text_field( $value );
609
        }
610
    }
611
    
612
    return $data;
613
}
614
615
/**
616
 * Checks if a given gateway supports subscription payments.
617
 */
618
function wpinv_gateway_support_subscription( $gateway ) {
619
    $supports = false;
620
621
    if ( wpinv_is_gateway_active( $gateway ) ) {
622
        $supports = apply_filters( 'wpinv_' . $gateway . '_support_subscription', $supports );
623
        $supports = apply_filters( 'getapid_gateway_supports_subscription', $supports, $gateway );
624
    }
625
626
    return $supports;
627
}
628
629
/**
630
 * Filters payment form gateways.
631
 * 
632
 * @param array $gateways an array of gateways.
633
 * @param GetPaid_Payment_Form $form payment form.
634
 */
635
function wpinv_payment_gateways_on_cart( $gateways, $form ) {
636
637
    if ( $form->is_recurring() ) {
638
639
        foreach ( array_keys( $gateways ) as $gateway ) {
640
641
            if ( ! wpinv_gateway_support_subscription( $gateway ) ) {
642
                unset( $gateways[$gateway] );
643
            }
644
645
        }
646
647
    }
648
649
    return $gateways;
650
}
651
add_filter( 'getpaid_payment_form_gateways', 'wpinv_payment_gateways_on_cart', 10, 2 );
652
653
/**
654
 * Validates checkout fields.
655
 *
656
 * @param GetPaid_Payment_Form_Submission $submission
657
 */
658
function wpinv_checkout_validate_gateway( $submission ) {
659
660
    $data = $submission->get_data();
661
662
    // Non-recurring gateways should not be allowed to process recurring invoices.
663
    if ( $submission->has_recurring && ! wpinv_gateway_support_subscription( $data['wpi-gateway'] ) ) {
664
        wpinv_set_error( 'invalid_gateway', __( 'The selected payment gateway does not support subscription payment.', 'invoicing' ) );
665
    }
666
667
    if ( ! wpinv_is_gateway_active( $data['wpi-gateway'] ) ) {
668
        wpinv_set_error( 'invalid_gateway', __( 'The selected payment gateway is not active', 'invoicing' ) );
669
    }
670
671
}
672
673
/**
674
 * Validates a zip code.
675
 */
676
function wpinv_checkout_validate_cc_zip( $zip = 0, $country_code = '' ) {
677
678
    if ( empty( $zip ) || empty( $country_code ) ){
679
        return false;
680
    }
681
682
    // Prepare the country code.
683
    $country_code = strtoupper( trim( $country_code ) );
684
685
    // Fetch the regexes.
686
    $zip_regex = wpinv_get_data( 'zip-regexes' );
687
688
    // Check if it is valid.
689
    $is_valid = ! isset ( $zip_regex[ $country_code ] ) || preg_match( "/" . $zip_regex[ $country_code ] . "/i", $zip );
690
691
    return apply_filters( 'wpinv_is_zip_valid', $is_valid, $zip, $country_code );
692
}
693
694
function wpinv_checkout_validate_agree_to_terms() {
695
    // Validate agree to terms
696
    if ( ! isset( $_POST['wpi_agree_to_terms'] ) || $_POST['wpi_agree_to_terms'] != 1 ) {
697
        // User did not agree
698
        wpinv_set_error( 'agree_to_terms', apply_filters( 'wpinv_agree_to_terms_text', __( 'You must agree to the terms of use', 'invoicing' ) ) );
699
    }
700
}
701
702
function wpinv_checkout_validate_invoice_user() {
703
    global $wpi_cart, $user_ID;
704
705
    if(empty($wpi_cart)){
706
        $wpi_cart = wpinv_get_invoice_cart();
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_get_invoice_cart() 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

706
        $wpi_cart = /** @scrutinizer ignore-deprecated */ wpinv_get_invoice_cart();
Loading history...
707
    }
708
709
    $invoice_user = (int)$wpi_cart->get_user_id();
710
    $valid_user_data = array(
711
        'user_id' => $invoice_user
712
    );
713
714
    // If guest checkout allowed
715
    if ( !wpinv_require_login_to_checkout() ) {
716
        return $valid_user_data;
717
    }
718
    
719
    // Verify there is a user_ID
720
    if ( $user_ID == $invoice_user ) {
721
        // Get the logged in user data
722
        $user_data = get_userdata( $user_ID );
723
        $required_fields  = wpinv_checkout_required_fields();
724
725
        // Loop through required fields and show error messages
726
         if ( !empty( $required_fields ) ) {
727
            foreach ( $required_fields as $field_name => $value ) {
728
                if ( in_array( $value, $required_fields ) && empty( $_POST[ 'wpinv_' . $field_name ] ) ) {
729
                    wpinv_set_error( $value['error_id'], $value['error_message'] );
730
                }
731
            }
732
        }
733
734
        // Verify data
735
        if ( $user_data ) {
736
            // Collected logged in user data
737
            $valid_user_data = array(
738
                'user_id'     => $user_ID,
739
                'email'       => isset( $_POST['wpinv_email'] ) ? sanitize_email( $_POST['wpinv_email'] ) : $user_data->user_email,
740
                'first_name'  => isset( $_POST['wpinv_first_name'] ) && ! empty( $_POST['wpinv_first_name'] ) ? sanitize_text_field( $_POST['wpinv_first_name'] ) : $user_data->first_name,
741
                'last_name'   => isset( $_POST['wpinv_last_name'] ) && ! empty( $_POST['wpinv_last_name']  ) ? sanitize_text_field( $_POST['wpinv_last_name']  ) : $user_data->last_name,
742
            );
743
744
            if ( !empty( $_POST[ 'wpinv_email' ] ) && !is_email( $_POST[ 'wpinv_email' ] ) ) {
745
                wpinv_set_error( 'invalid_email', __( 'Please enter a valid email address', 'invoicing' ) );
746
            }
747
        } else {
748
            // Set invalid user error
749
            wpinv_set_error( 'invalid_user', __( 'The user billing information is invalid', 'invoicing' ) );
750
        }
751
    } else {
752
        // Set invalid user error
753
        wpinv_set_error( 'invalid_user_id', __( 'The invalid invoice user id', 'invoicing' ) );
754
    }
755
756
    // Return user data
757
    return $valid_user_data;
758
}
759
760
function wpinv_checkout_validate_current_user() {
761
    global $wpi_cart;
762
763
    $data = array();
764
    
765
    if ( is_user_logged_in() ) {
766
        if ( !wpinv_require_login_to_checkout() || ( wpinv_require_login_to_checkout() && (int)$wpi_cart->get_user_id() === (int)get_current_user_id() ) ) {
767
            $data['user_id'] = (int)get_current_user_id();
768
        } else {
769
            wpinv_set_error( 'logged_in_only', __( 'You are not allowed to pay for this invoice', 'invoicing' ) );
770
        }
771
    } else {
772
        // If guest checkout allowed
773
        if ( !wpinv_require_login_to_checkout() ) {
774
            $data['user_id'] = 0;
775
        } else {
776
            wpinv_set_error( 'logged_in_only', __( 'You must be logged in to pay for this invoice', 'invoicing' ) );
777
        }
778
    }
779
780
    return $data;
781
}
782
783
784
/**
785
 * Processes checkout payments.
786
 *
787
 * @param WPInv_Invoice $invoice
788
 * @param GetPaid_Payment_Form_Submission $submission
789
 */
790
function wpinv_process_checkout( $invoice, $submission ) {
791
792
    // No need to send free invoices to the gateway.
793
    if ( $invoice->is_free() ) {
794
        $invoice->set_gateway( 'none' );
795
        $invoice->add_note( __( "This is a free invoice and won't be sent to the payment gateway", 'invoicing' ), false, false, true );
796
        $invoice->mark_paid();
797
        wpinv_send_to_success_page( array( 'invoice_key' => $invoice->get_key() ) );
798
    }
799
800
    // Clear an checkout errors.
801
    wpinv_clear_errors();
802
803
    // Fires before sending to the gateway.
804
    do_action( 'getpaid_checkout_before_gateway', $invoice, $submission );
805
806
    // Allow the sumission data to be modified before it is sent to the gateway.
807
    $submission_data    = $submission->get_data();
808
    $submission_gateway = apply_filters( 'getpaid_gateway_submission_gateway', $submission_data['wpi-gateway'], $submission, $invoice );
809
    $submission_data    = apply_filters( 'getpaid_gateway_submission_data', $submission_data, $submission, $invoice );
810
811
    // Validate the currency.
812
    if ( ! apply_filters( "getpaid_gateway_{$submission_gateway}_is_valid_for_currency", true, $invoice->get_currency() ) ) {
813
        wpinv_set_error( 'invalid_currency', __( 'The chosen payment gateway does not support the invoice currency', 'invoicing' ) );
814
    }
815
816
    // Check to see if we have any errors.
817
    if ( wpinv_get_errors() ) {
818
        wpinv_send_back_to_checkout();
819
    }
820
821
    // Send info to the gateway for payment processing
822
    do_action( "getpaid_gateway_$submission_gateway", $invoice, $submission_data, $submission );
823
824
    // Backwards compatibility.
825
    do_action( "wpinv_gateway_$submission_gateway", null, $invoice, $submission_data, $submission );
826
827
}
828