Test Failed
Push — develop ( ab2157...9c62ca )
by Remco
04:09
created

Upgrade300::execute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 95
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 13
Bugs 0 Features 1
Metric Value
cc 1
eloc 15
c 13
b 0
f 1
nc 1
nop 0
dl 0
loc 95
rs 9.7666

How to fix   Long Method   

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 3.0.0
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2020 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay\Gateways\Mollie
9
 */
10
11
namespace Pronamic\WordPress\Pay\Gateways\Mollie;
12
13
use Pronamic\WordPress\Pay\Upgrades\Upgrade;
14
15
/**
16
 * Upgrade 3.0.0
17
 *
18
 * @author  Remco Tolsma
19
 * @version 3.0.0
20
 * @since   3.0.0
21
 */
22
class Upgrade300 extends Upgrade {
23
	/**
24
	 * Construct 3.0.0 upgrade.
25
	 */
26
	public function __construct() {
27
		parent::__construct( '3.0.7' );
28
	}
29
30
	/**
31
	 * Execute.
32
	 *
33
	 * @link https://github.com/WordPress/WordPress/blob/5.3/wp-includes/wp-db.php#L992-L1072
34
	 * @link https://github.com/WordPress/WordPress/blob/5.3/wp-admin/includes/schema.php#L25-L344
35
	 * @link https://developer.wordpress.org/reference/functions/dbdelta/
36
	 * @link https://github.com/wp-premium/gravityforms/blob/2.4.16/includes/class-gf-upgrade.php#L518-L531
37
	 * @throws \Exception Throws exception when database update query fails.
38
	 */
39
	public function execute() {
40
		global $wpdb;
41
42
		/**
43
		 * Requirements.
44
		 */
45
		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
46
47
		/**
48
		 * Table options.
49
		 *
50
		 * In MySQL 5.6, InnoDB is the default MySQL storage engine. Unless you
51
		 * have configured a different default storage engine,  issuing a
52
		 * CREATE TABLE statement without an ENGINE= clause creates an InnoDB
53
		 * table.
54
		 *
55
		 * @link https://dev.mysql.com/doc/refman/5.6/en/innodb-introduction.html
56
		 *
57
		 * If a storage engine is specified that is not available, MySQL uses
58
		 * the default engine instead. Normally, this is MyISAM. For example,
59
		 * if a table definition includes the ENGINE=INNODB option but the MySQL
60
		 * server does not support INNODB tables, the table is created as a
61
		 * MyISAM table.
62
		 *
63
		 * @link https://dev.mysql.com/doc/refman/5.6/en/create-table.html
64
		 */
65
		$table_options = 'ENGINE=InnoDB ' . $wpdb->get_charset_collate();
66
67
		/**
68
		 * Queries.
69
		 *
70
		 * @link https://github.com/WordPress/WordPress/blob/5.3/wp-admin/includes/schema.php
71
		 */
72
		$queries = "
73
			CREATE TABLE $wpdb->pronamic_pay_mollie_organizations (
74
				id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
75
				mollie_id varchar(16) NOT NULL,
76
				name varchar(128) DEFAULT NULL,
77
				email varchar(100) DEFAULT NULL,
78
				PRIMARY KEY  ( id ),
79
				UNIQUE KEY mollie_id ( mollie_id )
80
			) $table_options;
81
			CREATE TABLE $wpdb->pronamic_pay_mollie_profiles (
82
				id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
83
				mollie_id varchar(16) NOT NULL,
84
				organization_id bigint(20) unsigned DEFAULT NULL,
85
				name varchar(128) DEFAULT NULL,
86
				email varchar(100) DEFAULT NULL,
87
				api_key_test varchar(35) DEFAULT NULL,
88
				api_key_live varchar(35) DEFAULT NULL,
89
				PRIMARY KEY  ( id ),
90
				UNIQUE KEY mollie_id ( mollie_id ),
91
				KEY organization_id ( organization_id )
92
			) $table_options;
93
			CREATE TABLE $wpdb->pronamic_pay_mollie_customers (
94
				id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
95
				mollie_id varchar(16) NOT NULL,
96
				organization_id bigint(20) unsigned DEFAULT NULL,
97
				profile_id bigint(20) unsigned DEFAULT NULL,
98
				test_mode tinyint(1) NOT NULL,
99
				email varchar(100) DEFAULT NULL,
100
				name varchar(255) DEFAULT NULL,
101
				PRIMARY KEY  ( id ),
102
				UNIQUE KEY mollie_id ( mollie_id ),
103
				KEY organization_id ( organization_id ),
104
				KEY profile_id ( profile_id ),
105
				KEY test_mode ( test_mode ),
106
				KEY email ( email )
107
			) $table_options;
108
			CREATE TABLE $wpdb->pronamic_pay_mollie_customer_users (
109
				id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
110
				customer_id bigint(20) unsigned NOT NULL,
111
				user_id bigint(20) unsigned NOT NULL,
112
				PRIMARY KEY  ( id ),
113
				UNIQUE KEY customer_user ( customer_id, user_id )
114
			) $table_options;
115
		";
116
117
		/**
118
		 * Execute.
119
		 *
120
		 * @link https://developer.wordpress.org/reference/functions/dbdelta/
121
		 * @link https://github.com/WordPress/WordPress/blob/5.3/wp-admin/includes/upgrade.php#L2538-L2915
122
		 */
123
		\dbDelta( $queries );
124
125
		/**
126
		 * Add foreign keys.
127
		 */
128
		$this->add_foreign_keys();
129
130
		/**
131
		 * Convert user meta.
132
		 */
133
		$this->convert_user_meta();
134
	}
135
136
	/**
137
	 * Add foreign keys.
138
	 *
139
	 * @t
140
	 */
141
	private function add_foreign_keys() {
142
		global $wpdb;
143
144
		/**
145
		 * Foreign keys.
146
		 *
147
		 * @link https://core.trac.wordpress.org/ticket/19207
148
		 * @link https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
149
		 */
150
		$data = array(
151
			(object) array(
152
				'table' => $wpdb->pronamic_pay_mollie_profiles,
153
				'name'  => 'fk_profile_organization_id',
154
				'query' => "
155
					ALTER TABLE  $wpdb->pronamic_pay_mollie_profiles
156
					ADD CONSTRAINT fk_profile_organization_id
157
					FOREIGN KEY ( organization_id )
158
					REFERENCES $wpdb->pronamic_pay_mollie_organizations ( id )
159
					ON DELETE RESTRICT
160
					ON UPDATE RESTRICT
161
					;
162
				",
163
			),
164
			(object) array(
165
				'table' => $wpdb->pronamic_pay_mollie_customers,
166
				'name'  => 'fk_customer_organization_id',
167
				'query' => "
168
					ALTER TABLE $wpdb->pronamic_pay_mollie_customers
169
					ADD CONSTRAINT fk_customer_organization_id
170
					FOREIGN KEY ( organization_id )
171
					REFERENCES $wpdb->pronamic_pay_mollie_organizations ( id )
172
					ON DELETE RESTRICT
173
					ON UPDATE RESTRICT
174
					;
175
				",
176
			),
177
			(object) array(
178
				'table' => $wpdb->pronamic_pay_mollie_customers,
179
				'name'  => 'fk_customer_profile_id',
180
				'query' => "
181
					ALTER TABLE $wpdb->pronamic_pay_mollie_customers
182
					ADD CONSTRAINT fk_customer_profile_id
183
					FOREIGN KEY ( profile_id )
184
					REFERENCES $wpdb->pronamic_pay_mollie_profiles ( id )
185
					ON DELETE RESTRICT
186
					ON UPDATE RESTRICT
187
					;
188
				",
189
			),
190
			(object) array(
191
				'table' => $wpdb->pronamic_pay_mollie_customer_users,
192
				'name'  => 'fk_customer_id',
193
				'query' => "
194
					ALTER TABLE $wpdb->pronamic_pay_mollie_customer_users
195
					ADD CONSTRAINT fk_customer_id
196
					FOREIGN KEY customer_id ( customer_id )
197
					REFERENCES $wpdb->pronamic_pay_mollie_customers ( id )
198
					ON DELETE RESTRICT
199
					ON UPDATE RESTRICT
200
					;
201
				",
202
			),
203
			(object) array(
204
				'table' => $wpdb->pronamic_pay_mollie_customer_users,
205
				'name'  => 'fk_customer_user_id',
206
				'query' => "
207
					ALTER TABLE $wpdb->pronamic_pay_mollie_customer_users
208
					ADD CONSTRAINT fk_customer_user_id
209
					FOREIGN KEY user_id ( user_id )
210
					REFERENCES $wpdb->users ( id )
211
					ON DELETE CASCADE
212
					ON UPDATE CASCADE
213
					;
214
				",
215
			),
216
		);
217
218
		foreach ( $data as $item ) {
219
			try {
220
				$this->add_foreign_key( $item );
221
			} catch ( \Exception $e ) {
222
				// Foreign keys are not strictly required.
223
				continue;
224
			}
225
		}
226
	}
227
228
	/**
229
	 * Add specified foreign key.
230
	 *
231
	 * @param object $item Foreig key data.
232
	 * @throws \Exception Throws exception when adding foreign key fails.
233
	 */
234
	private function add_foreign_key( $item ) {
235
		global $wpdb;
236
237
		/**
238
		 * Check if foreign key exists
239
		 *
240
		 * @link https://github.com/woocommerce/woocommerce/blob/3.9.0/includes/class-wc-install.php#L663-L681
241
		 */
242
		$result = $wpdb->get_var(
243
			$wpdb->prepare(
244
				"
245
			SELECT COUNT(*)
246
			FROM information_schema.TABLE_CONSTRAINTS
247
			WHERE CONSTRAINT_SCHEMA = %s
248
			AND CONSTRAINT_NAME = %s
249
			AND CONSTRAINT_TYPE = 'FOREIGN KEY'
250
			AND TABLE_NAME = %s
251
			",
252
				$wpdb->dbname,
253
				$item->name,
254
				$item->table
255
			)
256
		);
257
258
		if ( null === $result ) {
259
			throw new \Exception(
260
				\sprintf(
261
					'Could not count foreign keys: %s, database error: %s.',
262
					$item->name,
263
					$wpdb->last_error
264
				)
265
			);
266
		}
267
268
		$number_constraints = \intval( $result );
269
270
		if ( 0 === $number_constraints ) {
271
			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is prepared.
272
			$result = $wpdb->query( $item->query );
273
274
			if ( false === $result ) {
275
				throw new \Exception(
276
					\sprintf(
277
						'Could not add foreign key: %s, database error: %s.',
278
						$item->name,
279
						$wpdb->last_error
280
					)
281
				);
282
			}
283
		}
284
	}
285
286
	/**
287
	 * Convert user meta.
288
	 *
289
	 * @throws \Exception Throws exception when database update query fails.
290
	 */
291
	private function convert_user_meta() {
292
		global $wpdb;
293
294
		$query = "
295
			INSERT IGNORE INTO $wpdb->pronamic_pay_mollie_customers (
296
				mollie_id,
297
				test_mode
298
			)
299
			SELECT
300
				meta_value AS mollie_id,
301
				'_pronamic_pay_mollie_customer_id_test' = meta_key AS test_mode
302
			FROM
303
				$wpdb->usermeta
304
			WHERE
305
				meta_key IN (
306
					'_pronamic_pay_mollie_customer_id',
307
					'_pronamic_pay_mollie_customer_id_test'
308
				)
309
					AND
310
				meta_value != ''
311
			;
312
		";
313
314
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is prepared.
315
		$result = $wpdb->query( $query );
316
317
		if ( false === $result ) {
318
			throw new Exception(
0 ignored issues
show
Bug introduced by
The type Pronamic\WordPress\Pay\Gateways\Mollie\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
319
				sprintf(
320
					'Could not convert user meta, database error: %s.',
321
					$wpdb->last_error
322
				)
323
			);
324
		}
325
326
		$query = "
327
			INSERT IGNORE INTO $wpdb->pronamic_pay_mollie_customer_users (
328
				customer_id,
329
				user_id
330
			)
331
			SELECT
332
				mollie_customer.id AS mollie_customer_id,
333
				wp_user.ID AS wp_user_id
334
			FROM
335
				$wpdb->pronamic_pay_mollie_customers AS mollie_customer
336
					INNER JOIN
337
				$wpdb->usermeta AS wp_user_meta
338
						ON wp_user_meta.meta_value = mollie_customer.mollie_id
339
					INNER JOIN
340
				$wpdb->users AS wp_user
341
						ON wp_user_meta.user_id = wp_user.ID
342
			WHERE
343
				wp_user_meta.meta_key IN (
344
					'_pronamic_pay_mollie_customer_id',
345
					'_pronamic_pay_mollie_customer_id_test'
346
				)
347
					AND
348
				wp_user_meta.meta_value != ''
349
			;
350
		";
351
352
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is prepared.
353
		$result = $wpdb->query( $query );
354
355
		if ( false === $result ) {
356
			throw new Exception(
357
				sprintf(
358
					'Could not convert user meta, database error: %s.',
359
					$wpdb->last_error
360
				)
361
			);
362
		}
363
	}
364
}
365