PodsUpgrade_2_0_0   D
last analyzed

Complexity

Total Complexity 142

Size/Duplication

Total Lines 1066
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 1066
rs 4.4212
c 0
b 0
f 0
wmc 142
lcom 1
cbo 5

21 Methods

Rating   Name   Duplication   Size   Complexity  
C prepare_pod() 0 67 13
B migrate_1_x() 0 23 5
B migrate_fields() 0 36 5
A migrate_settings() 0 4 1
C migrate_roles() 0 68 14
B migrate_templates() 0 22 4
A migrate_pages() 0 20 4
B migrate_helpers() 0 32 6
A prepare_pods() 0 21 3
A prepare_fields() 0 21 3
A prepare_relationships() 0 21 3
A prepare_index() 0 21 3
A prepare_templates() 0 21 3
A prepare_pages() 0 21 3
A prepare_helpers() 0 21 3
D migrate_pods() 0 223 27
D migrate_relationships() 0 173 22
C migrate_pod() 0 99 12
A migrate_cleanup() 0 12 1
A restart() 0 17 3
B cleanup() 0 28 4

How to fix   Complexity   

Complex Class

Complex classes like PodsUpgrade_2_0_0 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PodsUpgrade_2_0_0, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * @package Pods\Upgrade
5
 */
6
class PodsUpgrade_2_0_0 extends PodsUpgrade {
7
8
	/**
9
	 * @var string
10
	 */
11
	protected $version = '2.0.0';
12
13
	/**
14
	 * @return array|bool|int|mixed|null|void
15
	 */
16
	public function prepare_pods() {
17
18
		/**
19
		 * @var $wpdb WPDB
20
		 */
21
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
22
23
		if ( ! in_array( "{$wpdb->prefix}pod_types", $this->tables, true ) ) {
24
			return pods_error( __( 'Table not found, it cannot be migrated', 'pods' ) );
25
		}
26
27
		$count = pods_query( 'SELECT COUNT(*) AS `count` FROM `@wp_pod_types`', false );
28
29
		if ( ! empty( $count ) ) {
30
			$count = (int) $count[0]->count;
31
		} else {
32
			$count = 0;
33
		}
34
35
		return $count;
36
	}
37
38
	/**
39
	 * @return array|bool|int|mixed|null|void
40
	 */
41
	public function prepare_fields() {
42
43
		/**
44
		 * @var $wpdb WPDB
45
		 */
46
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
47
48
		if ( ! in_array( "{$wpdb->prefix}pod_fields", $this->tables, true ) ) {
49
			return pods_error( __( 'Table not found, it cannot be migrated', 'pods' ) );
50
		}
51
52
		$count = pods_query( 'SELECT COUNT(*) AS `count` FROM `@wp_pod_fields`', false );
53
54
		if ( ! empty( $count ) ) {
55
			$count = (int) $count[0]->count;
56
		} else {
57
			$count = 0;
58
		}
59
60
		return $count;
61
	}
62
63
	/**
64
	 * @return array|bool|int|mixed|null|void
65
	 */
66
	public function prepare_relationships() {
67
68
		/**
69
		 * @var $wpdb WPDB
70
		 */
71
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
72
73
		if ( ! in_array( "{$wpdb->prefix}pod_rel", $this->tables, true ) ) {
74
			return pods_error( __( 'Table not found, it cannot be migrated', 'pods' ) );
75
		}
76
77
		$count = pods_query( 'SELECT COUNT(*) AS `count` FROM `@wp_pod_rel`', false );
78
79
		if ( ! empty( $count ) ) {
80
			$count = (int) $count[0]->count;
81
		} else {
82
			$count = 0;
83
		}
84
85
		return $count;
86
	}
87
88
	/**
89
	 * @return array|bool|int|mixed|null|void
90
	 */
91
	public function prepare_index() {
92
93
		/**
94
		 * @var $wpdb WPDB
95
		 */
96
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
97
98
		if ( ! in_array( "{$wpdb->prefix}pod", $this->tables, true ) ) {
99
			return pods_error( __( 'Table not found, it cannot be migrated', 'pods' ) );
100
		}
101
102
		$count = pods_query( 'SELECT COUNT(*) AS `count` FROM `@wp_pod`', false );
103
104
		if ( ! empty( $count ) ) {
105
			$count = (int) $count[0]->count;
106
		} else {
107
			$count = 0;
108
		}
109
110
		return $count;
111
	}
112
113
	/**
114
	 * @return array|bool|int|mixed|null|void
115
	 */
116
	public function prepare_templates() {
117
118
		/**
119
		 * @var $wpdb WPDB
120
		 */
121
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
122
123
		if ( ! in_array( "{$wpdb->prefix}pod_templates", $this->tables, true ) ) {
124
			return pods_error( __( 'Table not found, it cannot be migrated', 'pods' ) );
125
		}
126
127
		$count = pods_query( 'SELECT COUNT(*) AS `count` FROM `@wp_pod_templates`', false );
128
129
		if ( ! empty( $count ) ) {
130
			$count = (int) $count[0]->count;
131
		} else {
132
			$count = 0;
133
		}
134
135
		return $count;
136
	}
137
138
	/**
139
	 * @return array|bool|int|mixed|null|void
140
	 */
141
	public function prepare_pages() {
142
143
		/**
144
		 * @var $wpdb WPDB
145
		 */
146
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
147
148
		if ( ! in_array( "{$wpdb->prefix}pod_pages", $this->tables, true ) ) {
149
			return pods_error( __( 'Table not found, it cannot be migrated', 'pods' ) );
150
		}
151
152
		$count = pods_query( 'SELECT COUNT(*) AS `count` FROM `@wp_pod_pages`', false );
153
154
		if ( ! empty( $count ) ) {
155
			$count = (int) $count[0]->count;
156
		} else {
157
			$count = 0;
158
		}
159
160
		return $count;
161
	}
162
163
	/**
164
	 * @return array|bool|int|mixed|null|void
165
	 */
166
	public function prepare_helpers() {
167
168
		/**
169
		 * @var $wpdb WPDB
170
		 */
171
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
172
173
		if ( ! in_array( "{$wpdb->prefix}pod_helpers", $this->tables, true ) ) {
174
			return pods_error( __( 'Table not found, it cannot be migrated', 'pods' ) );
175
		}
176
177
		$count = pods_query( 'SELECT COUNT(*) AS `count` FROM `@wp_pod_helpers`', false );
178
179
		if ( ! empty( $count ) ) {
180
			$count = (int) $count[0]->count;
181
		} else {
182
			$count = 0;
183
		}
184
185
		return $count;
186
	}
187
188
	/**
189
	 * @param $params
190
	 *
191
	 * @return array|bool|int|mixed|null|void
192
	 */
193
	public function prepare_pod( $params ) {
194
195
		/**
196
		 * @var $wpdb WPDB
197
		 */
198
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
199
200
		if ( ! isset( $params->pod ) ) {
201
			return pods_error( __( 'Invalid Pod.', 'pods' ) );
202
		}
203
204
		$pod = pods_sanitize( pods_clean_name( $params->pod ) );
205
206
		if ( ! in_array( "{$wpdb->prefix}pod_tbl_{$pod}", $this->tables, true ) ) {
207
			return pods_error( __( 'Table not found, it cannot be migrated', 'pods' ) );
208
		}
209
210
		$count = pods_query( "SELECT COUNT(*) AS `count` FROM `@wp_pod_tbl_{$pod}`", false );
211
212
		if ( ! empty( $count ) ) {
213
			$count = (int) $count[0]->count;
214
		} else {
215
			$count = 0;
216
		}
217
218
		$pod_type = pods_query( "SELECT `id` FROM `@wp_pod_types` WHERE `name` = '{$pod}'", false );
219
220
		if ( ! empty( $pod_type ) ) {
221
			$pod_type = (int) $pod_type[0]->id;
222
		} else {
223
			return pods_error( __( 'Pod not found, it cannot be migrated', 'pods' ) );
224
		}
225
226
		$fields = array( 'id' );
227
228
		$field_rows = pods_query( "SELECT `id`, `name`, `coltype` FROM `@wp_pod_fields` WHERE `datatype` = {$pod_type} ORDER BY `weight`, `name`" );
229
230
		if ( ! empty( $field_rows ) ) {
231
			foreach ( $field_rows as $field ) {
232
				if ( ! in_array( $field->coltype, array( 'pick', 'file' ), true ) ) {
233
					$fields[] = $field->name;
234
				}
235
			}
236
		}
237
238
		$columns = PodsData::get_table_columns( "{$wpdb->prefix}pod_tbl_{$pod}" );
239
240
		$errors = array();
241
242
		foreach ( $columns as $column => $info ) {
243
			if ( ! in_array( $column, $fields, true ) ) {
244
				$errors[] = "<strong>{$column}</strong> " . __( 'is a field in the table, but was not found in this pod - the field data will not be migrated.', 'pods' );
245
			}
246
		}
247
248
		foreach ( $fields as $field ) {
249
			if ( ! isset( $columns[ $field ] ) ) {
250
				$errors[] = "<strong>{$field}</strong> " . __( 'is a field in this pod, but was not found in the table - the field data will not be migrated.', 'pods' );
251
			}
252
		}
253
254
		if ( ! empty( $errors ) ) {
255
			return pods_error( implode( '<br />', $errors ) );
256
		}
257
258
		return $count;
259
	}
260
261
	/**
262
	 *
263
	 */
264
	public function migrate_1_x() {
265
266
		$old_version = get_option( 'pods_version' );
267
268
		if ( 0 < strlen( $old_version ) ) {
269
			if ( false === strpos( $old_version, '.' ) ) {
270
				$old_version = pods_version_to_point( $old_version );
271
			}
272
273
			// Last DB change was 1.11
274
			if ( version_compare( $old_version, '1.11', '<' ) ) {
275
				do_action( 'pods_update', PODS_VERSION, $old_version );
276
277
				if ( false !== apply_filters( 'pods_update_run', null, PODS_VERSION, $old_version ) ) {
278
					include_once PODS_DIR . 'sql/update-1.x.php';
279
				}
280
281
				do_action( 'pods_update_post', PODS_VERSION, $old_version );
282
			}
283
		}
284
285
		return '1';
286
	}
287
288
	/**
289
	 * @return array|string
290
	 */
291
	public function migrate_pods() {
292
293
		if ( true === $this->check_progress( __FUNCTION__ ) ) {
294
			return '1';
295
		}
296
297
		$sister_ids = (array) get_option( 'pods_framework_upgrade_2_0_sister_ids', array() );
298
299
		$migration_limit = (int) apply_filters( 'pods_upgrade_pod_limit', 1 );
300
		$migration_limit = max( $migration_limit, 1 );
301
302
		$last_id = (int) $this->check_progress( __FUNCTION__ );
303
304
		$sql = "
305
            SELECT *
306
            FROM `@wp_pod_types`
307
            WHERE {$last_id} < `id`
308
            ORDER BY `id`
309
            LIMIT 0, {$migration_limit}
310
        ";
311
312
		$pod_types = pods_query( $sql );
313
314
		$last_id = true;
315
316
		if ( ! empty( $pod_types ) ) {
317
			foreach ( $pod_types as $pod_type ) {
318
				$field_rows = pods_query( "SELECT * FROM `@wp_pod_fields` WHERE `datatype` = {$pod_type->id} ORDER BY `weight`, `name`" );
319
320
				$fields = array(
321
					array(
322
						'name'    => 'name',
323
						'label'   => 'Name',
324
						'type'    => 'text',
325
						'weight'  => 0,
326
						'options' => array(
327
							'required'        => 1,
328
							'text_max_length' => 128,
329
						),
330
					),
331
					array(
332
						'name'    => 'created',
333
						'label'   => 'Date Created',
334
						'type'    => 'datetime',
335
						'options' => array(
336
							'datetime_format'      => 'ymd_slash',
337
							'datetime_time_type'   => '12',
338
							'datetime_time_format' => 'h_mm_ss_A',
339
						),
340
						'weight'  => 1,
341
					),
342
					array(
343
						'name'    => 'modified',
344
						'label'   => 'Date Modified',
345
						'type'    => 'datetime',
346
						'options' => array(
347
							'datetime_format'      => 'ymd_slash',
348
							'datetime_time_type'   => '12',
349
							'datetime_time_format' => 'h_mm_ss_A',
350
						),
351
						'weight'  => 2,
352
					),
353
					array(
354
						'name'        => 'author',
355
						'label'       => 'Author',
356
						'type'        => 'pick',
357
						'pick_object' => 'user',
358
						'options'     => array(
359
							'pick_format_type'   => 'single',
360
							'pick_format_single' => 'autocomplete',
361
							'default_value'      => '{@user.ID}',
362
						),
363
						'weight'      => 3,
364
					),
365
				);
366
367
				$weight = 4;
368
369
				$found_fields = array();
370
371
				foreach ( $field_rows as $row ) {
372
					if ( 'name' === $row->name ) {
373
						continue;
374
					}
375
376
					$old_name = $row->name;
377
378
					$row->name = pods_clean_name( $row->name );
379
380
					if ( in_array( $row->name, array( 'created', 'modified', 'author' ), true ) ) {
381
						$row->name .= '2';
382
					}
383
384
					$field_type = $row->coltype;
385
386
					if ( 'txt' === $field_type ) {
387
						$field_type = 'text';
388
					} elseif ( 'desc' === $field_type ) {
389
						$field_type = 'wysiwyg';
390
					} elseif ( 'code' === $field_type ) {
391
						$field_type = 'paragraph';
392
					} elseif ( 'bool' === $field_type ) {
393
						$field_type = 'boolean';
394
					} elseif ( 'num' === $field_type ) {
395
						$field_type = 'number';
396
					} elseif ( 'date' === $field_type ) {
397
						$field_type = 'datetime';
398
					}
399
400
					$field_params = array(
401
						'name'        => trim( $row->name ),
402
						'label'       => trim( $row->label ),
403
						'description' => trim( $row->comment ),
404
						'type'        => $field_type,
405
						'weight'      => $weight,
406
						'options'     => array(
407
							'required'            => $row->required,
408
							'unique'              => $row->unique,
409
							'input_helper'        => $row->input_helper,
410
							'_pods_1x_field_name' => $old_name,
411
							'_pods_1x_field_id'   => $row->id,
412
						),
413
					);
414
415
					if ( in_array( $field_params['name'], $found_fields, true ) ) {
416
						continue;
417
					}
418
419
					$found_fields[] = $field_params['name'];
420
421
					if ( 'pick' === $field_type ) {
422
						$field_params['pick_object'] = 'pod-' . $row->pickval;
423
424
						if ( 'wp_user' === $row->pickval ) {
425
							$field_params['pick_object'] = 'user';
426
						} elseif ( 'wp_post' === $row->pickval ) {
427
							$field_params['pick_object'] = 'post_type-post';
428
						} elseif ( 'wp_page' === $row->pickval ) {
429
							$field_params['pick_object'] = 'post_type-page';
430
						} elseif ( 'wp_taxonomy' === $row->pickval ) {
431
							$field_params['pick_object'] = 'taxonomy-category';
432
						}
433
434
						$field_params['sister_id'] = $row->sister_field_id;
435
436
						$sister_ids[ $row->id ] = $row->sister_field_id;
437
						// Old Sister Field ID
438
						$field_params['options']['_pods_1x_sister_id'] = $row->sister_field_id;
439
440
						$field_params['options']['pick_filter']  = $row->pick_filter;
441
						$field_params['options']['pick_orderby'] = $row->pick_orderby;
442
						$field_params['options']['pick_display'] = '';
443
						$field_params['options']['pick_size']    = 'medium';
444
445
						if ( 1 === (int) $row->multiple ) {
446
							$field_params['options']['pick_format_type']  = 'multi';
447
							$field_params['options']['pick_format_multi'] = 'checkbox';
448
							$field_params['options']['pick_limit']        = 0;
449
						} else {
450
							$field_params['options']['pick_format_type']   = 'single';
451
							$field_params['options']['pick_format_single'] = 'dropdown';
452
							$field_params['options']['pick_limit']         = 1;
453
						}
454
					} elseif ( 'file' === $field_type ) {
455
						$field_params['options']['file_format_type'] = 'multi';
456
						$field_params['options']['file_type']        = 'any';
457
					} elseif ( 'number' === $field_type ) {
458
						$field_params['options']['number_decimals'] = 2;
459
					} elseif ( 'desc' === $row->coltype ) {
460
						$field_params['options']['wysiwyg_editor'] = 'tinymce';
461
					} elseif ( 'text' === $field_type ) {
462
						$field_params['options']['text_max_length'] = 128;
463
					}//end if
464
465
					$fields[] = $field_params;
466
467
					$weight ++;
468
				}//end foreach
469
470
				$pod_type->name = pods_sanitize( pods_clean_name( $pod_type->name ) );
471
472
				$pod_params = array(
473
					'name'    => $pod_type->name,
474
					'label'   => $pod_type->label,
475
					'type'    => 'pod',
476
					'storage' => 'table',
477
					'fields'  => $fields,
478
					'options' => array(
479
						'pre_save_helpers'    => $pod_type->pre_save_helpers,
480
						'post_save_helpers'   => $pod_type->post_save_helpers,
481
						'pre_delete_helpers'  => $pod_type->pre_drop_helpers,
482
						'post_delete_helpers' => $pod_type->post_drop_helpers,
483
						'show_in_menu'        => $pod_type->is_toplevel,
484
						'detail_url'          => $pod_type->detail_page,
485
						'pod_index'           => 'name',
486
						'_pods_1x_pod_id'     => $pod_type->id,
487
					),
488
				);
489
490
				if ( empty( $pod_params['label'] ) ) {
491
					$pod_params['label'] = ucwords( str_replace( '_', ' ', $pod_params['name'] ) );
492
				}
493
494
				$pod_id = $this->api->save_pod( $pod_params );
495
496
				if ( 0 < $pod_id ) {
497
					$last_id = $pod_type->id;
498
				} else {
499
					pods_error( 'Error: ' . $pod_id );
500
				}
501
			}//end foreach
502
		}//end if
503
504
		update_option( 'pods_framework_upgrade_2_0_sister_ids', $sister_ids );
505
506
		$this->update_progress( __FUNCTION__, $last_id );
507
508
		if ( count( $pod_types ) === $migration_limit ) {
509
			return '-2';
510
		} else {
511
			return '1';
512
		}
513
	}
514
515
	/**
516
	 * @return string
517
	 */
518
	public function migrate_fields() {
519
520
		if ( true === $this->check_progress( __FUNCTION__ ) ) {
521
			return '1';
522
		}
523
524
		$sister_ids = (array) get_option( 'pods_framework_upgrade_2_0_sister_ids', array() );
525
526
		foreach ( $sister_ids as $old_field_id => $old_sister_id ) {
527
			$old_field_id  = (int) $old_field_id;
528
			$old_sister_id = (int) $old_sister_id;
529
530
			$new_field_id = pods_query( "SELECT `post_id` FROM `@wp_postmeta` WHERE `meta_key` = '_pods_1x_field_id' AND `meta_value` = '{$old_field_id}' LIMIT 1" );
531
532
			if ( ! empty( $new_field_id ) ) {
533
				$new_field_id = (int) $new_field_id[0]->post_id;
534
535
				$new_sister_id = pods_query( "SELECT `post_id` FROM `@wp_postmeta` WHERE `meta_key` = '_pods_1x_field_id' AND `meta_value` = '{$old_sister_id}' LIMIT 1" );
536
537
				if ( ! empty( $new_sister_id ) ) {
538
					$new_sister_id = (int) $new_sister_id[0]->post_id;
539
540
					update_post_meta( $new_field_id, 'sister_id', $new_sister_id );
541
				} else {
542
					delete_post_meta( $new_field_id, 'sister_id' );
543
				}
544
			}
545
		}
546
547
		// We were off the grid, so let's flush and allow for resync
548
		$this->api->cache_flush_pods();
549
550
		$this->update_progress( __FUNCTION__, true );
551
552
		return '1';
553
	}
554
555
	/**
556
	 * @return string
557
	 */
558
	public function migrate_relationships() {
559
560
		if ( true === $this->check_progress( __FUNCTION__ ) ) {
561
			return '1';
562
		}
563
564
		$migration_limit = (int) apply_filters( 'pods_upgrade_item_limit', 1500 );
565
		$migration_limit = max( $migration_limit, 100 );
566
567
		$last_id = (int) $this->check_progress( __FUNCTION__ );
568
569
		$sql = "
570
            SELECT `r`.*, `p`.`tbl_row_id` AS `real_id`, `p`.`datatype`
571
            FROM `@wp_pod_rel` AS `r`
572
            LEFT JOIN `@wp_pod` AS `p` ON `p`.`id` = `r`.`pod_id`
573
            WHERE {$last_id} < `r`.`id`
574
                AND `r`.`pod_id` IS NOT NULL
575
                AND `r`.`field_id` IS NOT NULL
576
                AND `p`.`id` IS NOT NULL
577
            ORDER BY `r`.`id`
578
            LIMIT 0, {$migration_limit}
579
        ";
580
581
		$rel = pods_query( $sql );
582
583
		$last_id = true;
584
585
		$pod_types = pods_query( 'SELECT `id`, `name` FROM `@wp_pod_types` ORDER BY `id`' );
586
587
		$types = array();
588
589
		$x = 0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $x. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
590
591
		if ( ! empty( $rel ) && ! empty( $pod_types ) ) {
592
			foreach ( $pod_types as $type ) {
593
				$type->name = pods_clean_name( $type->name );
594
595
				$types[ $type->id ] = $this->api->load_pod( array( 'name' => $type->name ), false );
596
597
				if ( empty( $types[ $type->id ] ) ) {
598
					return pods_error( sprintf( __( 'Pod <strong>%s</strong> not found, relationships cannot be migrated', 'pods' ), $type->name ) );
599
				}
600
601
				$pod_fields = pods_query( "SELECT `id`, `name` FROM `@wp_pod_fields` WHERE `datatype` = {$type->id} ORDER BY `id`" );
602
603
				$types[ $type->id ]['old_fields'] = array();
604
605
				foreach ( $pod_fields as $field ) {
606
					// Handle name changes
607
					if ( in_array( $field->name, array( 'created', 'modified', 'author' ), true ) ) {
608
						$field->name .= '2';
609
					}
610
611
					$types[ $type->id ]['old_fields'][ $field->id ] = $field->name;
612
				}
613
			}//end foreach
614
615
			foreach ( $rel as $r ) {
616
				$r->pod_id = (int) $r->pod_id;
617
618
				if ( ! isset( $types[ $r->datatype ] ) || ! isset( $types[ $r->datatype ]['old_fields'][ $r->field_id ] ) ) {
619
					continue;
620
				}
621
622
				if ( ! isset( $types[ $r->datatype ]['fields'][ $types[ $r->datatype ]['old_fields'][ $r->field_id ] ] ) ) {
623
					continue;
624
				}
625
626
				$field = $types[ $r->datatype ]['fields'][ $types[ $r->datatype ]['old_fields'][ $r->field_id ] ];
627
628
				if ( ! in_array( $field['type'], array( 'pick', 'file' ), true ) ) {
629
					continue;
630
				}
631
632
				$pod_id   = $types[ $r->datatype ]['id'];
633
				$field_id = $field['id'];
634
				$item_id  = $r->real_id;
635
636
				$related_pod_id   = 0;
637
				$related_field_id = 0;
638
				$related_item_id  = $r->tbl_row_id;
639
640
				if ( 'pick' === $field['type'] ) {
641
					$old_sister_id = (int) pods_v( '_pods_1x_sister_id', $field['options'], 0 );
642
643
					if ( 0 < $old_sister_id ) {
644
						$sql = '
645
                            SELECT `f`.`id`, `f`.`name`, `t`.`name` AS `pod`
646
                            FROM `@wp_pod_fields` AS `f`
647
                            LEFT JOIN `@wp_pod_types` AS `t` ON `t`.`id` = `f`.`datatype`
648
                            WHERE `f`.`id` = ' . $old_sister_id . ' AND `t`.`id` IS NOT NULL
649
                            ORDER BY `f`.`id`
650
                            LIMIT 1
651
                        ';
652
653
						$old_field = pods_query( $sql );
654
655
						if ( empty( $old_field ) ) {
656
							continue;
657
						}
658
659
						$old_field = $old_field[0];
660
661
						$related_field = $this->api->load_field(
662
							array(
663
								'name' => $old_field->name,
664
								'pod'  => $old_field->pod,
665
							)
666
						);
667
668
						if ( empty( $related_field ) ) {
669
							continue;
670
						}
671
672
						$related_pod_id   = $related_field['pod_id'];
673
						$related_field_id = $related_field['id'];
674
					} elseif ( 'pod' === $field['pick_object'] && 0 < strlen( $field['pick_val'] ) ) {
675
						$related_pod = $this->api->load_pod( array( 'name' => $field['pick_val'] ), false );
676
677
						if ( empty( $related_pod ) ) {
678
							continue;
679
						}
680
681
						$related_pod_id = $related_pod['id'];
682
					}//end if
683
				}//end if
684
685
				$r->id            = (int) $r->id;
686
				$pod_id           = (int) $pod_id;
687
				$field_id         = (int) $field_id;
688
				$item_id          = (int) $item_id;
689
				$related_pod_id   = (int) $related_pod_id;
690
				$related_field_id = (int) $related_field_id;
691
				$related_item_id  = (int) $related_item_id;
692
				$r->weight        = (int) $r->weight;
693
694
				$table_data = array(
695
					'id'               => $r->id,
696
					'pod_id'           => $pod_id,
697
					'field_id'         => $field_id,
698
					'item_id'          => $item_id,
699
					'related_pod_id'   => $related_pod_id,
700
					'related_field_id' => $related_field_id,
701
					'related_item_id'  => $related_item_id,
702
					'weight'           => $r->weight,
703
				);
704
705
				$table_formats = array_fill( 0, count( $table_data ), '%d' );
706
707
				$sql = PodsData::insert_on_duplicate( '@wp_podsrel', $table_data, $table_formats );
708
709
				pods_query( $sql );
710
711
				$last_id = $r->id;
712
713
				$x ++;
714
715
				if ( 10 < $x ) {
716
					$this->update_progress( __FUNCTION__, $last_id );
717
718
					$x = 0;
719
				}
720
			}//end foreach
721
		}//end if
722
723
		$this->update_progress( __FUNCTION__, $last_id );
724
725
		if ( count( $rel ) === $migration_limit ) {
726
			return '-2';
727
		} else {
728
			return '1';
729
		}
730
	}
731
732
	/**
733
	 * @return string
734
	 */
735
	public function migrate_settings() {
736
737
		return $this->migrate_roles();
738
	}
739
740
	/**
741
	 * @return string
742
	 */
743
	public function migrate_roles() {
744
745
		if ( true === $this->check_progress( __FUNCTION__ ) ) {
746
			return '1';
747
		}
748
749
		/**
750
		 * @var $wpdb WPDB
751
		 */
752
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
753
754
		$wp_roles = get_option( "{$wpdb->prefix}user_roles" );
755
756
		$old_roles = get_option( 'pods_roles' );
757
758
		if ( ! is_array( $old_roles ) && ! empty( $old_roles ) ) {
759
			$old_roles = @unserialize( $old_roles );
0 ignored issues
show
Coding Style introduced by
Silencing errors is discouraged
Loading history...
760
		}
761
762
		if ( ! is_array( $old_roles ) ) {
763
			$old_roles = array();
764
		}
765
766
		if ( ! empty( $old_roles ) ) {
767
			foreach ( $old_roles as $role => $data ) {
768
				if ( '_wpnonce' === $role ) {
769
					continue;
770
				}
771
772
				if ( ! isset( $wp_roles[ $role ] ) ) {
773
					continue;
774
				}
775
776
				$caps = $wp_roles[ $role ]['capabilities'];
777
778
				foreach ( $data as $cap ) {
779
					if ( 0 === strpos( 'manage_', $cap ) ) {
780
						if ( 'manage_roles' === $cap ) {
781
							continue;
782
						}
783
784
						$cap = pods_str_replace( 'manage_', 'pods_', $cap, 1 );
785
						$cap = pods_str_replace( 'pod_pages', 'pages', $cap, 1 );
786
787
						$caps[ $cap ] = true;
788
					} elseif ( 0 === strpos( 'pod_', $cap ) ) {
789
						$keys = array(
790
							pods_str_replace( 'pod_', 'pods_new_', $cap, 1 ),
791
							pods_str_replace( 'pod_', 'pods_edit_', $cap, 1 ),
792
							pods_str_replace( 'pod_', 'pods_delete_', $cap, 1 ),
793
						);
794
795
						foreach ( $keys as $key ) {
796
							$caps[ $key ] = true;
797
						}
798
					}
799
				}//end foreach
800
801
				$wp_roles[ $role ]['capabilities'] = $caps;
802
			}//end foreach
803
		}//end if
804
805
		update_option( "{$wpdb->prefix}user_roles", $wp_roles );
806
807
		$this->update_progress( __FUNCTION__, true );
808
809
		return '1';
810
	}
811
812
	/**
813
	 * @return array|string
814
	 */
815
	public function migrate_templates() {
816
817
		if ( true === $this->check_progress( __FUNCTION__ ) ) {
818
			return '1';
819
		}
820
821
		$templates = pods_query( 'SELECT * FROM `@wp_pod_templates`', false );
822
823
		$results = array();
824
825
		if ( ! empty( $templates ) ) {
826
			foreach ( $templates as $template ) {
827
				unset( $template->id );
828
829
				$results[] = $this->api->save_template( $template );
830
			}
831
		}
832
833
		$this->update_progress( __FUNCTION__, true );
834
835
		return '1';
836
	}
837
838
	/**
839
	 * @return array|string
840
	 */
841
	public function migrate_pages() {
842
843
		if ( true === $this->check_progress( __FUNCTION__ ) ) {
844
			return '1';
845
		}
846
847
		$pages = pods_query( 'SELECT * FROM `@wp_pod_pages`', false );
848
849
		if ( ! empty( $pages ) ) {
850
			foreach ( $pages as $page ) {
851
				unset( $page->id );
852
853
				$this->api->save_page( $page );
854
			}
855
		}
856
857
		$this->update_progress( __FUNCTION__, true );
858
859
		return '1';
860
	}
861
862
	/**
863
	 * @return array|string
864
	 */
865
	public function migrate_helpers() {
866
867
		if ( true === $this->check_progress( __FUNCTION__ ) ) {
868
			return '1';
869
		}
870
871
		$helpers = pods_query( 'SELECT * FROM `@wp_pod_helpers`', false );
872
873
		$notice = false;
874
875
		if ( ! empty( $helpers ) ) {
876
			foreach ( $helpers as $helper ) {
877
				unset( $helper->id );
878
879
				if ( 'input' === $helper->helper_type ) {
880
					$helper->status = 'draft';
881
882
					$notice = true;
883
				}
884
885
				$this->api->save_helper( $helper );
886
			}
887
		}
888
889
		$this->update_progress( __FUNCTION__, true );
890
891
		if ( $notice ) {
892
			return pods_error( __( 'Input Helpers may not function in our new forms, we have imported and disabled them for your review.', 'pods' ) );
893
		}
894
895
		return '1';
896
	}
897
898
	/**
899
	 * @param $params
900
	 *
901
	 * @return mixed|string|void
902
	 */
903
	public function migrate_pod( $params ) {
904
905
		/**
906
		 * @var $wpdb WPDB
907
		 */
908
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
909
910
		if ( ! isset( $params->pod ) ) {
911
			return pods_error( __( 'Invalid Pod.', 'pods' ) );
912
		}
913
914
		$pod = pods_sanitize( pods_clean_name( $params->pod ) );
915
916
		if ( ! in_array( "{$wpdb->prefix}pod_tbl_{$pod}", $this->tables, true ) ) {
917
			return pods_error( __( 'Table not found, items cannot be migrated', 'pods' ) );
918
		}
919
920
		if ( ! in_array( "{$wpdb->prefix}pods_{$pod}", $this->tables, true ) ) {
921
			return pods_error( __( 'New table not found, items cannot be migrated', 'pods' ) );
922
		}
923
924
		if ( ! in_array( "{$wpdb->prefix}pod_types", $this->tables, true ) ) {
925
			return pods_error( __( 'Pod Types table not found, items cannot be migrated', 'pods' ) );
926
		}
927
928
		if ( ! in_array( "{$wpdb->prefix}pod", $this->tables, true ) ) {
929
			return pods_error( __( 'Pod table not found, items cannot be migrated', 'pods' ) );
930
		}
931
932
		if ( true === $this->check_progress( __FUNCTION__, $pod ) ) {
933
			return '1';
934
		}
935
936
		$pod_data = $this->api->load_pod( array( 'name' => $pod ), false );
937
938
		if ( empty( $pod_data ) ) {
939
			return pods_error( sprintf( __( 'Pod <strong>%s</strong> not found, items cannot be migrated', 'pods' ), $pod ) );
940
		}
941
942
		$columns     = array();
943
		$old_columns = array();
944
945
		foreach ( $pod_data['fields'] as $field ) {
946
			if ( ! in_array(
947
				$field['name'], array(
948
					'created',
949
					'modified',
950
					'author',
951
				), true
952
			) && ! in_array( $field['type'], array( 'file', 'pick' ), true ) ) {
953
				$columns[]     = pods_sanitize( $field['name'] );
954
				$old_columns[] = pods_v( '_pods_1x_field_name', $field['options'], $field['name'], false );
955
			}
956
		}
957
958
		$into   = '`id`';
959
		$select = '`t`.`id`';
960
961
		if ( ! empty( $columns ) ) {
962
			$into   .= ', `' . implode( '`, `', $columns ) . '`';
963
			$select .= ', `t`.`' . implode( '`, `t`.`', $old_columns ) . '`';
964
		}
965
966
		// Copy content from the old table into the new
967
		$sql = "
968
            REPLACE INTO `@wp_pods_{$pod}`
969
                ( {$into} )
970
                ( SELECT {$select}
971
                  FROM `@wp_pod_tbl_{$pod}` AS `t` )
972
        ";
973
974
		pods_query( $sql );
975
976
		// Copy index data from the old index table into the new individual table
977
		$sql = "
978
            UPDATE `@wp_pods_{$pod}` AS `t`
979
            LEFT JOIN `@wp_pod_types` AS `x` ON `x`.`name` = '{$pod}'
980
            LEFT JOIN `@wp_pod` AS `p` ON `p`.`datatype` = `x`.`id` AND `p`.`tbl_row_id` = `t`.`id`
981
            SET `t`.`created` = `p`.`created`, `t`.`modified` = `p`.`modified`
982
            WHERE `x`.`id` IS NOT NULL AND `p`.`id` IS NOT NULL
983
        ";
984
985
		pods_query( $sql );
986
987
		// Copy name data from the old index table into the new individual table (if name empty in indiv table)
988
		$sql = "
989
            UPDATE `@wp_pods_{$pod}` AS `t`
990
            LEFT JOIN `@wp_pod_types` AS `x` ON `x`.`name` = '{$pod}'
991
            LEFT JOIN `@wp_pod` AS `p` ON `p`.`datatype` = `x`.`id` AND `p`.`tbl_row_id` = `t`.`id`
992
            SET `t`.`name` = `p`.`name`
993
            WHERE ( `t`.`name` IS NULL OR `t`.`name` = '' ) AND `x`.`id` IS NOT NULL AND `p`.`id` IS NOT NULL
994
        ";
995
996
		pods_query( $sql );
997
998
		$this->update_progress( __FUNCTION__, true, $pod );
999
1000
		return '1';
1001
	}
1002
1003
	/**
1004
	 * @return string
1005
	 */
1006
	public function migrate_cleanup() {
1007
1008
		update_option( 'pods_framework_upgraded_1_x', 1 );
1009
1010
		PodsInit::$components->activate_component( 'templates' );
1011
		PodsInit::$components->activate_component( 'pages' );
1012
		PodsInit::$components->activate_component( 'helpers' );
1013
1014
		$this->api->cache_flush_pods();
1015
1016
		return '1';
1017
	}
1018
1019
	/**
1020
	 *
1021
	 */
1022
	public function restart() {
1023
1024
		/**
1025
		 * @var $wpdb WPDB
1026
		 */
1027
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1028
1029
		foreach ( $this->tables as $table ) {
1030
			if ( false !== strpos( $table, "{$wpdb->prefix}pods" ) ) {
1031
				pods_query( "TRUNCATE `{$table}`", false );
1032
			}
1033
		}
1034
1035
		delete_option( 'pods_framework_upgrade_2_0' );
1036
		delete_option( 'pods_framework_upgrade_2_0_sister_ids' );
1037
		delete_option( 'pods_framework_upgraded_1_x' );
1038
	}
1039
1040
	/**
1041
	 *
1042
	 */
1043
	public function cleanup() {
1044
1045
		/**
1046
		 * @var $wpdb WPDB
1047
		 */
1048
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1049
1050
		foreach ( $this->tables as $table ) {
1051
			if ( false !== strpos( $table, "{$wpdb->prefix}pod_" ) || "{$wpdb->prefix}pod" === $table ) {
1052
				pods_query( "DROP TABLE `{$table}`", false );
1053
			}
1054
		}
1055
1056
		delete_option( 'pods_roles' );
1057
		delete_option( 'pods_version' );
1058
		delete_option( 'pods_framework_upgrade_2_0' );
1059
		delete_option( 'pods_framework_upgrade_2_0_sister_ids' );
1060
		delete_option( 'pods_framework_upgraded_1_x' );
1061
1062
		delete_option( 'pods_disable_file_browser' );
1063
		delete_option( 'pods_files_require_login' );
1064
		delete_option( 'pods_files_require_login_cap' );
1065
		delete_option( 'pods_disable_file_upload' );
1066
		delete_option( 'pods_upload_require_login' );
1067
		delete_option( 'pods_upload_require_login_cap' );
1068
1069
		pods_query( "DELETE FROM `@wp_postmeta` WHERE `meta_key` LIKE '_pods_1x_%'" );
1070
	}
1071
}
1072