Completed
Push — master ( 56a28f...6a5a36 )
by Brian
11:33
created

GetPaid_Installer   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 493
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 192
dl 0
loc 493
rs 9.68
c 1
b 0
f 0
wmc 34

15 Methods

Rating   Name   Duplication   Size   Complexity  
A upgrade_from_0() 0 7 1
A upgrade_db() 0 31 3
A upgrade_from_118() 0 4 1
A upgrade_from_004() 0 29 5
A upgrade_from_102() 0 3 1
A create_invoices_table() 0 44 1
A rename_gateways_label() 0 11 2
C migrate_old_invoices() 0 124 12
A get_pages() 0 60 1
A create_subscriptions_table() 0 32 1
A add_capabilities() 0 2 1
A upgrade_from_207() 0 4 1
A create_invoice_items_table() 0 30 1
A upgrade_from_2615() 0 4 1
A create_pages() 0 4 2
1
<?php
2
/**
3
 * Contains the main installer class.
4
 *
5
 * @package GetPaid
6
 * @subpackage Admin
7
 * @version 2.0.2
8
 * @since   2.0.2
9
 */
10
11
defined( 'ABSPATH' ) || exit;
12
13
/**
14
 * The main installer/updater class.
15
 *
16
 * @package GetPaid
17
 * @subpackage Admin
18
 * @version 2.0.2
19
 * @since   2.0.2
20
 */
21
class GetPaid_Installer {
22
23
	/**
24
	 * Upgrades the install.
25
	 *
26
	 * @param string $upgrade_from The current invoicing version.
27
	 */
28
	public function upgrade_db( $upgrade_from ) {
29
30
		// Save the current invoicing version.
31
		update_option( 'wpinv_version', WPINV_VERSION );
32
33
		// Setup the invoice Custom Post Type.
34
		GetPaid_Post_Types::register_post_types();
35
36
		// Clear the permalinks
37
		flush_rewrite_rules();
38
39
		// Maybe create new/missing pages.
40
		$this->create_pages();
41
42
		// Maybe re(add) admin capabilities.
43
		$this->add_capabilities();
44
45
		// Maybe create the default payment form.
46
		wpinv_get_default_payment_form();
47
48
		// Create any missing database tables.
49
		$method = "upgrade_from_$upgrade_from";
50
51
		$installed = get_option( 'gepaid_installed_on' );
52
53
		if ( empty( $installed ) ) {
54
			update_option( 'gepaid_installed_on', time() );
55
		}
56
57
		if ( method_exists( $this, $method ) ) {
58
			$this->$method();
59
		}
60
61
	}
62
63
	/**
64
	 * Do a fresh install.
65
	 *
66
	 */
67
	public function upgrade_from_0() {
68
		$this->create_subscriptions_table();
69
		$this->create_invoices_table();
70
		$this->create_invoice_items_table();
71
72
		// Save default tax rates.
73
		update_option( 'wpinv_tax_rates', wpinv_get_data( 'tax-rates' ) );
74
	}
75
76
	/**
77
	 * Upgrade to 0.0.5
78
	 *
79
	 */
80
	public function upgrade_from_004() {
81
		global $wpdb;
82
83
		// Invoices.
84
		$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' )" );
85
		if ( ! empty( $results ) ) {
86
			$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' )" );
87
88
			// Clean post cache
89
			foreach ( $results as $row ) {
90
				clean_post_cache( $row->ID );
91
			}
92
		}
93
94
		// Item meta key changes
95
		$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' )";
96
		$results = $wpdb->get_results( $query );
97
98
		if ( ! empty( $results ) ) {
99
			$wpdb->query( 'UPDATE ' . $wpdb->postmeta . " SET meta_key = '_wpinv_custom_id' WHERE meta_key IN( '_wpinv_item_id', '_wpinv_package_id', '_wpinv_post_id' )" );
100
			$wpdb->query( 'UPDATE ' . $wpdb->postmeta . " SET meta_key = '_wpinv_custom_name' WHERE meta_key = '_wpinv_cpt_name'" );
101
			$wpdb->query( 'UPDATE ' . $wpdb->postmeta . " SET meta_key = '_wpinv_custom_singular_name' WHERE meta_key = '_wpinv_cpt_singular_name'" );
102
103
			foreach ( $results as $row ) {
104
				clean_post_cache( $row->post_id );
105
			}
106
		}
107
108
		$this->upgrade_from_102();
109
	}
110
111
	/**
112
	 * Upgrade to 1.0.3
113
	 *
114
	 */
115
	public function upgrade_from_102() {
116
		$this->create_subscriptions_table();
117
		$this->upgrade_from_118();
118
	}
119
120
	/**
121
	 * Upgrade to version 2.0.0.
122
	 *
123
	 */
124
	public function upgrade_from_118() {
125
		$this->create_invoices_table();
126
		$this->create_invoice_items_table();
127
		$this->migrate_old_invoices();
128
	}
129
130
	/**
131
	 * Upgrade to version 2.0.8.
132
	 *
133
	 */
134
	public function upgrade_from_207() {
135
		global $wpdb;
136
		$wpdb->query( "ALTER TABLE {$wpdb->prefix}getpaid_invoice_items MODIFY COLUMN quantity FLOAT(20);" );
137
		$this->upgrade_from_2615();
138
	}
139
140
	/**
141
	 * Upgrade to version 2.6.16.
142
	 *
143
	 */
144
	public function upgrade_from_2615() {
145
		global $wpdb;
146
		$wpdb->query( "ALTER TABLE {$wpdb->prefix}getpaid_invoice_items MODIFY COLUMN item_price DECIMAL(16,4) NOT NULL DEFAULT '0', MODIFY custom_price DECIMAL(16,4) NOT NULL DEFAULT '0', MODIFY discount DECIMAL(16,4) NOT NULL DEFAULT '0', MODIFY subtotal DECIMAL(16,4) NOT NULL DEFAULT '0', MODIFY price DECIMAL(16,4) NOT NULL DEFAULT '0';" );
147
		$wpdb->query( "ALTER TABLE {$wpdb->prefix}_getpaid_invoices MODIFY COLUMN subtotal DECIMAL(16,4) NOT NULL DEFAULT '0', MODIFY tax DECIMAL(16,4) NOT NULL DEFAULT '0', MODIFY fees_total DECIMAL(16,4) NOT NULL DEFAULT '0', MODIFY total DECIMAL(16,4) NOT NULL DEFAULT '0', MODIFY discount DECIMAL(16,4) NOT NULL DEFAULT '0';" );
148
	}
149
150
	/**
151
	 * Give administrators the capability to manage GetPaid.
152
	 *
153
	 */
154
	public function add_capabilities() {
155
		$GLOBALS['wp_roles']->add_cap( 'administrator', 'manage_invoicing' );
156
	}
157
158
	/**
159
	 * Retreives GetPaid pages.
160
	 *
161
	 */
162
	public static function get_pages() {
163
164
		return apply_filters(
165
			'wpinv_create_pages',
166
			array(
167
168
				// Checkout page.
169
				'checkout_page'             => array(
170
					'name'    => _x( 'gp-checkout', 'Page slug', 'invoicing' ),
171
					'title'   => _x( 'Checkout', 'Page title', 'invoicing' ),
172
					'content' => '
173
						<!-- wp:shortcode -->
174
						[wpinv_checkout]
175
						<!-- /wp:shortcode -->
176
					',
177
					'parent'  => '',
178
				),
179
180
				// Invoice history page.
181
				'invoice_history_page'      => array(
182
					'name'    => _x( 'gp-invoices', 'Page slug', 'invoicing' ),
183
					'title'   => _x( 'My Invoices', 'Page title', 'invoicing' ),
184
					'content' => '
185
					<!-- wp:shortcode -->
186
					[wpinv_history]
187
					<!-- /wp:shortcode -->
188
				',
189
					'parent'  => '',
190
				),
191
192
				// Success page content.
193
				'success_page'              => array(
194
					'name'    => _x( 'gp-receipt', 'Page slug', 'invoicing' ),
195
					'title'   => _x( 'Payment Confirmation', 'Page title', 'invoicing' ),
196
					'content' => '
197
					<!-- wp:shortcode -->
198
					[wpinv_receipt]
199
					<!-- /wp:shortcode -->
200
				',
201
					'parent'  => 'gp-checkout',
202
				),
203
204
				// Failure page content.
205
				'failure_page'              => array(
206
					'name'    => _x( 'gp-transaction-failed', 'Page slug', 'invoicing' ),
207
					'title'   => _x( 'Transaction Failed', 'Page title', 'invoicing' ),
208
					'content' => __( 'Your transaction failed, please try again or contact site support.', 'invoicing' ),
209
					'parent'  => 'gp-checkout',
210
				),
211
212
				// Subscriptions history page.
213
				'invoice_subscription_page' => array(
214
					'name'    => _x( 'gp-subscriptions', 'Page slug', 'invoicing' ),
215
					'title'   => _x( 'My Subscriptions', 'Page title', 'invoicing' ),
216
					'content' => '
217
					<!-- wp:shortcode -->
218
					[wpinv_subscriptions]
219
					<!-- /wp:shortcode -->
220
				',
221
					'parent'  => '',
222
				),
223
224
			)
225
		);
226
227
	}
228
229
	/**
230
	 * Re-create GetPaid pages.
231
	 *
232
	 */
233
	public function create_pages() {
234
235
		foreach ( self::get_pages() as $key => $page ) {
236
			wpinv_create_page( esc_sql( $page['name'] ), $key, $page['title'], $page['content'], $page['parent'] );
237
		}
238
239
	}
240
241
	/**
242
	 * Create subscriptions table.
243
	 *
244
	 */
245
	public function create_subscriptions_table() {
246
247
		global $wpdb;
248
249
		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
250
251
		// Create tables.
252
		$charset_collate = $wpdb->get_charset_collate();
253
		$sql             = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}wpinv_subscriptions (
254
			id bigint(20) unsigned NOT NULL auto_increment,
255
			customer_id bigint(20) NOT NULL,
256
			frequency int(11) NOT NULL DEFAULT '1',
257
			period varchar(20) NOT NULL,
258
			initial_amount DECIMAL(16,4) NOT NULL,
259
			recurring_amount DECIMAL(16,4) NOT NULL,
260
			bill_times bigint(20) NOT NULL,
261
			transaction_id varchar(60) NOT NULL,
262
			parent_payment_id bigint(20) NOT NULL,
263
			product_id bigint(20) NOT NULL,
264
			created datetime NOT NULL,
265
			expiration datetime NOT NULL,
266
			trial_period varchar(20) NOT NULL,
267
			profile_id varchar(60) NOT NULL,
268
			status varchar(20) NOT NULL,
269
			PRIMARY KEY  (id),
270
			KEY profile_id (profile_id),
271
			KEY customer (customer_id),
272
			KEY transaction (transaction_id),
273
			KEY customer_and_status (customer_id, status)
274
		  ) $charset_collate;";
275
276
		dbDelta( $sql );
277
278
	}
279
280
	/**
281
	 * Create invoices table.
282
	 *
283
	 */
284
	public function create_invoices_table() {
285
		global $wpdb;
286
287
		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
288
289
		// Create tables.
290
		$charset_collate = $wpdb->get_charset_collate();
291
		$sql             = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}getpaid_invoices (
292
			post_id BIGINT(20) NOT NULL,
293
            `number` VARCHAR(100),
294
            `key` VARCHAR(100),
295
            `type` VARCHAR(100) NOT NULL DEFAULT 'invoice',
296
            mode VARCHAR(100) NOT NULL DEFAULT 'live',
297
            user_ip VARCHAR(100),
298
            first_name VARCHAR(100),
299
            last_name VARCHAR(100),
300
            `address` VARCHAR(100),
301
            city VARCHAR(100),
302
            `state` VARCHAR(100),
303
            country VARCHAR(100),
304
            zip VARCHAR(100),
305
            adddress_confirmed INT(10),
306
            gateway VARCHAR(100),
307
            transaction_id VARCHAR(100),
308
            currency VARCHAR(10),
309
            subtotal DECIMAL(16,4) NOT NULL DEFAULT 0,
310
            tax DECIMAL(16,4) NOT NULL DEFAULT 0,
311
            fees_total DECIMAL(16,4) NOT NULL DEFAULT 0,
312
            total DECIMAL(16,4) NOT NULL DEFAULT 0,
313
            discount DECIMAL(16,4) NOT NULL DEFAULT 0,
314
            discount_code VARCHAR(100),
315
            disable_taxes INT(2) NOT NULL DEFAULT 0,
316
            due_date DATETIME,
317
            completed_date DATETIME,
318
            company VARCHAR(100),
319
            vat_number VARCHAR(100),
320
            vat_rate VARCHAR(100),
321
            custom_meta TEXT,
322
			PRIMARY KEY  (post_id),
323
			KEY number (number),
324
			KEY `key` (`key`)
325
		  ) $charset_collate;";
326
327
		dbDelta( $sql );
328
329
	}
330
331
	/**
332
	 * Create invoice items table.
333
	 *
334
	 */
335
	public function create_invoice_items_table() {
336
		global $wpdb;
337
338
		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
339
340
		// Create tables.
341
		$charset_collate = $wpdb->get_charset_collate();
342
		$sql             = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}getpaid_invoice_items (
343
			ID BIGINT(20) NOT NULL AUTO_INCREMENT,
344
            post_id BIGINT(20) NOT NULL,
345
            item_id BIGINT(20) NOT NULL,
346
            item_name TEXT NOT NULL,
347
            item_description TEXT NOT NULL,
348
            vat_rate FLOAT NOT NULL DEFAULT 0,
349
            vat_class VARCHAR(100),
350
            tax DECIMAL(16,4) NOT NULL DEFAULT 0,
351
            item_price DECIMAL(16,4) NOT NULL DEFAULT 0,
352
            custom_price DECIMAL(16,4) NOT NULL DEFAULT 0,
353
            quantity FLOAT NOT NULL DEFAULT 1,
354
            discount DECIMAL(16,4) NOT NULL DEFAULT 0,
355
            subtotal DECIMAL(16,4) NOT NULL DEFAULT 0,
356
            price DECIMAL(16,4) NOT NULL DEFAULT 0,
357
            meta TEXT,
358
            fees TEXT,
359
			PRIMARY KEY  (ID),
360
			KEY item_id (item_id),
361
			KEY post_id (post_id)
362
		  ) $charset_collate;";
363
364
		dbDelta( $sql );
365
366
	}
367
368
	/**
369
	 * Migrates old invoices to new invoices.
370
	 *
371
	 */
372
	public function migrate_old_invoices() {
373
		global $wpdb;
374
375
		$invoices_table      = $wpdb->prefix . 'getpaid_invoices';
376
		$invoice_items_table = $wpdb->prefix . 'getpaid_invoice_items';
377
		$migrated            = $wpdb->get_col( "SELECT post_id FROM $invoices_table" );
378
		$invoices            = array_unique(
379
			get_posts(
380
				array(
381
					'post_type'      => array( 'wpi_invoice', 'wpi_quote' ),
382
					'posts_per_page' => -1,
383
					'fields'         => 'ids',
384
					'post_status'    => array_keys( get_post_stati() ),
385
					'exclude'        => (array) $migrated,
386
				)
387
			)
388
		);
389
390
		// Abort if we do not have any invoices.
391
		if ( empty( $invoices ) ) {
392
			return;
393
		}
394
395
		require_once WPINV_PLUGIN_DIR . 'includes/class-wpinv-legacy-invoice.php';
396
397
		$invoice_rows = array();
398
		foreach ( $invoices as $invoice ) {
399
400
			$invoice = new WPInv_Legacy_Invoice( $invoice );
401
402
			if ( empty( $invoice->ID ) ) {
403
				return;
404
			}
405
406
			$fields = array(
407
				'post_id'            => $invoice->ID,
408
				'number'             => $invoice->get_number(),
409
				'key'                => $invoice->get_key(),
410
				'type'               => str_replace( 'wpi_', '', $invoice->post_type ),
411
				'mode'               => $invoice->mode,
412
				'user_ip'            => $invoice->get_ip(),
413
				'first_name'         => $invoice->get_first_name(),
414
				'last_name'          => $invoice->get_last_name(),
415
				'address'            => $invoice->get_address(),
416
				'city'               => $invoice->city,
417
				'state'              => $invoice->state,
418
				'country'            => $invoice->country,
419
				'zip'                => $invoice->zip,
420
				'adddress_confirmed' => (int) $invoice->adddress_confirmed,
421
				'gateway'            => $invoice->get_gateway(),
422
				'transaction_id'     => $invoice->get_transaction_id(),
423
				'currency'           => $invoice->get_currency(),
424
				'subtotal'           => $invoice->get_subtotal(),
425
				'tax'                => $invoice->get_tax(),
426
				'fees_total'         => $invoice->get_fees_total(),
427
				'total'              => $invoice->get_total(),
428
				'discount'           => $invoice->get_discount(),
429
				'discount_code'      => $invoice->get_discount_code(),
430
				'disable_taxes'      => $invoice->disable_taxes,
431
				'due_date'           => $invoice->get_due_date(),
432
				'completed_date'     => $invoice->get_completed_date(),
433
				'company'            => $invoice->company,
434
				'vat_number'         => $invoice->vat_number,
435
				'vat_rate'           => $invoice->vat_rate,
436
				'custom_meta'        => $invoice->payment_meta,
437
			);
438
439
			foreach ( $fields as $key => $val ) {
440
				if ( is_null( $val ) ) {
441
					$val = '';
442
				}
443
				$val = maybe_serialize( $val );
444
				$fields[ $key ] = $wpdb->prepare( '%s', $val );
445
			}
446
447
			$fields = implode( ', ', $fields );
448
			$invoice_rows[] = "($fields)";
449
450
			$item_rows    = array();
451
			$item_columns = array();
452
			foreach ( $invoice->get_cart_details() as $details ) {
453
				$fields = array(
454
					'post_id'          => $invoice->ID,
455
					'item_id'          => $details['id'],
456
					'item_name'        => $details['name'],
457
					'item_description' => empty( $details['meta']['description'] ) ? '' : $details['meta']['description'],
458
					'vat_rate'         => $details['vat_rate'],
459
					'vat_class'        => empty( $details['vat_class'] ) ? '_standard' : $details['vat_class'],
460
					'tax'              => $details['tax'],
461
					'item_price'       => $details['item_price'],
462
					'custom_price'     => $details['custom_price'],
463
					'quantity'         => $details['quantity'],
464
					'discount'         => $details['discount'],
465
					'subtotal'         => $details['subtotal'],
466
					'price'            => $details['price'],
467
					'meta'             => $details['meta'],
468
					'fees'             => $details['fees'],
469
				);
470
471
				$item_columns = array_keys( $fields );
472
473
				foreach ( $fields as $key => $val ) {
474
					if ( is_null( $val ) ) {
475
						$val = '';
476
					}
477
					$val = maybe_serialize( $val );
478
					$fields[ $key ] = $wpdb->prepare( '%s', $val );
479
				}
480
481
				$fields = implode( ', ', $fields );
482
				$item_rows[] = "($fields)";
483
			}
484
485
			$item_rows    = implode( ', ', $item_rows );
486
			$item_columns = implode( ', ', $item_columns );
487
			$wpdb->query( "INSERT INTO $invoice_items_table ($item_columns) VALUES $item_rows" );
488
		}
489
490
		if ( empty( $invoice_rows ) ) {
491
			return;
492
		}
493
494
		$invoice_rows = implode( ', ', $invoice_rows );
495
		$wpdb->query( "INSERT INTO $invoices_table VALUES $invoice_rows" );
496
497
	}
498
499
	/**
500
	 * Migrates old invoices to new invoices.
501
	 *
502
	 */
503
	public static function rename_gateways_label() {
504
		global $wpdb;
505
506
		foreach ( array_keys( wpinv_get_payment_gateways() ) as $gateway ) {
507
508
			$wpdb->update(
509
				$wpdb->prefix . 'getpaid_invoices',
510
				array( 'gateway' => $gateway ),
511
				array( 'gateway' => wpinv_get_gateway_admin_label( $gateway ) ),
512
				'%s',
513
				'%s'
514
			);
515
516
		}
517
	}
518
519
}
520