Passed
Pull Request — master (#50)
by Kiran
03:42
created

wpinv-general-functions.php ➔ wpinv_create_invoice()   F

Complexity

Conditions 12
Paths 245

Size

Total Lines 79
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 54
nc 245
nop 3
dl 0
loc 79
rs 3.9453
c 0
b 0
f 0

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 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', '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
    } else {
249
        if ( !$updating ) {
250
            $invoice_number = wpinv_format_invoice_number( $invoice_id );
251
            
252
            $update = array( 'ID' => $invoice_id, 'post_title' => $invoice_number, 'post_name' => sanitize_title( $invoice_number ) );
253
            wp_update_post( $update );
254
            
255
            update_post_meta( $invoice_id, '_wpinv_number', $invoice_number );
256
        }
257
    }
258
    
259
    $invoice = wpinv_get_invoice( $invoice_id );
260
261
    if ( !$updating ) {
262
        update_post_meta( $invoice_id, '_wpinv_key', apply_filters( 'wpinv_generate_invoice_key', uniqid( 'wpinv_' ) ) );
263
        update_post_meta( $invoice_id, '_wpinv_currency', wpinv_get_currency() );
264
        update_post_meta( $invoice_id, '_wpinv_include_tax', get_option( 'wpinv_prices_include_tax' ) );
265
        update_post_meta( $invoice_id, '_wpinv_user_ip', wpinv_get_ip() );
266
        update_post_meta( $invoice_id, '_wpinv_user_agent', wpinv_get_user_agent() );
267
        update_post_meta( $invoice_id, '_wpinv_created_via', sanitize_text_field( $args['created_via'] ) );
268
        
269
        // Add invoice note
270
        $invoice->add_note( wp_sprintf( __( 'Invoice is created with status %s.', 'invoicing' ), wpinv_status_nicename( $invoice->status ) ) );
271
    }
272
273
    update_post_meta( $invoice_id, '_wpinv_version', WPINV_VERSION );
274
275
    return $invoice;
276
}
277
278
function wpinv_get_prefix() {
279
    $invoice_prefix = 'INV-';
280
    
281
    return apply_filters( 'wpinv_get_prefix', $invoice_prefix );
282
}
283
284
function wpinv_get_business_logo() {
285
    $business_logo = wpinv_get_option( 'logo' );
286
    return apply_filters( 'wpinv_get_business_logo', $business_logo );
287
}
288
289
function wpinv_get_business_name() {
290
    $business_name = wpinv_get_option('store_name');
291
    return apply_filters( 'wpinv_get_business_name', $business_name );
292
}
293
294
function wpinv_get_blogname() {
295
    return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
296
}
297
298
function wpinv_get_admin_email() {
299
    $admin_email = get_option( 'admin_email' );
300
    return apply_filters( 'wpinv_admin_email', $admin_email );
301
}
302
303
function wpinv_get_business_website() {
304
    $business_website = home_url( '/' );
305
    return apply_filters( 'wpinv_get_business_website', $business_website );
306
}
307
308
function wpinv_get_terms_text( $invoice_id = 0 ) {
309
    $terms_text = '';
310
    return apply_filters( 'wpinv_get_terms_text', $terms_text, $invoice_id );
311
}
312
313
function wpinv_get_business_footer() {
314
    $site_link = '<a target="_blank" href="' . esc_url( wpinv_get_business_website() ) . '">' . esc_html( wpinv_get_business_name() ) . '</a>';
315
    $business_footer = wp_sprintf( __( 'Thanks for using %s', 'invoicing' ), $site_link );
316
    return apply_filters( 'wpinv_get_business_footer', $business_footer );
317
}
318
319
function wpinv_checkout_required_fields() {
320
    $required_fields = array();
321
    
322
    // Let payment gateways and other extensions determine if address fields should be required
323
    $require_billing_details = apply_filters( 'wpinv_checkout_required_billing_details', wpinv_use_taxes() );
324
    
325
    if ( $require_billing_details ) {
326
        ///$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...
327
                ///'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...
328
                ///'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...
329
            ///);
330
        $required_fields['first_name'] = array(
331
                'error_id' => 'invalid_first_name',
332
                'error_message' => __( 'Please enter your first name', 'invoicing' )
333
            );
334
        $required_fields['address'] = array(
335
                'error_id' => 'invalid_address',
336
                'error_message' => __( 'Please enter your address', 'invoicing' )
337
            );
338
        $required_fields['city'] = array(
339
                'error_id' => 'invalid_city',
340
                'error_message' => __( 'Please enter your billing city', 'invoicing' )
341
            );
342
        $required_fields['state'] = array(
343
                'error_id' => 'invalid_state',
344
                'error_message' => __( 'Please enter billing state / province', 'invoicing' )
345
            );
346
        $required_fields['country'] = array(
347
                'error_id' => 'invalid_country',
348
                'error_message' => __( 'Please select your billing country', 'invoicing' )
349
            );
350
    }
351
352
    return apply_filters( 'wpinv_checkout_required_fields', $required_fields );
353
}
354
355
function wpinv_is_ssl_enforced() {
356
    $ssl_enforced = wpinv_get_option( 'enforce_ssl', false );
357
    return (bool) apply_filters( 'wpinv_is_ssl_enforced', $ssl_enforced );
358
}
359
360
function wpinv_user_can_print_invoice( $post ) {
361
    $allow = false;
362
    
363
    if ( !( $user_id = get_current_user_id() ) ) {
364
        return $allow;
365
    }
366
    
367
    if ( is_int( $post ) ) {
368
        $post = get_post( $post );
369
    }
370
    
371
    // Allow to owner.
372
    if ( is_object( $post ) && !empty( $post->post_author ) && $post->post_author == $user_id ) {
373
        $allow = true;
374
    }
375
    
376
    // Allow to admin user.
377
    if ( current_user_can( 'manage_options' ) ) {
378
        $allow = true;
379
    }
380
    
381
    return apply_filters( 'wpinv_can_print_invoice', $allow, $post );
382
}
383
384
function wpinv_schedule_events() {
385
    // hourly, daily and twicedaily
386
    if ( !wp_next_scheduled( 'wpinv_register_schedule_event_twicedaily' ) ) {
387
        wp_schedule_event( current_time( 'timestamp' ), 'twicedaily', 'wpinv_register_schedule_event_twicedaily' );
388
    }
389
}
390
add_action( 'wp', 'wpinv_schedule_events' );
391
392
function wpinv_schedule_event_twicedaily() {
393
    wpinv_email_payment_reminders();
394
}
395
add_action( 'wpinv_register_schedule_event_twicedaily', 'wpinv_schedule_event_twicedaily' );