Passed
Pull Request — master (#275)
by Brian
06:25
created

wpinv_checkout_required_fields()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 28
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 2
nop 0
dl 0
loc 28
rs 9.5555
c 0
b 0
f 0
1
<?php
2
/**
3
 * Contains functions related to Invoicing plugin.
4
 *
5
 * @since 1.0.0
6
 * @package Invoicing
7
 */
8
 
9
// MUST have WordPress.
10
if ( !defined( 'WPINC' ) ) {
11
    exit( 'Do NOT access this file directly: ' . basename( __FILE__ ) );
12
}
13
14
function wpinv_is_checkout() {
15
    global $wp_query;
16
17
    $is_object_set    = isset( $wp_query->queried_object );
18
    $is_object_id_set = isset( $wp_query->queried_object_id );
19
    $is_checkout      = is_page( wpinv_get_option( 'checkout_page' ) );
0 ignored issues
show
Bug introduced by
It seems like wpinv_get_option('checkout_page') can also be of type false; however, parameter $page of is_page() does only seem to accept array|integer|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

19
    $is_checkout      = is_page( /** @scrutinizer ignore-type */ wpinv_get_option( 'checkout_page' ) );
Loading history...
20
21
    if ( !$is_object_set ) {
22
        unset( $wp_query->queried_object );
23
    }
24
25
    if ( !$is_object_id_set ) {
26
        unset( $wp_query->queried_object_id );
27
    }
28
29
    return apply_filters( 'wpinv_is_checkout', $is_checkout );
30
}
31
32
function wpinv_can_checkout() {
33
	$can_checkout = true; // Always true for now
34
35
	return (bool) apply_filters( 'wpinv_can_checkout', $can_checkout );
36
}
37
38
function wpinv_get_success_page_uri() {
39
	$page_id = wpinv_get_option( 'success_page', 0 );
40
	$page_id = absint( $page_id );
41
42
	return apply_filters( 'wpinv_get_success_page_uri', get_permalink( $page_id ) );
43
}
44
45
function wpinv_get_history_page_uri() {
46
	$page_id = wpinv_get_option( 'invoice_history_page', 0 );
47
	$page_id = absint( $page_id );
48
49
	return apply_filters( 'wpinv_get_history_page_uri', get_permalink( $page_id ) );
50
}
51
52
function wpinv_is_success_page() {
53
	$is_success_page = wpinv_get_option( 'success_page', false );
54
	$is_success_page = isset( $is_success_page ) ? is_page( $is_success_page ) : false;
55
56
	return apply_filters( 'wpinv_is_success_page', $is_success_page );
57
}
58
59
function wpinv_is_invoice_history_page() {
60
	$ret = wpinv_get_option( 'invoice_history_page', false );
61
	$ret = $ret ? is_page( $ret ) : false;
62
	return apply_filters( 'wpinv_is_invoice_history_page', $ret );
63
}
64
65
function wpinv_is_subscriptions_history_page() {
66
    $ret = wpinv_get_option( 'invoice_subscription_page', false );
67
    $ret = $ret ? is_page( $ret ) : false;
68
    return apply_filters( 'wpinv_is_subscriptions_history_page', $ret );
69
}
70
71
function wpinv_send_to_success_page( $args = null ) {
72
	$redirect = wpinv_get_success_page_uri();
73
    
74
    if ( !empty( $args ) ) {
75
        // Check for backward compatibility
76
        if ( is_string( $args ) )
77
            $args = str_replace( '?', '', $args );
78
79
        $args = wp_parse_args( $args );
80
81
        $redirect = add_query_arg( $args, $redirect );
82
    }
83
84
    $gateway = isset( $_REQUEST['wpi-gateway'] ) ? $_REQUEST['wpi-gateway'] : '';
85
    
86
    $redirect = apply_filters( 'wpinv_success_page_redirect', $redirect, $gateway, $args );
87
    wp_redirect( $redirect );
88
    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...
89
}
90
91
function wpinv_send_to_failed_page( $args = null ) {
92
	$redirect = wpinv_get_failed_transaction_uri();
93
    
94
    if ( !empty( $args ) ) {
95
        // Check for backward compatibility
96
        if ( is_string( $args ) )
97
            $args = str_replace( '?', '', $args );
98
99
        $args = wp_parse_args( $args );
100
101
        $redirect = add_query_arg( $args, $redirect );
102
    }
103
104
    $gateway = isset( $_REQUEST['wpi-gateway'] ) ? $_REQUEST['wpi-gateway'] : '';
105
    
106
    $redirect = apply_filters( 'wpinv_failed_page_redirect', $redirect, $gateway, $args );
107
    wp_redirect( $redirect );
108
    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...
109
}
110
111
function wpinv_get_checkout_uri( $args = array() ) {
112
	$uri = wpinv_get_option( 'checkout_page', false );
113
	$uri = isset( $uri ) ? get_permalink( $uri ) : NULL;
114
115
	if ( !empty( $args ) ) {
116
		// Check for backward compatibility
117
		if ( is_string( $args ) )
118
			$args = str_replace( '?', '', $args );
119
120
		$args = wp_parse_args( $args );
121
122
		$uri = add_query_arg( $args, $uri );
123
	}
124
125
	$scheme = defined( 'FORCE_SSL_ADMIN' ) && FORCE_SSL_ADMIN ? 'https' : 'admin';
126
127
	$ajax_url = admin_url( 'admin-ajax.php', $scheme );
128
129
	if ( ( ! preg_match( '/^https/', $uri ) && preg_match( '/^https/', $ajax_url ) ) || wpinv_is_ssl_enforced() ) {
0 ignored issues
show
Bug introduced by
It seems like $uri can also be of type false; however, parameter $subject of preg_match() 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

129
	if ( ( ! preg_match( '/^https/', /** @scrutinizer ignore-type */ $uri ) && preg_match( '/^https/', $ajax_url ) ) || wpinv_is_ssl_enforced() ) {
Loading history...
130
		$uri = preg_replace( '/^http:/', 'https:', $uri );
131
	}
132
133
	return apply_filters( 'wpinv_get_checkout_uri', $uri );
134
}
135
136
function wpinv_send_back_to_checkout( $args = array() ) {
137
	$redirect = wpinv_get_checkout_uri();
138
139
	if ( ! empty( $args ) ) {
140
		// Check for backward compatibility
141
		if ( is_string( $args ) )
142
			$args = str_replace( '?', '', $args );
143
144
		$args = wp_parse_args( $args );
145
146
		$redirect = add_query_arg( $args, $redirect );
147
	}
148
149
	wp_redirect( apply_filters( 'wpinv_send_back_to_checkout', $redirect, $args ) );
150
	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...
151
}
152
153
function wpinv_get_success_page_url( $query_string = null ) {
154
	$success_page = wpinv_get_option( 'success_page', 0 );
155
	$success_page = get_permalink( $success_page );
156
157
	if ( $query_string )
158
		$success_page .= $query_string;
159
160
	return apply_filters( 'wpinv_success_page_url', $success_page );
161
}
162
163
function wpinv_get_failed_transaction_uri( $extras = false ) {
164
	$uri = wpinv_get_option( 'failure_page', '' );
165
	$uri = ! empty( $uri ) ? trailingslashit( get_permalink( $uri ) ) : home_url();
0 ignored issues
show
Bug introduced by
It seems like $uri can also be of type string; however, parameter $post of get_permalink() does only seem to accept WP_Post|integer, 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

165
	$uri = ! empty( $uri ) ? trailingslashit( get_permalink( /** @scrutinizer ignore-type */ $uri ) ) : home_url();
Loading history...
Bug introduced by
It seems like get_permalink($uri) can also be of type false; however, parameter $string of trailingslashit() 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

165
	$uri = ! empty( $uri ) ? trailingslashit( /** @scrutinizer ignore-type */ get_permalink( $uri ) ) : home_url();
Loading history...
166
167
	if ( $extras )
168
		$uri .= $extras;
169
170
	return apply_filters( 'wpinv_get_failed_transaction_uri', $uri );
171
}
172
173
function wpinv_is_failed_transaction_page() {
174
	$ret = wpinv_get_option( 'failure_page', false );
175
	$ret = isset( $ret ) ? is_page( $ret ) : false;
176
177
	return apply_filters( 'wpinv_is_failure_page', $ret );
178
}
179
180
function wpinv_transaction_query( $type = 'start' ) {
181
    global $wpdb;
182
183
    $wpdb->hide_errors();
184
185
    if ( ! defined( 'WPINV_USE_TRANSACTIONS' ) ) {
186
        define( 'WPINV_USE_TRANSACTIONS', true );
187
    }
188
189
    if ( WPINV_USE_TRANSACTIONS ) {
190
        switch ( $type ) {
191
            case 'commit' :
192
                $wpdb->query( 'COMMIT' );
193
                break;
194
            case 'rollback' :
195
                $wpdb->query( 'ROLLBACK' );
196
                break;
197
            default :
198
                $wpdb->query( 'START TRANSACTION' );
199
            break;
200
        }
201
    }
202
}
203
204
function wpinv_create_invoice( $args = array(), $data = array(), $wp_error = false ) {
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

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

204
function wpinv_create_invoice( $args = array(), /** @scrutinizer ignore-unused */ $data = array(), $wp_error = false ) {

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

Loading history...
205
    $default_args = array(
206
        'status'        => '',
207
        'user_id'       => null,
208
        'user_note'     => null,
209
        'invoice_id'    => 0,
210
        'created_via'   => '',
211
        'parent'        => 0,
212
        'post_type'     => 'wpi_invoice'
213
    );
214
215
    $args           = wp_parse_args( $args, $default_args );
216
    $invoice_data   = array();
217
218
    if ( $args['invoice_id'] > 0 ) {
219
        $updating           = true;
220
        $invoice_data['post_type']  = $args['post_type'];
221
        $invoice_data['ID']         = $args['invoice_id'];
222
    } else {
223
        $updating                       = false;
224
        $invoice_data['post_type']      = $args['post_type'];
225
        $invoice_data['post_status']    = apply_filters( 'wpinv_default_invoice_status', 'wpi-pending' );
226
        $invoice_data['ping_status']    = 'closed';
227
        $invoice_data['post_author']    = !empty( $args['user_id'] ) ? $args['user_id'] : get_current_user_id();
228
        $invoice_data['post_title']     = wpinv_format_invoice_number( '0' );
229
        $invoice_data['post_parent']    = absint( $args['parent'] );
230
        if ( !empty( $args['created_date'] ) ) {
231
            $invoice_data['post_date']      = $args['created_date'];
232
            $invoice_data['post_date_gmt']  = get_gmt_from_date( $args['created_date'] );
233
        }
234
    }
235
236
    if ( $args['status'] ) {
237
        if ( ! in_array( $args['status'], array_keys( wpinv_get_invoice_statuses() ) ) && 'wpi_invoice' === $invoice_data['post_type'] ) {
238
            return new WP_Error( 'wpinv_invalid_invoice_status', wp_sprintf( __( 'Invalid invoice status: %s', 'invoicing' ), $args['status'] ) );
239
        }
240
        $invoice_data['post_status']    = $args['status'];
241
    }
242
243
    if ( ! is_null( $args['user_note'] ) ) {
244
        $invoice_data['post_excerpt']   = $args['user_note'];
245
    }
246
247
    if ( $updating ) {
248
        $invoice_id = wp_update_post( $invoice_data, true );
249
    } else {
250
        $invoice_id = wp_insert_post( apply_filters( 'wpinv_new_invoice_data', $invoice_data ), true );
251
    }
252
253
    if ( is_wp_error( $invoice_id ) ) {
254
        return $wp_error ? $invoice_id : 0;
255
    }
256
    
257
    $invoice = wpinv_get_invoice( $invoice_id );
258
259
    if ( !$updating ) {
260
        update_post_meta( $invoice_id, '_wpinv_key', apply_filters( 'wpinv_generate_invoice_key', uniqid( 'wpinv_' ) ) );
0 ignored issues
show
Bug introduced by
It seems like $invoice_id can also be of type WP_Error; however, parameter $post_id of update_post_meta() does only seem to accept integer, 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

260
        update_post_meta( /** @scrutinizer ignore-type */ $invoice_id, '_wpinv_key', apply_filters( 'wpinv_generate_invoice_key', uniqid( 'wpinv_' ) ) );
Loading history...
261
        update_post_meta( $invoice_id, '_wpinv_currency', wpinv_get_currency() );
262
        update_post_meta( $invoice_id, '_wpinv_include_tax', get_option( 'wpinv_prices_include_tax' ) );
263
        update_post_meta( $invoice_id, '_wpinv_user_ip', wpinv_get_ip() );
264
        update_post_meta( $invoice_id, '_wpinv_user_agent', wpinv_get_user_agent() );
265
        update_post_meta( $invoice_id, '_wpinv_created_via', sanitize_text_field( $args['created_via'] ) );
266
        
267
        // Add invoice note
268
        if ( ! $invoice->is_quote() ) {
269
            $invoice->add_note( wp_sprintf( __( 'Invoice is created with status %s.', 'invoicing' ), wpinv_status_nicename( $invoice->status ) ) );
270
        }
271
        
272
    }
273
274
    update_post_meta( $invoice_id, '_wpinv_version', WPINV_VERSION );
275
276
    return $invoice;
277
}
278
279
function wpinv_get_prefix() {
280
    $invoice_prefix = 'INV-';
281
    
282
    return apply_filters( 'wpinv_get_prefix', $invoice_prefix );
283
}
284
285
function wpinv_get_business_logo() {
286
    $business_logo = wpinv_get_option( 'logo' );
287
    return apply_filters( 'wpinv_get_business_logo', $business_logo );
288
}
289
290
function wpinv_get_business_name() {
291
    $business_name = wpinv_get_option('store_name');
292
    return apply_filters( 'wpinv_get_business_name', $business_name );
293
}
294
295
function wpinv_get_blogname() {
296
    return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
0 ignored issues
show
Bug introduced by
It seems like get_option('blogname') can also be of type false; however, parameter $string of wp_specialchars_decode() 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

296
    return wp_specialchars_decode( /** @scrutinizer ignore-type */ get_option( 'blogname' ), ENT_QUOTES );
Loading history...
297
}
298
299
function wpinv_get_admin_email() {
300
    $admin_email = get_option( 'admin_email' );
301
    return apply_filters( 'wpinv_admin_email', $admin_email );
302
}
303
304
function wpinv_get_business_website() {
305
    $business_website = home_url( '/' );
306
    return apply_filters( 'wpinv_get_business_website', $business_website );
307
}
308
309
function wpinv_get_terms_text( $invoice_id = 0 ) {
310
    $terms_text = '';
311
    return apply_filters( 'wpinv_get_terms_text', $terms_text, $invoice_id );
312
}
313
314
function wpinv_get_business_footer() {
315
    $site_link = '<a target="_blank" href="' . esc_url( wpinv_get_business_website() ) . '">' . esc_html( wpinv_get_business_name() ) . '</a>';
0 ignored issues
show
Bug introduced by
It seems like wpinv_get_business_name() can also be of type false; however, parameter $text of esc_html() 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

315
    $site_link = '<a target="_blank" href="' . esc_url( wpinv_get_business_website() ) . '">' . esc_html( /** @scrutinizer ignore-type */ wpinv_get_business_name() ) . '</a>';
Loading history...
316
    $business_footer = wp_sprintf( __( 'Thanks for using %s', 'invoicing' ), $site_link );
317
    return apply_filters( 'wpinv_get_business_footer', $business_footer );
318
}
319
320
function wpinv_checkout_required_fields() {
321
    $required_fields = array();
322
323
    // Let payment gateways and other extensions determine if address fields should be required
324
    $require_billing_details = apply_filters( 'wpinv_checkout_required_billing_details', wpinv_use_taxes() );
325
    $checkout_fields    = wpinv_get_checkout_checkout_fields();
0 ignored issues
show
Bug introduced by
The function wpinv_get_checkout_checkout_fields was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

325
    $checkout_fields    = /** @scrutinizer ignore-call */ wpinv_get_checkout_checkout_fields();
Loading history...
326
327
    if ( $require_billing_details ) {
328
329
        foreach( $checkout_fields as $key => $details ) {
330
331
            if ( ! empty( $details['field_enabled'] ) &&  ! empty( $details['field_required'] ) ) {
332
333
                $required_fields[ $details['key'] ] = array(
334
                    'error_id'      => $details['name'],
335
                    'error_message' => sprintf(
336
                        __( '%s is required', 'invoicing' ),
337
                        $details['field_label']
338
                    )
339
                );
340
341
            }
342
343
        }
344
345
    }
346
347
    return apply_filters( 'wpinv_checkout_required_fields', $required_fields );
348
}
349
350
function wpinv_is_ssl_enforced() {
351
    $ssl_enforced = wpinv_get_option( 'enforce_ssl', false );
352
    return (bool) apply_filters( 'wpinv_is_ssl_enforced', $ssl_enforced );
353
}
354
355
function wpinv_user_can_view_invoice( $post ) {
356
    $allow = false;
357
358
    $post = get_post( $post );
359
360
    if ( empty( $post->ID ) ) {
361
        return $allow;
362
    }
363
364
    $invoice = wpinv_get_invoice( $post->ID );
365
    if ( empty( $invoice->ID ) ) {
366
        return $allow;
367
    }
368
369
    // Don't allow trash, draft status
370
    if ( $invoice->has_status( array_keys( wpinv_get_invoice_statuses() ) ) ) {
371
        if ( wpinv_current_user_can_manage_invoicing() || current_user_can( 'view_invoices', $invoice->ID ) ) { // Admin user
372
            $allow = true;
373
        } else {
374
            if ( is_user_logged_in() ) {
375
                if ( (int)$invoice->get_user_id() === (int)get_current_user_id() ) {
376
                    $allow = true;
377
                } else if ( !wpinv_require_login_to_checkout() && isset( $_GET['invoice_key'] ) && $_GET['invoice_key'] === $invoice->get_key() ) {
378
                    $allow = true;
379
                }
380
            } else {
381
                if ( !wpinv_require_login_to_checkout() && isset( $_GET['invoice_key'] ) && $_GET['invoice_key'] === $invoice->get_key() ) {
382
                    $allow = true;
383
                }
384
            }
385
        }
386
    }
387
    
388
    return apply_filters( 'wpinv_can_print_invoice', $allow, $post, $invoice );
389
}
390
391
function wpinv_schedule_events() {
392
    // hourly, daily and twicedaily
393
    if ( !wp_next_scheduled( 'wpinv_register_schedule_event_twicedaily' ) ) {
394
        wp_schedule_event( current_time( 'timestamp' ), 'twicedaily', 'wpinv_register_schedule_event_twicedaily' );
395
    }
396
}
397
add_action( 'wp', 'wpinv_schedule_events' );
398
399
function wpinv_schedule_event_twicedaily() {
400
    wpinv_email_payment_reminders();
401
}
402
add_action( 'wpinv_register_schedule_event_twicedaily', 'wpinv_schedule_event_twicedaily' );
403
404
function wpinv_require_login_to_checkout() {
405
    $return = wpinv_get_option( 'login_to_checkout', false );
406
    return (bool) apply_filters( 'wpinv_require_login_to_checkout', $return );
407
}
408
409
function wpinv_sequential_number_active( $type = '' ) {
410
    $check = apply_filters( 'wpinv_pre_check_sequential_number_active', null, $type );
411
    if ( null !== $check ) {
412
        return $check;
413
    }
414
    
415
    return wpinv_get_option( 'sequential_invoice_number' );
416
}
417
418
function wpinv_switch_to_locale( $locale = NULL ) {
419
    global $invoicing, $wpi_switch_locale;
420
421
    if ( ! empty( $invoicing ) && function_exists( 'switch_to_locale' ) ) {
422
        $locale = empty( $locale ) ? get_locale() : $locale;
423
424
        switch_to_locale( $locale );
425
426
        $wpi_switch_locale = $locale;
427
428
        add_filter( 'plugin_locale', 'get_locale' );
429
430
        $invoicing->load_textdomain();
431
432
        do_action( 'wpinv_switch_to_locale', $locale );
433
    }
434
}
435
436
function wpinv_restore_locale() {
437
    global $invoicing, $wpi_switch_locale;
438
    
439
    if ( ! empty( $invoicing ) && function_exists( 'restore_previous_locale' ) && $wpi_switch_locale ) {
440
        restore_previous_locale();
441
442
        $wpi_switch_locale = NULL;
443
444
        remove_filter( 'plugin_locale', 'get_locale' );
445
446
        $invoicing->load_textdomain();
447
448
        do_action( 'wpinv_restore_locale' );
449
    }
450
}