Issues (2873)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

components/Migrate-Packages/Migrate-Packages.php (7 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
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
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
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
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
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