Passed
Pull Request — master (#57)
by Kiran
04:35
created

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

Complexity

Conditions 11
Paths 165

Size

Total Lines 70
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 48
nc 165
nop 3
dl 0
loc 70
rs 5.3599
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
    }
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_print_invoice( $post ) {
352
    $allow = false;
353
    
354
    if ( !( $user_id = get_current_user_id() ) ) {
355
        return $allow;
356
    }
357
    
358
    if ( is_int( $post ) ) {
359
        $post = get_post( $post );
360
    }
361
    
362
    // Allow to owner.
363
    if ( is_object( $post ) && !empty( $post->post_author ) && $post->post_author == $user_id ) {
364
        $allow = true;
365
    }
366
    
367
    // Allow to admin user.
368
    if ( current_user_can( 'manage_options' ) ) {
369
        $allow = true;
370
    }
371
    
372
    return apply_filters( 'wpinv_can_print_invoice', $allow, $post );
373
}
374
375
function wpinv_schedule_events() {
376
    // hourly, daily and twicedaily
377
    if ( !wp_next_scheduled( 'wpinv_register_schedule_event_twicedaily' ) ) {
378
        wp_schedule_event( current_time( 'timestamp' ), 'twicedaily', 'wpinv_register_schedule_event_twicedaily' );
379
    }
380
}
381
add_action( 'wp', 'wpinv_schedule_events' );
382
383
function wpinv_schedule_event_twicedaily() {
384
    wpinv_email_payment_reminders();
385
}
386
add_action( 'wpinv_register_schedule_event_twicedaily', 'wpinv_schedule_event_twicedaily' );