Passed
Pull Request — master (#97)
by Kiran
04:00
created

wpinv-general-functions.php ➔ wpinv_sequential_number_active()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 8
rs 9.4285
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' ) );
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 );
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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 );
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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 View Code Duplication
function wpinv_send_to_success_page( $args = null ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
66
	$redirect = wpinv_get_success_page_uri();
67
    
68
    if ( !empty( $args ) ) {
69
        // Check for backward compatibility
70
        if ( is_string( $args ) )
71
            $args = str_replace( '?', '', $args );
72
73
        $args = wp_parse_args( $args );
74
75
        $redirect = add_query_arg( $args, $redirect );
76
    }
77
78
    $gateway = isset( $_REQUEST['wpi-gateway'] ) ? $_REQUEST['wpi-gateway'] : '';
79
    
80
    $redirect = apply_filters( 'wpinv_success_page_redirect', $redirect, $gateway, $args );
81
    wp_redirect( $redirect );
82
    exit;
83
}
84
85 View Code Duplication
function wpinv_send_to_failed_page( $args = null ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
	$redirect = wpinv_get_failed_transaction_uri();
87
    
88
    if ( !empty( $args ) ) {
89
        // Check for backward compatibility
90
        if ( is_string( $args ) )
91
            $args = str_replace( '?', '', $args );
92
93
        $args = wp_parse_args( $args );
94
95
        $redirect = add_query_arg( $args, $redirect );
96
    }
97
98
    $gateway = isset( $_REQUEST['wpi-gateway'] ) ? $_REQUEST['wpi-gateway'] : '';
99
    
100
    $redirect = apply_filters( 'wpinv_failed_page_redirect', $redirect, $gateway, $args );
101
    wp_redirect( $redirect );
102
    exit;
103
}
104
105
function wpinv_get_checkout_uri( $args = array() ) {
106
	$uri = wpinv_get_option( 'checkout_page', false );
107
	$uri = isset( $uri ) ? get_permalink( $uri ) : NULL;
108
109
	if ( !empty( $args ) ) {
110
		// Check for backward compatibility
111
		if ( is_string( $args ) )
112
			$args = str_replace( '?', '', $args );
113
114
		$args = wp_parse_args( $args );
115
116
		$uri = add_query_arg( $args, $uri );
117
	}
118
119
	$scheme = defined( 'FORCE_SSL_ADMIN' ) && FORCE_SSL_ADMIN ? 'https' : 'admin';
120
121
	$ajax_url = admin_url( 'admin-ajax.php', $scheme );
122
123
	if ( ( ! preg_match( '/^https/', $uri ) && preg_match( '/^https/', $ajax_url ) ) || wpinv_is_ssl_enforced() ) {
124
		$uri = preg_replace( '/^http:/', 'https:', $uri );
125
	}
126
127
	return apply_filters( 'wpinv_get_checkout_uri', $uri );
128
}
129
130
function wpinv_send_back_to_checkout( $args = array() ) {
131
	$redirect = wpinv_get_checkout_uri();
132
133
	if ( ! empty( $args ) ) {
134
		// Check for backward compatibility
135
		if ( is_string( $args ) )
136
			$args = str_replace( '?', '', $args );
137
138
		$args = wp_parse_args( $args );
139
140
		$redirect = add_query_arg( $args, $redirect );
141
	}
142
143
	wp_redirect( apply_filters( 'wpinv_send_back_to_checkout', $redirect, $args ) );
144
	exit;
145
}
146
147
function wpinv_get_success_page_url( $query_string = null ) {
148
	$success_page = wpinv_get_option( 'success_page', 0 );
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
149
	$success_page = get_permalink( $success_page );
150
151
	if ( $query_string )
152
		$success_page .= $query_string;
153
154
	return apply_filters( 'wpinv_success_page_url', $success_page );
155
}
156
157
function wpinv_get_failed_transaction_uri( $extras = false ) {
158
	$uri = wpinv_get_option( 'failure_page', '' );
0 ignored issues
show
Documentation introduced by
'' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
159
	$uri = ! empty( $uri ) ? trailingslashit( get_permalink( $uri ) ) : home_url();
160
161
	if ( $extras )
162
		$uri .= $extras;
163
164
	return apply_filters( 'wpinv_get_failed_transaction_uri', $uri );
165
}
166
167
function wpinv_is_failed_transaction_page() {
168
	$ret = wpinv_get_option( 'failure_page', false );
169
	$ret = isset( $ret ) ? is_page( $ret ) : false;
170
171
	return apply_filters( 'wpinv_is_failure_page', $ret );
172
}
173
174
function wpinv_transaction_query( $type = 'start' ) {
175
    global $wpdb;
176
177
    $wpdb->hide_errors();
178
179
    if ( ! defined( 'WPINV_USE_TRANSACTIONS' ) ) {
180
        define( 'WPINV_USE_TRANSACTIONS', true );
181
    }
182
183
    if ( WPINV_USE_TRANSACTIONS ) {
184
        switch ( $type ) {
185
            case 'commit' :
186
                $wpdb->query( 'COMMIT' );
187
                break;
188
            case 'rollback' :
189
                $wpdb->query( 'ROLLBACK' );
190
                break;
191
            default :
192
                $wpdb->query( 'START TRANSACTION' );
193
            break;
194
        }
195
    }
196
}
197
198
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.

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

Loading history...
199
    $default_args = array(
200
        'status'        => '',
201
        'user_id'       => null,
202
        'user_note'     => null,
203
        'invoice_id'    => 0,
204
        'created_via'   => '',
205
        'parent'        => 0
206
    );
207
208
    $args           = wp_parse_args( $args, $default_args );
209
    $invoice_data   = array();
210
211
    if ( $args['invoice_id'] > 0 ) {
212
        $updating           = true;
213
        $invoice_data['post_type']  = 'wpi_invoice';
214
        $invoice_data['ID']         = $args['invoice_id'];
215
    } else {
216
        $updating                       = false;
217
        $invoice_data['post_type']      = 'wpi_invoice';
218
        $invoice_data['post_status']    = apply_filters( 'wpinv_default_invoice_status', 'wpi-pending' );
219
        $invoice_data['ping_status']    = 'closed';
220
        $invoice_data['post_author']    = !empty( $args['user_id'] ) ? $args['user_id'] : get_current_user_id();
221
        $invoice_data['post_title']     = wpinv_format_invoice_number( '0' );
222
        $invoice_data['post_parent']    = absint( $args['parent'] );
223
        if ( !empty( $args['created_date'] ) ) {
224
            $invoice_data['post_date']      = $args['created_date'];
225
            $invoice_data['post_date_gmt']  = get_gmt_from_date( $args['created_date'] );
226
        }
227
    }
228
229
    if ( $args['status'] ) {
230
        if ( ! in_array( $args['status'], array_keys( wpinv_get_invoice_statuses() ) ) ) {
231
            return new WP_Error( 'wpinv_invalid_invoice_status', wp_sprintf( __( 'Invalid invoice status: %s', 'invoicing' ), $args['status'] ) );
232
        }
233
        $invoice_data['post_status']    = $args['status'];
234
    }
235
236
    if ( ! is_null( $args['user_note'] ) ) {
237
        $invoice_data['post_excerpt']   = $args['user_note'];
238
    }
239
240
    if ( $updating ) {
241
        $invoice_id = wp_update_post( $invoice_data, true );
242
    } else {
243
        $invoice_id = wp_insert_post( apply_filters( 'wpinv_new_invoice_data', $invoice_data ), true );
244
    }
245
246
    if ( is_wp_error( $invoice_id ) ) {
247
        return $wp_error ? $invoice_id : 0;
248
    }
249
    
250
    $invoice = wpinv_get_invoice( $invoice_id );
251
252
    if ( !$updating ) {
253
        update_post_meta( $invoice_id, '_wpinv_key', apply_filters( 'wpinv_generate_invoice_key', uniqid( 'wpinv_' ) ) );
254
        update_post_meta( $invoice_id, '_wpinv_currency', wpinv_get_currency() );
255
        update_post_meta( $invoice_id, '_wpinv_include_tax', get_option( 'wpinv_prices_include_tax' ) );
256
        update_post_meta( $invoice_id, '_wpinv_user_ip', wpinv_get_ip() );
257
        update_post_meta( $invoice_id, '_wpinv_user_agent', wpinv_get_user_agent() );
258
        update_post_meta( $invoice_id, '_wpinv_created_via', sanitize_text_field( $args['created_via'] ) );
259
        
260
        // Add invoice note
261
        $invoice->add_note( wp_sprintf( __( 'Invoice is created with status %s.', 'invoicing' ), wpinv_status_nicename( $invoice->status ) ) );
262
    }
263
264
    update_post_meta( $invoice_id, '_wpinv_version', WPINV_VERSION );
265
266
    return $invoice;
267
}
268
269
function wpinv_get_prefix() {
270
    $invoice_prefix = 'INV-';
271
    
272
    return apply_filters( 'wpinv_get_prefix', $invoice_prefix );
273
}
274
275
function wpinv_get_business_logo() {
276
    $business_logo = wpinv_get_option( 'logo' );
277
    return apply_filters( 'wpinv_get_business_logo', $business_logo );
278
}
279
280
function wpinv_get_business_name() {
281
    $business_name = wpinv_get_option('store_name');
282
    return apply_filters( 'wpinv_get_business_name', $business_name );
283
}
284
285
function wpinv_get_blogname() {
286
    return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
287
}
288
289
function wpinv_get_admin_email() {
290
    $admin_email = get_option( 'admin_email' );
291
    return apply_filters( 'wpinv_admin_email', $admin_email );
292
}
293
294
function wpinv_get_business_website() {
295
    $business_website = home_url( '/' );
296
    return apply_filters( 'wpinv_get_business_website', $business_website );
297
}
298
299
function wpinv_get_terms_text( $invoice_id = 0 ) {
300
    $terms_text = '';
301
    return apply_filters( 'wpinv_get_terms_text', $terms_text, $invoice_id );
302
}
303
304
function wpinv_get_business_footer() {
305
    $site_link = '<a target="_blank" href="' . esc_url( wpinv_get_business_website() ) . '">' . esc_html( wpinv_get_business_name() ) . '</a>';
306
    $business_footer = wp_sprintf( __( 'Thanks for using %s', 'invoicing' ), $site_link );
307
    return apply_filters( 'wpinv_get_business_footer', $business_footer );
308
}
309
310
function wpinv_checkout_required_fields() {
311
    $required_fields = array();
312
    
313
    // Let payment gateways and other extensions determine if address fields should be required
314
    $require_billing_details = apply_filters( 'wpinv_checkout_required_billing_details', wpinv_use_taxes() );
315
    
316
    if ( $require_billing_details ) {
317
        ///$required_fields['email'] = array(
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
318
                ///'error_id' => 'invalid_email',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
319
                ///'error_message' => __( 'Please enter a valid email address', 'invoicing' )
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
320
            ///);
321
        $required_fields['first_name'] = array(
322
                'error_id' => 'invalid_first_name',
323
                'error_message' => __( 'Please enter your first name', 'invoicing' )
324
            );
325
        $required_fields['address'] = array(
326
                'error_id' => 'invalid_address',
327
                'error_message' => __( 'Please enter your address', 'invoicing' )
328
            );
329
        $required_fields['city'] = array(
330
                'error_id' => 'invalid_city',
331
                'error_message' => __( 'Please enter your billing city', 'invoicing' )
332
            );
333
        $required_fields['state'] = array(
334
                'error_id' => 'invalid_state',
335
                'error_message' => __( 'Please enter billing state / province', 'invoicing' )
336
            );
337
        $required_fields['country'] = array(
338
                'error_id' => 'invalid_country',
339
                'error_message' => __( 'Please select your billing country', 'invoicing' )
340
            );
341
    }
342
343
    return apply_filters( 'wpinv_checkout_required_fields', $required_fields );
344
}
345
346
function wpinv_is_ssl_enforced() {
347
    $ssl_enforced = wpinv_get_option( 'enforce_ssl', false );
348
    return (bool) apply_filters( 'wpinv_is_ssl_enforced', $ssl_enforced );
349
}
350
351
function wpinv_user_can_view_invoice( $post ) {
352
    $allow = false;
353
354
    $post = get_post( $post );
355
356
    if ( empty( $post->ID ) ) {
357
        return $allow;
358
    }
359
360
    $invoice = wpinv_get_invoice( $post->ID );
361
    if ( empty( $invoice->ID ) ) {
362
        return $allow;
363
    }
364
365
    // Don't allow trash, draft status
366
    if ( $invoice->has_status( array_keys( wpinv_get_invoice_statuses() ) ) ) {
367
        if ( current_user_can( 'manage_options' ) ) { // Admin user
368
            $allow = true;
369
        } else {
370
            if ( is_user_logged_in() ) {
371
                if ( (int)$invoice->get_user_id() === (int)get_current_user_id() ) {
372
                    $allow = true;
373 View Code Duplication
                } else if ( !wpinv_require_login_to_checkout() && isset( $_GET['invoice_key'] ) && $_GET['invoice_key'] === $invoice->get_key() ) {
374
                    $allow = true;
375
                }
376 View Code Duplication
            } else {
377
                if ( !wpinv_require_login_to_checkout() && isset( $_GET['invoice_key'] ) && $_GET['invoice_key'] === $invoice->get_key() ) {
378
                    $allow = true;
379
                }
380
            }
381
        }
382
    }
383
    
384
    return apply_filters( 'wpinv_can_print_invoice', $allow, $post, $invoice );
385
}
386
387
function wpinv_schedule_events() {
388
    // hourly, daily and twicedaily
389
    if ( !wp_next_scheduled( 'wpinv_register_schedule_event_twicedaily' ) ) {
390
        wp_schedule_event( current_time( 'timestamp' ), 'twicedaily', 'wpinv_register_schedule_event_twicedaily' );
391
    }
392
}
393
add_action( 'wp', 'wpinv_schedule_events' );
394
395
function wpinv_schedule_event_twicedaily() {
396
    wpinv_email_payment_reminders();
397
}
398
add_action( 'wpinv_register_schedule_event_twicedaily', 'wpinv_schedule_event_twicedaily' );
399
400
function wpinv_require_login_to_checkout() {
401
    $return = wpinv_get_option( 'login_to_checkout', false );
402
    return (bool) apply_filters( 'wpinv_require_login_to_checkout', $return );
403
}
404
405
function wpinv_sequential_number_active( $type = '' ) {
406
    $check = apply_filters( 'wpinv_pre_check_sequential_number_active', null, $type );
407
    if ( null !== $check ) {
408
        return $check;
409
    }
410
    
411
    return wpinv_get_option( 'sequential_invoice_number' );
412
}