Completed
Push — feature/codesniffer-fixes ( c7a4f1...41059d )
by Scott Kingsley
13:22
created

Pods_Migrate_Packages   F

Complexity

Total Complexity 132

Size/Duplication

Total Lines 713
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 713
rs 1.263
c 0
b 0
f 0
wmc 132
lcom 0
cbo 3

5 Methods

Rating   Name   Duplication   Size   Complexity  
A admin_assets() 0 4 1
A admin() 0 6 1
C ajax_import_export() 0 50 9
F import() 0 435 87
F export() 0 167 34

How to fix   Complexity   

Complex Class

Complex classes like Pods_Migrate_Packages 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 Pods_Migrate_Packages, and based on these observations, apply Extract Interface, too.

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 27 and the first side effect is on line 21.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Name: Migrate: Packages
4
 *
5
 * Menu Name: Migrate Packages
6
 *
7
 * Description: Import/Export your Pods, Fields, and other settings from any Pods site; Includes an API to
8
 * Import/Export Packages via PHP
9
 *
10
 * Version: 2.0
11
 *
12
 * Category: Migration
13
 *
14
 * Plugin: pods-migrate-packages/pods-migrate-packages.php
15
 *
16
 * @package    Pods\Components
17
 * @subpackage Migrate-Packages
18
 */
19
20
if ( class_exists( 'Pods_Migrate_Packages' ) ) {
21
	return;
22
}
23
24
/**
25
 * Class Pods_Migrate_Packages
26
 */
27
class Pods_Migrate_Packages extends PodsComponent {
28
29
	/**
30
	 * Enqueue styles
31
	 *
32
	 * @since 2.0
33
	 */
34
	public function admin_assets() {
35
36
		wp_enqueue_style( 'pods-wizard' );
37
	}
38
39
	/**
40
	 * Build admin area
41
	 *
42
	 * @param array  $options   Component options.
43
	 * @param string $component Component name.
44
	 *
45
	 * @since 2.0
46
	 */
47
	public function admin( $options, $component ) {
48
49
		$method = 'import_export';
50
		// ajax_import
51
		pods_view( PODS_DIR . 'components/Migrate-Packages/ui/wizard.php', compact( array_keys( get_defined_vars() ) ) );
52
	}
53
54
	/**
55
	 * Handle the Import/Export AJAX
56
	 *
57
	 * @param $params
58
	 */
59
	public function ajax_import_export( $params ) {
60
61
		if ( 'import' === $params->import_export ) {
62
			$data = trim( $params->import_package );
63
64
			$content = '<div class="pods-wizard-content">';
65
66
			if ( ! empty( $data ) ) {
67
				$imported = $this->import( $data );
68
69
				if ( ! empty( $imported ) ) {
70
					$content .= '<p>Import Complete! The following items were imported:</p>';
71
72
					foreach ( $imported as $type => $import ) {
0 ignored issues
show
Bug introduced by
The expression $imported of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
73
						$content .= '<h4>' . ucwords( $type ) . '</h4>';
74
75
						$content .= '<ul class="normal">';
76
77
						foreach ( $import as $k => $what ) {
78
							$content .= '<li>' . esc_html( $what ) . '</li>';
79
						}
80
81
						$content .= '</ul>';
82
					}
83
				}
84
			} else {
85
				$content .= '<p>Import Error: Invalid Package</p>';
86
			}//end if
87
88
			$content .= '</div>';
89
90
			echo $content;
91
		} elseif ( 'export' === $params->import_export ) {
92
			$params = get_object_vars( $params );
93
			foreach ( $params as $k => $v ) {
94
				if ( is_array( $v ) ) {
95
					$params[ $k ] = array_keys( array_filter( $v ) );
96
				}
97
			}
98
99
			$package = $this->export( $params );
100
101
			echo '<div class="pods-field-option">';
102
103
			echo PodsForm::field( 'export_package', $package, 'paragraph', array( 'attributes' => array( 'style' => 'width: 94%; max-width: 94%; height: 300px;' ) ) );
104
105
			echo '</div>';
106
		}//end if
107
108
	}
109
110
	/**
111
	 * Import a Package
112
	 *
113
	 * @param string|array $data    a JSON array package string, or an array of Package Data
114
	 * @param bool         $replace Whether to replace existing pods entirely or just update them
115
	 *
116
	 * @return array|bool
117
	 *
118
	 * @static
119
	 * @since 2.0.5
120
	 */
121
	public static function import( $data, $replace = false ) {
122
123
		if ( ! defined( 'PODS_FIELD_STRICT' ) ) {
124
			define( 'PODS_FIELD_STRICT', false );
125
		}
126
127
		if ( ! is_array( $data ) ) {
128
			$json_data = @json_decode( $data, true );
0 ignored issues
show
Coding Style introduced by
Silencing errors is discouraged
Loading history...
129
130
			if ( ! is_array( $json_data ) ) {
131
				$json_data = @json_decode( pods_unslash( $data ), true );
0 ignored issues
show
Coding Style introduced by
Silencing errors is discouraged
Loading history...
132
			}
133
134
			$data = $json_data;
135
		}
136
137
		if ( ! is_array( $data ) || empty( $data ) ) {
138
			return false;
139
		}
140
141
		$api = pods_api();
142
143
		if ( ! isset( $data['meta'] ) || ! isset( $data['meta']['version'] ) || empty( $data['meta']['version'] ) ) {
144
			return false;
145
		}
146
147
		if ( false === strpos( $data['meta']['version'], '.' ) && (int) $data['meta']['version'] < 1000 ) {
148
			// Pods 1.x < 1.10
149
			$data['meta']['version'] = implode( '.', str_split( $data['meta']['version'] ) );
150
		} elseif ( false === strpos( $data['meta']['version'], '.' ) ) {
151
			// Pods 1.10 <= 2.0
152
			$data['meta']['version'] = pods_version_to_point( $data['meta']['version'] );
153
		}
154
155
		$found = array();
156
157
		if ( isset( $data['pods'] ) && is_array( $data['pods'] ) ) {
158
			foreach ( $data['pods'] as $pod_data ) {
159
				if ( isset( $pod_data['id'] ) ) {
160
					unset( $pod_data['id'] );
161
				}
162
163
				$pod = $api->load_pod( array( 'name' => $pod_data['name'] ), false );
164
165
				$existing_fields = array();
166
167
				if ( ! empty( $pod ) ) {
168
					// Delete Pod if it exists
169
					if ( $replace ) {
170
						$api->delete_pod( array( 'id' => $pod['id'] ) );
171
172
						$pod = array( 'fields' => array() );
173
					} else {
174
						$existing_fields = $pod['fields'];
175
					}
176
				} else {
177
					$pod = array( 'fields' => array() );
178
				}
179
180
				// Backwards compatibility
181
				if ( version_compare( $data['meta']['version'], '2.0', '<' ) ) {
182
					$core_fields = array(
183
						array(
184
							'name'    => 'created',
185
							'label'   => 'Date Created',
186
							'type'    => 'datetime',
187
							'options' => array(
188
								'datetime_format'      => 'ymd_slash',
189
								'datetime_time_type'   => '12',
190
								'datetime_time_format' => 'h_mm_ss_A',
191
							),
192
							'weight'  => 1,
193
						),
194
						array(
195
							'name'    => 'modified',
196
							'label'   => 'Date Modified',
197
							'type'    => 'datetime',
198
							'options' => array(
199
								'datetime_format'      => 'ymd_slash',
200
								'datetime_time_type'   => '12',
201
								'datetime_time_format' => 'h_mm_ss_A',
202
							),
203
							'weight'  => 2,
204
						),
205
						array(
206
							'name'        => 'author',
207
							'label'       => 'Author',
208
							'type'        => 'pick',
209
							'pick_object' => 'user',
210
							'options'     => array(
211
								'pick_format_type'   => 'single',
212
								'pick_format_single' => 'autocomplete',
213
								'default_value'      => '{@user.ID}',
214
							),
215
							'weight'      => 3,
216
						),
217
					);
218
219
					$found_fields = array();
220
221
					if ( ! empty( $pod_data['fields'] ) ) {
222
						foreach ( $pod_data['fields'] as $k => $field ) {
223
							$field_type = $field['coltype'];
224
225
							if ( 'txt' === $field_type ) {
226
								$field_type = 'text';
227
							} elseif ( 'desc' === $field_type ) {
228
								$field_type = 'wysiwyg';
229
							} elseif ( 'code' === $field_type ) {
230
								$field_type = 'paragraph';
231
							} elseif ( 'bool' === $field_type ) {
232
								$field_type = 'boolean';
233
							} elseif ( 'num' === $field_type ) {
234
								$field_type = 'number';
235
							} elseif ( 'date' === $field_type ) {
236
								$field_type = 'datetime';
237
							}
238
239
							$multiple = min( max( (int) $field['multiple'], 0 ), 1 );
240
241
							$new_field = array(
242
								'name'        => trim( $field['name'] ),
243
								'label'       => trim( $field['label'] ),
244
								'description' => trim( $field['comment'] ),
245
								'type'        => $field_type,
246
								'weight'      => (int) $field['weight'],
247
								'options'     => array(
248
									'required'     => min( max( (int) $field['required'], 0 ), 1 ),
249
									'unique'       => min( max( (int) $field['unique'], 0 ), 1 ),
250
									'input_helper' => $field['input_helper'],
251
								),
252
							);
253
254
							if ( in_array( $new_field['name'], $found_fields, true ) ) {
255
								unset( $pod_data['fields'][ $k ] );
256
257
								continue;
258
							}
259
260
							$found_fields[] = $new_field['name'];
261
262
							if ( 'pick' === $field_type ) {
263
								$new_field['pick_object'] = 'pod';
264
								$new_field['pick_val']    = $field['pickval'];
265
266
								if ( 'wp_user' === $field['pickval'] ) {
267
									$new_field['pick_object'] = 'user';
268
								} elseif ( 'wp_post' === $field['pickval'] ) {
269
									$new_field['pick_object'] = 'post_type-post';
270
								} elseif ( 'wp_page' === $field['pickval'] ) {
271
									$new_field['pick_object'] = 'post_type-page';
272
								} elseif ( 'wp_taxonomy' === $field['pickval'] ) {
273
									$new_field['pick_object'] = 'taxonomy-category';
274
								}
275
276
								// This won't work if the field doesn't exist
277
								// $new_field[ 'sister_id' ] = $field[ 'sister_field_id' ];
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
278
								$new_field['options']['pick_filter']  = $field['pick_filter'];
279
								$new_field['options']['pick_orderby'] = $field['pick_orderby'];
280
								$new_field['options']['pick_display'] = '';
281
								$new_field['options']['pick_size']    = 'medium';
282
283
								if ( 1 == $multiple ) {
284
									$new_field['options']['pick_format_type']  = 'multi';
285
									$new_field['options']['pick_format_multi'] = 'checkbox';
286
									$new_field['options']['pick_limit']        = 0;
287
								} else {
288
									$new_field['options']['pick_format_type']   = 'single';
289
									$new_field['options']['pick_format_single'] = 'dropdown';
290
									$new_field['options']['pick_limit']         = 1;
291
								}
292
							} elseif ( 'file' === $field_type ) {
293
								$new_field['options']['file_format_type'] = 'multi';
294
								$new_field['options']['file_type']        = 'any';
295
							} elseif ( 'number' === $field_type ) {
296
								$new_field['options']['number_decimals'] = 2;
297
							} elseif ( 'desc' === $field['coltype'] ) {
298
								$new_field['options']['wysiwyg_editor'] = 'tinymce';
299
							} elseif ( 'text' === $field_type ) {
300
								$new_field['options']['text_max_length'] = 128;
301
							}//end if
302
303
							if ( isset( $pod['fields'][ $new_field['name'] ] ) ) {
304
								$new_field = array_merge( $pod['fields'][ $new_field['name'] ], $new_field );
305
							}
306
307
							$pod_data['fields'][ $k ] = $new_field;
308
						}//end foreach
309
					}//end if
310
311
					if ( pods_var( 'id', $pod, 0 ) < 1 ) {
312
						$pod_data['fields'] = array_merge( $core_fields, $pod_data['fields'] );
313
					}
314
315
					if ( empty( $pod_data['label'] ) ) {
316
						$pod_data['label'] = ucwords( str_replace( '_', ' ', $pod_data['name'] ) );
317
					}
318
319
					if ( isset( $pod_data['is_toplevel'] ) ) {
320
						$pod_data['show_in_menu'] = ( 1 == $pod_data['is_toplevel'] ? 1 : 0 );
321
322
						unset( $pod_data['is_toplevel'] );
323
					}
324
325
					if ( isset( $pod_data['detail_page'] ) ) {
326
						$pod_data['detail_url'] = $pod_data['detail_page'];
327
328
						unset( $pod_data['detail_page'] );
329
					}
330
331
					if ( isset( $pod_data['before_helpers'] ) ) {
332
						$pod_data['pre_save_helpers'] = $pod_data['before_helpers'];
333
334
						unset( $pod_data['before_helpers'] );
335
					}
336
337
					if ( isset( $pod_data['after_helpers'] ) ) {
338
						$pod_data['post_save_helpers'] = $pod_data['after_helpers'];
339
340
						unset( $pod_data['after_helpers'] );
341
					}
342
343
					if ( isset( $pod_data['pre_drop_helpers'] ) ) {
344
						$pod_data['pre_delete_helpers'] = $pod_data['pre_drop_helpers'];
345
346
						unset( $pod_data['pre_drop_helpers'] );
347
					}
348
349
					if ( isset( $pod_data['post_drop_helpers'] ) ) {
350
						$pod_data['post_delete_helpers'] = $pod_data['post_drop_helpers'];
351
352
						unset( $pod_data['post_drop_helpers'] );
353
					}
354
355
					$pod_data['name'] = pods_clean_name( $pod_data['name'] );
356
357
					$pod_data = array(
358
						'name'    => $pod_data['name'],
359
						'label'   => $pod_data['label'],
360
						'type'    => 'pod',
361
						'storage' => 'table',
362
						'fields'  => $pod_data['fields'],
363
						'options' => array(
364
							'pre_save_helpers'    => pods_var_raw( 'pre_save_helpers', $pod_data ),
365
							'post_save_helpers'   => pods_var_raw( 'post_save_helpers', $pod_data ),
366
							'pre_delete_helpers'  => pods_var_raw( 'pre_delete_helpers', $pod_data ),
367
							'post_delete_helpers' => pods_var_raw( 'post_delete_helpers', $pod_data ),
368
							'show_in_menu'        => ( 1 == pods_var_raw( 'show_in_menu', $pod_data, 0 ) ? 1 : 0 ),
369
							'detail_url'          => pods_var_raw( 'detail_url', $pod_data ),
370
							'pod_index'           => 'name',
371
						),
372
					);
373
				}//end if
374
375
				$pod = array_merge( $pod, $pod_data );
376
377
				foreach ( $pod['fields'] as $k => $field ) {
378
					if ( isset( $field['id'] ) && ! isset( $existing_fields[ $field['name'] ] ) ) {
379
						unset( $pod['fields'][ $k ]['id'] );
380
					}
381
382
					if ( isset( $field['pod_id'] ) ) {
383
						unset( $pod['fields'][ $k ]['pod_id'] );
384
					}
385
386
					if ( isset( $existing_fields[ $field['name'] ] ) ) {
387
						if ( $existing_field = pods_api()->load_field(
388
							array(
389
								'name' => $field['name'],
390
								'pod'  => $pod['name'],
391
							)
392
						) ) {
393
							$pod['fields'][ $k ]['id'] = $existing_field['id'];
394
						}
395
					}
396
397
					if ( isset( $field['pod'] ) ) {
398
						unset( $pod['fields'][ $k ]['pod'] );
399
					}
400
				}//end foreach
401
402
				$api->save_pod( $pod );
403
404
				if ( ! isset( $found['pods'] ) ) {
405
					$found['pods'] = array();
406
				}
407
408
				$found['pods'][ $pod['name'] ] = $pod['label'];
409
			}//end foreach
410
		}//end if
411
412
		if ( isset( $data['templates'] ) && is_array( $data['templates'] ) ) {
413
			foreach ( $data['templates'] as $template_data ) {
414
				if ( isset( $template_data['id'] ) ) {
415
					unset( $template_data['id'] );
416
				}
417
418
				$template = $api->load_template( array( 'name' => $template_data['name'] ) );
419
420
				if ( ! empty( $template ) ) {
421
					// Delete Template if it exists
422
					if ( $replace ) {
423
						$api->delete_template( array( 'id' => $template['id'] ) );
424
425
						$template = array();
426
					}
427
				} else {
428
					$template = array();
429
				}
430
431
				$template = array_merge( $template, $template_data );
432
433
				$api->save_template( $template );
434
435
				if ( ! isset( $found['templates'] ) ) {
436
					$found['templates'] = array();
437
				}
438
439
				$found['templates'][ $template['name'] ] = $template['name'];
440
			}//end foreach
441
		}//end if
442
443
		// Backwards compatibility
444
		if ( isset( $data['pod_pages'] ) ) {
445
			$data['pages'] = $data['pod_pages'];
446
447
			unset( $data['pod_pages'] );
448
		}
449
450
		if ( isset( $data['pages'] ) && is_array( $data['pages'] ) ) {
451
			foreach ( $data['pages'] as $page_data ) {
452
				if ( isset( $page_data['id'] ) ) {
453
					unset( $page_data['id'] );
454
				}
455
456
				$page = $api->load_page( array( 'name' => pods_var_raw( 'name', $page_data, pods_var_raw( 'uri', $page_data ), null, true ) ) );
457
458
				if ( ! empty( $page ) ) {
459
					// Delete Page if it exists
460
					if ( $replace ) {
461
						$api->delete_page( array( 'id' => $page['id'] ) );
462
463
						$page = array();
464
					}
465
				} else {
466
					$page = array();
467
				}
468
469
				// Backwards compatibility
470
				if ( isset( $page_data['uri'] ) ) {
471
					$page_data['name'] = $page_data['uri'];
472
473
					unset( $page_data['uri'] );
474
				}
475
476
				if ( isset( $page_data['phpcode'] ) ) {
477
					$page_data['code'] = $page_data['phpcode'];
478
479
					unset( $page_data['phpcode'] );
480
				}
481
482
				$page = array_merge( $page, $page_data );
483
484
				$page['name'] = trim( $page['name'], '/' );
485
486
				$api->save_page( $page );
487
488
				if ( ! isset( $found['pages'] ) ) {
489
					$found['pages'] = array();
490
				}
491
492
				$found['pages'][ $page['name'] ] = $page['name'];
493
			}//end foreach
494
		}//end if
495
496
		if ( isset( $data['helpers'] ) && is_array( $data['helpers'] ) ) {
497
			foreach ( $data['helpers'] as $helper_data ) {
498
				if ( isset( $helper_data['id'] ) ) {
499
					unset( $helper_data['id'] );
500
				}
501
502
				$helper = $api->load_helper( array( 'name' => $helper_data['name'] ) );
503
504
				if ( ! empty( $helper ) ) {
505
					// Delete Helper if it exists
506
					if ( $replace ) {
507
						$api->delete_helper( array( 'id' => $helper['id'] ) );
508
509
						$helper = array();
510
					}
511
				} else {
512
					$helper = array();
513
				}
514
515
				// Backwards compatibility
516
				if ( isset( $helper_data['phpcode'] ) ) {
517
					$helper_data['code'] = $helper_data['phpcode'];
518
519
					unset( $helper_data['phpcode'] );
520
				}
521
522
				if ( isset( $helper_data['type'] ) ) {
523
					if ( 'before' === $helper_data['type'] ) {
524
						$helper_data['type'] = 'pre_save';
525
					} elseif ( 'after' === $helper_data['type'] ) {
526
						$helper_data['type'] = 'post_save';
527
					}
528
				}
529
530
				$helper = array_merge( $helper, $helper_data );
531
532
				if ( isset( $helper['type'] ) ) {
533
					$helper['helper_type'] = $helper['type'];
534
535
					unset( $helper['helper_type'] );
536
				}
537
538
				$api->save_helper( $helper );
539
540
				if ( ! isset( $found['helpers'] ) ) {
541
					$found['helpers'] = array();
542
				}
543
544
				$found['helpers'][ $helper['name'] ] = $helper['name'];
545
			}//end foreach
546
		}//end if
547
548
		$found = apply_filters( 'pods_packages_import', $found, $data, $replace );
549
550
		if ( ! empty( $found ) ) {
551
			return $found;
552
		}
553
554
		return false;
555
	}
556
557
	/**
558
	 * Export a Package
559
	 *
560
	 * $params['pods'] string|array|bool Pod IDs to export, or set to true to export all
561
	 * $params['templates'] string|array|bool Template IDs to export, or set to true to export all
562
	 * $params['pages'] string|array|bool Page IDs to export, or set to true to export all
563
	 * $params['helpers'] string|array|bool Helper IDs to export, or set to true to export all
564
	 *
565
	 * @param array $params Array of things to export
566
	 *
567
	 * @return array|bool
568
	 *
569
	 * @static
570
	 * @since 2.0.5
571
	 */
572
	public static function export( $params ) {
573
574
		$export = array(
575
			'meta' => array(
576
				'version' => PODS_VERSION,
577
				'build'   => time(),
578
			),
579
		);
580
581
		if ( is_object( $params ) ) {
582
			$params = get_object_vars( $params );
583
		}
584
585
		$api = pods_api();
586
587
		$pod_ids      = pods_var_raw( 'pods', $params );
588
		$template_ids = pods_var_raw( 'templates', $params );
589
		$page_ids     = pods_var_raw( 'pages', $params );
590
		$helper_ids   = pods_var_raw( 'helpers', $params );
591
592
		if ( ! empty( $pod_ids ) ) {
593
			$api_params = array( 'export' => true );
594
595
			if ( true !== $pod_ids ) {
596
				$api_params['ids'] = (array) $pod_ids;
597
			}
598
599
			$export['pods'] = $api->load_pods( $api_params );
600
601
			$options_ignore = array(
602
				'pod_id',
603
				'old_name',
604
				'object_type',
605
				'object_name',
606
				'object_hierarchical',
607
				'table',
608
				'meta_table',
609
				'pod_table',
610
				'field_id',
611
				'field_index',
612
				'field_slug',
613
				'field_type',
614
				'field_parent',
615
				'field_parent_select',
616
				'meta_field_id',
617
				'meta_field_index',
618
				'meta_field_value',
619
				'pod_field_id',
620
				'pod_field_index',
621
				'object_fields',
622
				'join',
623
				'where',
624
				'where_default',
625
				'orderby',
626
				'pod',
627
				'recurse',
628
				'table_info',
629
				'attributes',
630
				'group',
631
				'grouped',
632
				'developer_mode',
633
				'dependency',
634
				'depends-on',
635
				'excludes-on',
636
			);
637
638
			$field_types = PodsForm::field_types();
639
640
			$field_type_options = array();
641
642
			foreach ( $field_types as $type => $field_type_data ) {
643
				$field_type_options[ $type ] = PodsForm::ui_options( $type );
644
			}
645
646
			foreach ( $export['pods'] as &$pod ) {
0 ignored issues
show
Bug introduced by
The expression $export['pods'] of type array|object|integer|double|string|null|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
647
				if ( isset( $pod['options'] ) ) {
648
					$pod = array_merge( $pod, $pod['options'] );
649
650
					unset( $pod['options'] );
651
				}
652
653
				foreach ( $pod as $option => $option_value ) {
654
					if ( in_array( $option, $options_ignore, true ) || null === $option_value ) {
655
						unset( $pod[ $option ] );
656
					}
657
				}
658
659
				if ( ! empty( $pod['fields'] ) ) {
660
					foreach ( $pod['fields'] as &$field ) {
661
						if ( isset( $field['options'] ) ) {
662
							$field = array_merge( $field, $field['options'] );
663
664
							unset( $field['options'] );
665
						}
666
667
						foreach ( $field as $option => $option_value ) {
668
							if ( in_array( $option, $options_ignore, true ) || null === $option_value ) {
669
								unset( $field[ $option ] );
670
							}
671
						}
672
673
						foreach ( $field_type_options as $type => $options ) {
674
							if ( $type == pods_var( 'type', $field ) ) {
675
								continue;
676
							}
677
678
							foreach ( $options as $option_data ) {
679
								if ( isset( $option_data['group'] ) && is_array( $option_data['group'] ) && ! empty( $option_data['group'] ) ) {
680
									if ( isset( $field[ $option_data['name'] ] ) ) {
681
										unset( $field[ $option_data['name'] ] );
682
									}
683
684
									foreach ( $option_data['group'] as $group_option_data ) {
685
										if ( isset( $field[ $group_option_data['name'] ] ) ) {
686
											unset( $field[ $group_option_data['name'] ] );
687
										}
688
									}
689
								} elseif ( isset( $field[ $option_data['name'] ] ) ) {
690
									unset( $field[ $option_data['name'] ] );
691
								}
692
							}
693
						}//end foreach
694
					}//end foreach
695
				}//end if
696
			}//end foreach
697
		}//end if
698
699
		if ( ! empty( $template_ids ) ) {
700
			$api_params = array();
701
702
			if ( true !== $template_ids ) {
703
				$api_params['ids'] = (array) $template_ids;
704
			}
705
706
			$export['templates'] = $api->load_templates( $api_params );
707
		}
708
709
		if ( ! empty( $page_ids ) ) {
710
			$api_params = array();
711
712
			if ( true !== $page_ids ) {
713
				$api_params['ids'] = (array) $page_ids;
714
			}
715
716
			$export['pages'] = $api->load_pages( $api_params );
717
		}
718
719
		if ( ! empty( $helper_ids ) ) {
720
			$api_params = array();
721
722
			if ( true !== $helper_ids ) {
723
				$api_params['ids'] = (array) $helper_ids;
724
			}
725
726
			$export['helpers'] = $api->load_helpers( $api_params );
727
		}
728
729
		$export = apply_filters( 'pods_packages_export', $export, $params );
730
731
		if ( 1 == count( $export ) ) {
732
			return false;
733
		}
734
735
		$export = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $export, JSON_UNESCAPED_UNICODE ) : json_encode( $export );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
736
737
		return $export;
738
	}
739
}
740