Passed
Push — master ( abdd42...378b1c )
by Brian
20:25 queued 15:01
created

wpinv_convert_old_subscriptions()   F

Complexity

Conditions 23
Paths 545

Size

Total Lines 107
Code Lines 70

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 70
c 0
b 0
f 0
nc 545
nop 0
dl 0
loc 107
rs 0.6319

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
 * Upgrade related functions.
4
 *
5
 * @since 1.0.0
6
 */
7
8
/**
9
 * Perform automatic upgrades when necessary.
10
 *
11
 * @since 1.0.0
12
*/
13
function wpinv_automatic_upgrade() {
14
    $wpi_version = get_option( 'wpinv_version' );
15
16
    // Update tables.
17
    if ( ! get_option( 'getpaid_created_invoice_tables' ) ) {
18
        wpinv_v119_upgrades();
19
        update_option( 'getpaid_created_invoice_tables', true );
20
    }
21
22
    if ( $wpi_version == WPINV_VERSION ) {
23
        return;
24
    }
25
26
    if ( version_compare( $wpi_version, '0.0.5', '<' ) ) {
0 ignored issues
show
Bug introduced by
It seems like $wpi_version can also be of type false; however, parameter $version1 of version_compare() 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

26
    if ( version_compare( /** @scrutinizer ignore-type */ $wpi_version, '0.0.5', '<' ) ) {
Loading history...
27
        wpinv_v005_upgrades();
28
    }
29
30
    if ( version_compare( $wpi_version, '1.0.3', '<' ) ) {
31
        wpinv_v110_upgrades();
32
    }
33
34
    update_option( 'wpinv_version', WPINV_VERSION );
35
}
36
add_action( 'admin_init', 'wpinv_automatic_upgrade' );
37
38
function wpinv_v005_upgrades() {
39
    global $wpdb;
40
41
    // Invoices status
42
    $results = $wpdb->get_results( "SELECT ID FROM " . $wpdb->posts . " WHERE post_type = 'wpi_invoice' AND post_status IN( 'pending', 'processing', 'onhold', 'refunded', 'cancelled', 'failed', 'renewal' )" );
43
    if ( !empty( $results ) ) {
44
        $wpdb->query( "UPDATE " . $wpdb->posts . " SET post_status = CONCAT( 'wpi-', post_status ) WHERE post_type = 'wpi_invoice' AND post_status IN( 'pending', 'processing', 'onhold', 'refunded', 'cancelled', 'failed', 'renewal' )" );
45
46
        // Clean post cache
47
        foreach ( $results as $row ) {
48
            clean_post_cache( $row->ID );
49
        }
50
    }
51
52
    // Item meta key changes
53
    $query = "SELECT DISTINCT post_id FROM " . $wpdb->postmeta . " WHERE meta_key IN( '_wpinv_item_id', '_wpinv_package_id', '_wpinv_post_id', '_wpinv_cpt_name', '_wpinv_cpt_singular_name' )";
54
    $results = $wpdb->get_results( $query );
55
56
    if ( !empty( $results ) ) {
57
        $wpdb->query( "UPDATE " . $wpdb->postmeta . " SET meta_key = '_wpinv_custom_id' WHERE meta_key IN( '_wpinv_item_id', '_wpinv_package_id', '_wpinv_post_id' )" );
58
        $wpdb->query( "UPDATE " . $wpdb->postmeta . " SET meta_key = '_wpinv_custom_name' WHERE meta_key = '_wpinv_cpt_name'" );
59
        $wpdb->query( "UPDATE " . $wpdb->postmeta . " SET meta_key = '_wpinv_custom_singular_name' WHERE meta_key = '_wpinv_cpt_singular_name'" );
60
        
61
        foreach ( $results as $row ) {
62
            clean_post_cache( $row->post_id );
63
        }
64
    }
65
66
    wpinv_add_admin_caps();
67
}
68
69
function wpinv_v110_upgrades() {
70
    // Upgrade email settings
71
    wpinv_update_new_email_settings();
72
73
    // Add Subscription tables
74
    $db = new WPInv_Subscriptions_DB;
75
    /** @scrutinizer ignore-unhandled */ @$db->create_table();
0 ignored issues
show
Bug introduced by
Are you sure the usage of $db->create_table() targeting WPInv_Subscriptions_DB::create_table() 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...
76
77
    wpinv_convert_old_subscriptions();
78
}
79
80
function wpinv_convert_old_subscriptions() {
81
    global $wpdb;
82
83
    $query = "SELECT ". $wpdb->posts .".ID FROM ". $wpdb->posts ." INNER JOIN ". $wpdb->postmeta ." ON ( ". $wpdb->posts .".ID = ". $wpdb->postmeta .".post_id ) WHERE 1=1  AND ". $wpdb->postmeta .".meta_key = '_wpinv_subscr_status' AND (". $wpdb->postmeta .".meta_value = 'pending' OR ". $wpdb->postmeta .".meta_value = 'active' OR ". $wpdb->postmeta .".meta_value = 'cancelled' OR ". $wpdb->postmeta .".meta_value = 'completed' OR ". $wpdb->postmeta .".meta_value = 'expired' OR ". $wpdb->postmeta .".meta_value = 'trialling' OR ". $wpdb->postmeta .".meta_value = 'failing') AND ". $wpdb->posts .".post_type = 'wpi_invoice' GROUP BY ". $wpdb->posts .".ID ORDER BY ". $wpdb->posts .".ID ASC";
84
85
    $results = $wpdb->get_results( $query );
86
87
    if ( empty( $results ) ) {
88
        return;
89
    }
90
91
    foreach ( $results as $row ) {
92
        $invoice = new WPInv_Invoice( $row->ID );
93
94
        if ( empty( $invoice->ID ) ) {
95
            continue;
96
        }
97
98
        if ( $invoice->has_status( 'wpi-renewal' ) ) {
99
            continue;
100
        }
101
        
102
        $item = $invoice->get_recurring( true );
103
104
        if ( empty( $item ) ) {
105
            continue;
106
        }
107
108
        $is_free_trial          = $invoice->is_free_trial();
0 ignored issues
show
Unused Code introduced by
The assignment to $is_free_trial is dead and can be removed.
Loading history...
Deprecated Code introduced by
The function WPInv_Invoice::is_free_trial() 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

108
        $is_free_trial          = /** @scrutinizer ignore-deprecated */ $invoice->is_free_trial();
Loading history...
Bug introduced by
Are you sure the assignment to $is_free_trial is correct as $invoice->is_free_trial() targeting WPInv_Invoice::is_free_trial() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
109
        $profile_id             = get_post_meta( $invoice->ID, '_wpinv_subscr_profile_id', true );
110
        $subscription_status    = get_post_meta( $invoice->ID, '_wpinv_subscr_status', true );
111
        $transaction_id         = $invoice->get_transaction_id();
112
113
        // Last invoice
114
        $query          = "SELECT ID, post_date FROM ". $wpdb->posts ." WHERE post_type = 'wpi_invoice' AND post_parent = '" . $invoice->ID . "' ORDER BY ID DESC LIMIT 1";
115
        $last_payment   = $wpdb->get_row( $query );
116
117
        if ( !empty( $last_payment ) ) {
118
            $invoice_date       = $last_payment->post_date;
119
            
120
            $meta_profile_id     = get_post_meta( $last_payment->ID, '_wpinv_subscr_profile_id', true );
121
            $meta_transaction_id = get_post_meta( $last_payment->ID, '_wpinv_transaction_id', true );
122
123
            if ( !empty( $meta_profile_id ) ) {
124
                $profile_id  = $meta_profile_id;
125
            }
126
127
            if ( !empty( $meta_transaction_id ) ) {
128
                $transaction_id  = $meta_transaction_id;
129
            }
130
        } else {
131
            $invoice_date       = $invoice->get_invoice_date( false );
0 ignored issues
show
Deprecated Code introduced by
The function WPInv_Invoice::get_invoice_date() 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

131
            $invoice_date       = /** @scrutinizer ignore-deprecated */ $invoice->get_invoice_date( false );
Loading history...
132
        }
133
        
134
        $profile_id             = empty( $profile_id ) ? $invoice->ID : $profile_id;
135
        $status                 = empty( $subscription_status ) ? 'pending' : $subscription_status;
136
        
137
        $period                 = $item->get_recurring_period( true );
138
        $interval               = $item->get_recurring_interval();
139
        $bill_times             = (int)$item->get_recurring_limit();
140
        $add_period             = $interval . ' ' . $period;
141
        $trial_period           = '';
142
143
        if ( $invoice->is_free_trial() ) {
0 ignored issues
show
Deprecated Code introduced by
The function WPInv_Invoice::is_free_trial() 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

143
        if ( /** @scrutinizer ignore-deprecated */ $invoice->is_free_trial() ) {
Loading history...
Bug introduced by
Are you sure the usage of $invoice->is_free_trial() targeting WPInv_Invoice::is_free_trial() 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...
144
            $trial_period       = $item->get_trial_period( true );
145
            $free_interval      = $item->get_trial_interval();
146
            $trial_period       = $free_interval . ' ' . $trial_period;
147
148
            if ( empty( $last_payment ) ) {
149
                $add_period     = $trial_period;
150
            }
151
        }
152
153
        $expiration             = date_i18n( 'Y-m-d H:i:s', strtotime( '+' . $add_period  . ' 23:59:59', strtotime( $invoice_date ) ) );
154
        if ( strtotime( $expiration ) <  strtotime( date_i18n( 'Y-m-d' ) ) ) {
155
            if ( $status == 'active' || $status == 'trialling' || $status == 'pending' ) {
156
                $status = 'expired';
157
            }
158
        }
159
160
        $args = array(
161
            'product_id'        => $item->ID,
162
            'customer_id'       => $invoice->user_id,
0 ignored issues
show
Bug Best Practice introduced by
The property user_id does not exist on WPInv_Invoice. Since you implemented __get, consider adding a @property annotation.
Loading history...
163
            'parent_payment_id' => $invoice->ID,
164
            'status'            => $status,
165
            'frequency'         => $interval,
166
            'period'            => $period,
167
            'initial_amount'    => $invoice->get_total(),
168
            'recurring_amount'  => $invoice->get_recurring_details( 'total' ),
169
            'bill_times'        => $bill_times,
170
            'created'           => $invoice_date,
171
            'expiration'        => $expiration,
172
            'trial_period'      => $trial_period,
173
            'profile_id'        => $profile_id,
174
            'transaction_id'    => $transaction_id,
175
        );
176
177
        $subs_db      = new WPInv_Subscriptions_DB;
178
        $subs         = $subs_db->get_subscriptions( array( 'parent_payment_id' => $invoice->ID, 'number' => 1 ) );
179
        $subscription = reset( $subs );
180
181
        if ( empty( $subscription ) || $subscription->id <= 0 ) {
182
            $subscription = new WPInv_Subscription();
183
            $new_sub = $subscription->create( $args );
184
185
            if ( !empty( $bill_times ) && $new_sub->get_times_billed() >= $bill_times && ( 'active' == $new_sub->status || 'trialling' == $new_sub->status ) ) {
0 ignored issues
show
Bug introduced by
The method get_times_billed() does not exist on integer. ( Ignorable by Annotation )

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

185
            if ( !empty( $bill_times ) && $new_sub->/** @scrutinizer ignore-call */ get_times_billed() >= $bill_times && ( 'active' == $new_sub->status || 'trialling' == $new_sub->status ) ) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The property status does not exist on integer.
Loading history...
186
                $new_sub->complete(); // Mark completed if all times billed
187
            }
188
        }
189
    }
190
}
191
192
function wpinv_update_new_email_settings() {
193
    global $wpinv_options;
194
195
    $current_options = get_option( 'wpinv_settings', array() );
196
    $options = array(
197
        'email_new_invoice_body' => __( '<p>Hi Admin,</p><p>You have received payment invoice from {name}.</p>', 'invoicing' ),
198
        'email_cancelled_invoice_body' => __( '<p>Hi Admin,</p><p>The invoice #{invoice_number} from {site_title} has been cancelled.</p>', 'invoicing' ),
199
        'email_failed_invoice_body' => __( '<p>Hi Admin,</p><p>Payment for invoice #{invoice_number} from {site_title} has been failed.</p>', 'invoicing' ),
200
        'email_onhold_invoice_body' => __( '<p>Hi {name},</p><p>Your invoice is on-hold until we confirm your payment has been received.</p>', 'invoicing' ),
201
        'email_processing_invoice_body' => __( '<p>Hi {name},</p><p>Your invoice has been received at {site_title} and is now being processed.</p>', 'invoicing' ),
202
        'email_refunded_invoice_body' => __( '<p>Hi {name},</p><p>Your invoice on {site_title} has been refunded.</p>', 'invoicing' ),
203
        'email_user_invoice_body' => __( '<p>Hi {name},</p><p>An invoice has been created for you on {site_title}. To view / pay for this invoice please use the following link: <a class="btn btn-success" href="{invoice_link}">View / Pay</a></p>', 'invoicing' ),
204
        'email_user_note_body' => __( '<p>Hi {name},</p><p>Following note has been added to your {invoice_label}:</p><blockquote class="wpinv-note">{customer_note}</blockquote>', 'invoicing' ),
205
        'email_overdue_body' => __( '<p>Hi {full_name},</p><p>This is just a friendly reminder that your invoice <a href="{invoice_link}">#{invoice_number}</a> {is_was} due on {invoice_due_date}.</p><p>The total of this invoice is {invoice_total}</p><p>To view / pay now for this invoice please use the following link: <a class="btn btn-success" href="{invoice_link}">View / Pay</a></p>', 'invoicing' ),
206
    );
207
208
    foreach ($options as $option => $value){
209
        if (!isset($current_options[$option])) {
210
            $current_options[$option] = $value;
211
        }
212
    }
213
214
    $wpinv_options = $current_options;
215
216
    update_option( 'wpinv_settings', $current_options );
217
}
218
219
/**
220
 * Version 119 upgrades.
221
 */
222
function wpinv_v119_upgrades() {
223
    wpinv_create_invoices_table();
224
    wpinv_convert_old_invoices();
225
}
226
227
/**
228
 * Creates the invoices table.
229
 */
230
function wpinv_create_invoices_table() {
231
    global $wpdb;
232
233
    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
234
235
    // Create invoices table.
236
    $table = $wpdb->prefix . 'getpaid_invoices';
237
    $sql   = "CREATE TABLE $table (
238
239
            post_id BIGINT(20) NOT NULL,
240
            `number` VARCHAR(100),
241
            `key` VARCHAR(100),
242
            `type` VARCHAR(100) NOT NULL DEFAULT 'invoice',
243
            mode VARCHAR(100) NOT NULL DEFAULT 'live',
244
245
            user_ip VARCHAR(100),
246
            first_name VARCHAR(100),
247
            last_name VARCHAR(100),
248
            `address` VARCHAR(100),
249
            city VARCHAR(100),
250
            `state` VARCHAR(100),
251
            country VARCHAR(100),
252
            zip VARCHAR(100),
253
            adddress_confirmed INT(10),
254
255
            gateway VARCHAR(100),
256
            transaction_id VARCHAR(100),
257
            currency VARCHAR(10),
258
            subtotal FLOAT NOT NULL DEFAULT 0,
259
            tax FLOAT NOT NULL DEFAULT 0,
260
            fees_total FLOAT NOT NULL DEFAULT 0,
261
            total FLOAT NOT NULL DEFAULT 0,
262
            discount FLOAT NOT NULL DEFAULT 0,
263
            discount_code VARCHAR(100),
264
            disable_taxes INT(2) NOT NULL DEFAULT 0,
265
            due_date DATETIME,
266
            completed_date DATETIME,
267
            company VARCHAR(100),
268
            vat_number VARCHAR(100),
269
            vat_rate VARCHAR(100),
270
271
            custom_meta TEXT,
272
            PRIMARY KEY  (post_id),
273
            KEY number (number),
274
            KEY `key` ( `key` )
275
            ) CHARACTER SET utf8 COLLATE utf8_general_ci;";
276
277
    dbDelta( $sql );
278
279
    // Create invoice items table.
280
    $table = $wpdb->prefix . 'getpaid_invoice_items';
281
    $sql   = "CREATE TABLE $table (
282
            ID BIGINT(20) NOT NULL AUTO_INCREMENT,
283
            post_id BIGINT(20) NOT NULL,
284
285
            item_id BIGINT(20) NOT NULL,
286
            item_name TEXT NOT NULL,
287
            item_description TEXT NOT NULL,
288
289
            vat_rate FLOAT NOT NULL DEFAULT 0,
290
            vat_class VARCHAR(100),
291
            tax FLOAT NOT NULL DEFAULT 0,
292
            item_price FLOAT NOT NULL DEFAULT 0,
293
            custom_price FLOAT NOT NULL DEFAULT 0,
294
            quantity INT(20) NOT NULL DEFAULT 1,
295
            discount FLOAT NOT NULL DEFAULT 0,
296
            subtotal FLOAT NOT NULL DEFAULT 0,
297
            price FLOAT NOT NULL DEFAULT 0,
298
            meta TEXT,
299
            fees TEXT,
300
            PRIMARY KEY  (ID),
301
            KEY item_id (item_id),
302
            KEY post_id ( post_id )
303
            ) CHARACTER SET utf8 COLLATE utf8_general_ci;";
304
305
    dbDelta( $sql );
306
}
307
308
/**
309
 * Copies data from meta tables to our custom tables.
310
 */
311
function wpinv_convert_old_invoices() {
312
    global $wpdb;
313
314
    $invoices = array_unique(
315
        get_posts(
316
            array(
317
                'post_type'      => array( 'wpi_invoice', 'wpi_quote' ),
318
                'posts_per_page' => -1,
319
                'fields'         => 'ids',
320
                'post_status'    => array_keys( wpinv_get_invoice_statuses( true ) ),
321
            )
322
        )
323
    );
324
    $invoices_table = $wpdb->prefix . 'getpaid_invoices';
325
    $invoice_items_table = $wpdb->prefix . 'getpaid_invoice_items';
326
327
    if ( ! class_exists( 'WPInv_Legacy_Invoice' ) ) {
328
        require_once( WPINV_PLUGIN_DIR . 'includes/class-wpinv-legacy-invoice.php' );
329
    }
330
331
    $invoice_rows = array();
332
    foreach ( $invoices as $invoice ) {
333
334
        $invoice = new WPInv_Legacy_Invoice( $invoice );
335
        $fields = array (
336
            'post_id'        => $invoice->ID,
337
            'number'         => $invoice->get_number(),
338
            'key'            => $invoice->get_key(),
339
            'type'           => str_replace( 'wpi_', '', $invoice->post_type ),
340
            'mode'           => $invoice->mode,
341
            'user_ip'        => $invoice->get_ip(),
342
            'first_name'     => $invoice->get_first_name(),
343
            'last_name'      => $invoice->get_last_name(),
344
            'address'        => $invoice->get_address(),
345
            'city'           => $invoice->city,
346
            'state'          => $invoice->state,
347
            'country'        => $invoice->country,
348
            'zip'            => $invoice->zip,
349
            'adddress_confirmed' => (int) $invoice->adddress_confirmed,
350
            'gateway'        => $invoice->get_gateway(),
351
            'transaction_id' => $invoice->get_transaction_id(),
352
            'currency'       => $invoice->get_currency(),
353
            'subtotal'       => $invoice->get_subtotal(),
354
            'tax'            => $invoice->get_tax(),
355
            'fees_total'     => $invoice->get_fees_total(),
356
            'total'          => $invoice->get_total(),
357
            'discount'       => $invoice->get_discount(),
358
            'discount_code'  => $invoice->get_discount_code(),
359
            'disable_taxes'  => $invoice->disable_taxes,
360
            'due_date'       => $invoice->get_due_date(),
361
            'completed_date' => $invoice->get_completed_date(),
362
            'company'        => $invoice->company,
363
            'vat_number'     => $invoice->vat_number,
364
            'vat_rate'       => $invoice->vat_rate,
365
            'custom_meta'    => $invoice->payment_meta
366
        );
367
368
        foreach ( $fields as $key => $val ) {
369
            if ( is_null( $val ) ) {
370
                $val = '';
371
            }
372
            $val = maybe_serialize( $val );
373
            $fields[ $key ] = $wpdb->prepare( '%s', $val );
374
        }
375
376
        $fields = implode( ', ', $fields );
377
        $invoice_rows[] = "($fields)";
378
379
        $item_rows    = array();
380
        $item_columns = array();
381
        foreach ( $invoice->get_cart_details() as $details ) {
382
            $fields = array(
383
                'post_id'          => $invoice->ID,
384
                'item_id'          => $details['id'],
385
                'item_name'        => $details['name'],
386
                'item_description' => empty( $details['meta']['description'] ) ? '' : $details['meta']['description'],
387
                'vat_rate'         => $details['vat_rate'],
388
                'vat_class'        => empty( $details['vat_class'] ) ? '_standard' : $details['vat_class'],
389
                'tax'              => $details['tax'],
390
                'item_price'       => $details['item_price'],
391
                'custom_price'     => $details['custom_price'],
392
                'quantity'         => $details['quantity'],
393
                'discount'         => $details['discount'],
394
                'subtotal'         => $details['subtotal'],
395
                'price'            => $details['price'],
396
                'meta'             => $details['meta'],
397
                'fees'             => $details['fees'],
398
            );
399
400
            $item_columns = array_keys ( $fields );
401
402
            foreach ( $fields as $key => $val ) {
403
                if ( is_null( $val ) ) {
404
                    $val = '';
405
                }
406
                $val = maybe_serialize( $val );
407
                $fields[ $key ] = $wpdb->prepare( '%s', $val );
408
            }
409
410
            $fields = implode( ', ', $fields );
411
            $item_rows[] = "($fields)";
412
        }
413
414
        $item_rows    = implode( ', ', $item_rows );
415
        $item_columns = implode( ', ', $item_columns );
416
        $wpdb->query( "INSERT INTO $invoice_items_table ($item_columns) VALUES $item_rows" );
417
    }
418
419
    $invoice_rows = implode( ', ', $invoice_rows );
420
    $wpdb->query( "INSERT INTO $invoices_table VALUES $invoice_rows" );
421
422
}
423