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.

classes/PodsAdmin.php (34 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
2
3
/**
4
 * @package Pods
5
 */
6
class PodsAdmin {
7
8
	/**
9
	 * @var PodsAdmin
10
	 */
11
	public static $instance = null;
12
13
	/**
14
	 * Singleton handling for a basic pods_admin() request
15
	 *
16
	 * @return \PodsAdmin
17
	 *
18
	 * @since 2.3.5
19
	 */
20
	public static function init() {
21
22
		if ( ! is_object( self::$instance ) ) {
23
			self::$instance = new PodsAdmin();
24
		}
25
26
		return self::$instance;
27
	}
28
29
	/**
30
	 * Setup and Handle Admin functionality
31
	 *
32
	 * @return \PodsAdmin
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
33
	 *
34
	 * @license http://www.gnu.org/licenses/gpl-2.0.html
35
	 * @since   2.0
36
	 */
37
	public function __construct() {
38
39
		// Scripts / Stylesheets
40
		add_action( 'admin_enqueue_scripts', array( $this, 'admin_head' ), 20 );
41
42
		// AJAX $_POST fix
43
		add_action( 'admin_init', array( $this, 'admin_init' ), 9 );
44
45
		// Menus
46
		add_action( 'admin_menu', array( $this, 'admin_menu' ), 99 );
47
48
		// AJAX for Admin
49
		add_action( 'wp_ajax_pods_admin', array( $this, 'admin_ajax' ) );
50
		add_action( 'wp_ajax_nopriv_pods_admin', array( $this, 'admin_ajax' ) );
51
52
		// Add Media Bar button for Shortcode
53
		add_action( 'media_buttons', array( $this, 'media_button' ), 12 );
54
55
		// Add the Pods capabilities
56
		add_filter( 'members_get_capabilities', array( $this, 'admin_capabilities' ) );
57
58
		add_action( 'admin_head-media-upload-popup', array( $this, 'register_media_assets' ) );
59
60
		$this->rest_admin();
61
62
	}
63
64
	/**
65
	 * Init the admin area
66
	 *
67
	 * @since 2.0
68
	 */
69
	public function admin_init() {
70
71
		// Fix for plugins that *don't do it right* so we don't cause issues for users
72
		// @codingStandardsIgnoreLine
73
		if ( defined( 'DOING_AJAX' ) && ! empty( $_POST ) ) {
74
			$pods_admin_ajax_actions = array(
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $pods_admin_ajax_actions exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
75
				'pods_admin',
76
				'pods_relationship',
77
				'pods_upload',
78
				'pods_admin_components',
79
			);
80
81
			/**
82
			 * Admin AJAX Callbacks
83
			 *
84
			 * @since unknown
85
			 *
86
			 * @param array $pods_admin_ajax_actions Array of actions to handle.
87
			 */
88
			$pods_admin_ajax_actions = apply_filters( 'pods_admin_ajax_actions', $pods_admin_ajax_actions );
89
90
			if ( in_array( pods_v( 'action' ), $pods_admin_ajax_actions, true ) || in_array( pods_v( 'action', 'post' ), $pods_admin_ajax_actions, true ) ) {
91
				// @codingStandardsIgnoreLine
92
				foreach ( $_POST as $key => $value ) {
93
					if ( 'action' === $key || 0 === strpos( $key, '_podsfix_' ) ) {
94
						continue;
95
					}
96
97
					// @codingStandardsIgnoreLine
98
					unset( $_POST[ $key ] );
99
100
					// @codingStandardsIgnoreLine
101
					$_POST[ '_podsfix_' . $key ] = $value;
102
				}
103
			}
104
		}//end if
105
	}
106
107
	/**
108
	 * Attach requirements to admin header
109
	 *
110
	 * @since 2.0
111
	 */
112
	public function admin_head() {
113
114
		wp_register_script( 'pods-floatmenu', PODS_URL . 'ui/js/floatmenu.js', array(), PODS_VERSION );
115
116
		wp_register_script( 'pods-admin-importer', PODS_URL . 'ui/js/admin-importer.js', array(), PODS_VERSION );
117
118
		wp_register_script( 'pods-upgrade', PODS_URL . 'ui/js/jquery.pods.upgrade.js', array(), PODS_VERSION );
119
120
		wp_register_script( 'pods-migrate', PODS_URL . 'ui/js/jquery.pods.migrate.js', array(), PODS_VERSION );
121
122
		// @codingStandardsIgnoreLine
123
		if ( isset( $_GET['page'] ) ) {
124
			// @codingStandardsIgnoreLine
125
			$page = $_GET['page'];
126
			if ( 'pods' === $page || ( false !== strpos( $page, 'pods-' ) && 0 === strpos( $page, 'pods-' ) ) ) {
127
				?>
128
				<script type="text/javascript">
129
					var PODS_URL = "<?php echo esc_js( PODS_URL ); ?>";
130
				</script>
131
				<?php
132
				wp_enqueue_script( 'jquery' );
133
				wp_enqueue_script( 'jquery-ui-core' );
134
				wp_enqueue_script( 'jquery-ui-sortable' );
135
136
				wp_enqueue_script( 'pods-floatmenu' );
137
138
				wp_enqueue_script( 'jquery-qtip2' );
139
				wp_enqueue_script( 'pods-qtip-init' );
140
141
				wp_enqueue_script( 'pods' );
142
143
				if ( 0 === strpos( $page, 'pods-manage-' ) || 0 === strpos( $page, 'pods-add-new-' ) ) {
144
					wp_enqueue_script( 'post' );
145
				} elseif ( 0 === strpos( $page, 'pods-settings-' ) ) {
146
					wp_enqueue_script( 'post' );
147
				}
148
149
				if ( 'pods-advanced' === $page ) {
150
					wp_register_script( 'pods-advanced', PODS_URL . 'ui/js/advanced.js', array(), PODS_VERSION );
151
					wp_enqueue_script( 'jquery-ui-effects-core', PODS_URL . 'ui/js/jquery-ui/jquery.effects.core.js', array( 'jquery' ), '1.8.8' );
152
					wp_enqueue_script( 'jquery-ui-effects-fade', PODS_URL . 'ui/js/jquery-ui/jquery.effects.fade.js', array( 'jquery' ), '1.8.8' );
153
					wp_enqueue_script( 'jquery-ui-dialog' );
154
					wp_enqueue_script( 'pods-advanced' );
155
				} elseif ( 'pods-packages' === $page ) {
156
					wp_enqueue_style( 'pods-wizard' );
157
				} elseif ( 'pods-wizard' === $page || 'pods-upgrade' === $page || ( in_array(
158
					$page, array(
159
						'pods',
160
						'pods-add-new',
161
					), true
162
				) && in_array(
163
					pods_v( 'action', 'get', 'manage' ), array(
164
						'add',
165
						'manage',
166
					), true
167
				) ) ) {
168
					wp_enqueue_style( 'pods-wizard' );
169
170
					if ( 'pods-upgrade' === $page ) {
171
						wp_enqueue_script( 'pods-upgrade' );
172
					}
173
				}//end if
174
			}//end if
175
		}//end if
176
177
		// New Styles Enqueue
178
		wp_enqueue_style( 'pods-styles' );
179
	}
180
181
	/**
182
	 * Build the admin menus
183
	 *
184
	 * @since 2.0
185
	 */
186
	public function admin_menu() {
187
188
		$advanced_content_types = PodsMeta::$advanced_content_types;
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $advanced_content_types exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
189
		$taxonomies             = PodsMeta::$taxonomies;
190
		$settings               = PodsMeta::$settings;
191
192
		$all_pods = pods_api()->load_pods( array( 'count' => true ) );
193
194
		if ( ! PodsInit::$upgrade_needed || ( pods_is_admin() && 1 === (int) pods_v( 'pods_upgrade_bypass' ) ) ) {
195
			$submenu_items = array();
196
197
			if ( ! empty( $advanced_content_types ) ) {
198
				$submenu = array();
199
200
				$pods_pages = 0;
201
202
				foreach ( (array) $advanced_content_types as $pod ) {
203
					if ( ! isset( $pod['name'] ) || ! isset( $pod['options'] ) || empty( $pod['fields'] ) ) {
204
						continue;
205
					} elseif ( ! pods_is_admin(
206
						array(
207
							'pods',
208
							'pods_content',
209
							'pods_add_' . $pod['name'],
210
							'pods_edit_' . $pod['name'],
211
							'pods_delete_' . $pod['name'],
212
						)
213
					) ) {
214
						continue;
215
					}
216
217
					$pod = apply_filters( 'pods_advanced_content_type_pod_data_' . $pod['name'], $pod, $pod['name'] );
218
					$pod = apply_filters( 'pods_advanced_content_type_pod_data', $pod, $pod['name'] );
219
220
					if ( 1 === (int) pods_v( 'show_in_menu', $pod['options'], 0 ) ) {
221
						$page_title = pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true );
222
						$page_title = apply_filters( 'pods_admin_menu_page_title', $page_title, $pod );
223
224
						$menu_label = pods_v( 'menu_name', $pod['options'], $page_title, true );
225
						$menu_label = apply_filters( 'pods_admin_menu_label', $menu_label, $pod );
226
227
						$singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
228
						$plural_label   = pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true );
229
230
						$menu_location        = pods_v( 'menu_location', $pod['options'], 'objects' );
231
						$menu_location_custom = pods_v( 'menu_location_custom', $pod['options'], '' );
232
233
						$menu_position = pods_v( 'menu_position', $pod['options'], '', true );
234
						$menu_icon     = pods_evaluate_tags( pods_v( 'menu_icon', $pod['options'], '', true ), true );
235
236
						if ( empty( $menu_position ) ) {
237
							$menu_position = null;
238
						}
239
240
						$parent_page = null;
241
242
						if ( pods_is_admin(
243
							array(
244
								'pods',
245
								'pods_content',
246
								'pods_edit_' . $pod['name'],
247
								'pods_delete_' . $pod['name'],
248
							)
249
						) ) {
250
							if ( ! empty( $menu_location_custom ) ) {
251
								if ( ! isset( $submenu_items[ $menu_location_custom ] ) ) {
252
									$submenu_items[ $menu_location_custom ] = array();
253
								}
254
255
								$submenu_items[ $menu_location_custom ][] = array(
256
									$menu_location_custom,
257
									$page_title,
258
									$menu_label,
259
									'read',
260
									'pods-manage-' . $pod['name'],
261
									array( $this, 'admin_content' ),
262
								);
263
264
								continue;
265
							} else {
266
								$pods_pages ++;
267
268
								$page        = 'pods-manage-' . $pod['name'];
269
								$parent_page = $page;
270
271
								if ( empty( $menu_position ) ) {
272
									$menu_position = null;
273
								}
274
								add_menu_page( $page_title, $menu_label, 'read', $parent_page, '', $menu_icon, $menu_position );
275
276
								$all_title = $plural_label;
277
								$all_label = pods_v( 'label_all_items', $pod['options'], __( 'All', 'pods' ) . ' ' . $plural_label );
278
279
								if ( pods_v( 'page' ) === $page ) {
280
									if ( 'edit' === pods_v( 'action', 'get', 'manage' ) ) {
281
										$all_title = pods_v( 'label_edit_item', $pod['options'], __( 'Edit', 'pods' ) . ' ' . $singular_label );
282
									} elseif ( 'add' === pods_v( 'action', 'get', 'manage' ) ) {
283
										$all_title = pods_v( 'label_add_new_item', $pod['options'], __( 'Add New', 'pods' ) . ' ' . $singular_label );
284
									}
285
								}
286
287
								add_submenu_page(
288
									$parent_page, $all_title, $all_label, 'read', $page, array(
289
										$this,
290
										'admin_content',
291
									)
292
								);
293
							}//end if
294
						}//end if
295
296
						if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_add_' . $pod['name'] ) ) ) {
297
							$page = 'pods-add-new-' . $pod['name'];
298
299
							if ( null === $parent_page ) {
300
								$pods_pages ++;
301
302
								$parent_page = $page;
303
304
								if ( empty( $menu_position ) ) {
305
									$menu_position = null;
306
								}
307
								add_menu_page( $page_title, $menu_label, 'read', $parent_page, '', $menu_icon, $menu_position );
308
							}
309
310
							$add_title = pods_v( 'label_add_new_item', $pod['options'], __( 'Add New', 'pods' ) . ' ' . $singular_label );
311
							$add_label = pods_v( 'label_add_new', $pod['options'], __( 'Add New', 'pods' ) );
312
313
							add_submenu_page(
314
								$parent_page, $add_title, $add_label, 'read', $page, array(
315
									$this,
316
									'admin_content',
317
								)
318
							);
319
						}//end if
320
					} else {
321
						$submenu[] = $pod;
322
					}//end if
323
				}//end foreach
324
325
				$submenu = apply_filters( 'pods_admin_menu_secondary_content', $submenu );
326
327
				if ( ! empty( $submenu ) && ( ! defined( 'PODS_DISABLE_CONTENT_MENU' ) || ! PODS_DISABLE_CONTENT_MENU ) ) {
328
					$parent_page = null;
329
330
					foreach ( $submenu as $item ) {
331
						$singular_label = pods_v( 'label_singular', $item['options'], pods_v( 'label', $item, ucwords( str_replace( '_', ' ', $item['name'] ) ), true ), true );
332
						$plural_label   = pods_v( 'label', $item, ucwords( str_replace( '_', ' ', $item['name'] ) ), true );
333
334
						if ( pods_is_admin(
335
							array(
336
								'pods',
337
								'pods_content',
338
								'pods_edit_' . $item['name'],
339
								'pods_delete_' . $item['name'],
340
							)
341
						) ) {
342
							$page = 'pods-manage-' . $item['name'];
343
344
							if ( null === $parent_page ) {
345
								$parent_page = $page;
346
347
								add_menu_page( 'Pods', 'Pods', 'read', $parent_page, null, 'dashicons-pods', '58.5' );
348
							}
349
350
							$all_title = $plural_label;
351
							$all_label = __( 'Manage', 'pods' ) . ' ' . $plural_label;
352
353
							if ( pods_v( 'page' ) === $page ) {
354
								if ( 'edit' === pods_v( 'action', 'get', 'manage' ) ) {
355
									$all_title = __( 'Edit', 'pods' ) . ' ' . $singular_label;
356
								} elseif ( 'add' === pods_v( 'action', 'get', 'manage' ) ) {
357
									$all_title = __( 'Add New', 'pods' ) . ' ' . $singular_label;
358
								}
359
							}
360
361
							add_submenu_page(
362
								$parent_page, $all_title, $all_label, 'read', $page, array(
363
									$this,
364
									'admin_content',
365
								)
366
							);
367
						} elseif ( current_user_can( 'pods_add_' . $item['name'] ) ) {
368
							$page = 'pods-add-new-' . $item['name'];
369
370
							if ( null === $parent_page ) {
371
								$parent_page = $page;
372
373
								add_menu_page( 'Pods', 'Pods', 'read', $parent_page, null, 'dashicons-pods', '58.5' );
374
							}
375
376
							$add_title = __( 'Add New', 'pods' ) . ' ' . $singular_label;
377
							$add_label = __( 'Manage', 'pods' ) . ' ' . $plural_label;
378
379
							add_submenu_page(
380
								$parent_page, $add_title, $add_label, 'read', $page, array(
381
									$this,
382
									'admin_content',
383
								)
384
							);
385
						}//end if
386
					}//end foreach
387
				}//end if
388
			}//end if
389
390
			if ( ! empty( $taxonomies ) ) {
391
				foreach ( (array) $taxonomies as $pod ) {
392
					// Default taxonomy capability
393
					$capability = 'manage_categories';
394
395
					if ( ! empty( $pod['options']['capability_type'] ) ) {
396
						if ( 'custom' === $pod['options']['capability_type'] && ! empty( $pod['options']['capability_type_custom'] ) ) {
397
							$capability = 'manage_' . (string) $pod['options']['capability_type_custom'] . '_terms';
398
						}
399
					}
400
401
					if ( ! pods_is_admin(
402
						array(
403
							'pods',
404
							'pods_content',
405
							'pods_edit_' . $pod['name'],
406
							$capability,
407
						)
408
					) ) {
409
						continue;
410
					}
411
412
					// Check UI settings
413
					if ( 1 !== (int) pods_v( 'show_ui', $pod['options'], 0 ) || 1 !== (int) pods_v( 'show_in_menu', $pod['options'], 0 ) ) {
414
						continue;
415
					}
416
417
					$page_title = pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true );
418
					$page_title = apply_filters( 'pods_admin_menu_page_title', $page_title, $pod );
419
420
					$menu_label = pods_v( 'menu_name', $pod['options'], $page_title, true );
421
					$menu_label = apply_filters( 'pods_admin_menu_label', $menu_label, $pod );
422
423
					$menu_position = pods_v( 'menu_position', $pod['options'], '', true );
424
					$menu_icon     = pods_evaluate_tags( pods_v( 'menu_icon', $pod['options'], '', true ), true );
425
426
					if ( empty( $menu_position ) ) {
427
						$menu_position = null;
428
					}
429
430
					$menu_slug            = 'edit-tags.php?taxonomy=' . $pod['name'];
431
					$menu_location        = pods_v( 'menu_location', $pod['options'], 'default' );
432
					$menu_location_custom = pods_v( 'menu_location_custom', $pod['options'], '' );
433
434
					if ( 'default' === $menu_location ) {
435
						continue;
436
					}
437
438
					$taxonomy_data = get_taxonomy( $pod['name'] );
439
440
					foreach ( (array) $taxonomy_data->object_type as $post_type ) {
441
						if ( 'post' === $post_type ) {
442
							remove_submenu_page( 'edit.php', 'edit-tags.php?taxonomy=' . $pod['name'] );
443
						} elseif ( 'attachment' === $post_type ) {
444
							remove_submenu_page( 'upload.php', 'edit-tags.php?taxonomy=' . $pod['name'] . '&amp;post_type=' . $post_type );
445
						} else {
446
							remove_submenu_page( 'edit.php?post_type=' . $post_type, 'edit-tags.php?taxonomy=' . $pod['name'] . '&amp;post_type=' . $post_type );
447
						}
448
					}
449
450
					if ( 'settings' === $menu_location ) {
451
						add_options_page( $page_title, $menu_label, 'read', $menu_slug );
452
					} elseif ( 'appearances' === $menu_location ) {
453
						add_theme_page( $page_title, $menu_label, 'read', $menu_slug );
454
					} elseif ( 'objects' === $menu_location ) {
455
						if ( empty( $menu_position ) ) {
456
							$menu_position = null;
457
						}
458
						add_menu_page( $page_title, $menu_label, 'read', $menu_slug, '', $menu_icon, $menu_position );
459
					} elseif ( 'top' === $menu_location ) {
460
						add_menu_page( $page_title, $menu_label, 'read', $menu_slug, '', $menu_icon, $menu_position );
461
					} elseif ( 'submenu' === $menu_location && ! empty( $menu_location_custom ) ) {
462
						if ( ! isset( $submenu_items[ $menu_location_custom ] ) ) {
463
							$submenu_items[ $menu_location_custom ] = array();
464
						}
465
466
						$submenu_items[ $menu_location_custom ][] = array(
467
							$menu_location_custom,
468
							$page_title,
469
							$menu_label,
470
							'read',
471
							$menu_slug,
472
							'',
473
						);
474
					}//end if
475
				}//end foreach
476
			}//end if
477
478
			if ( ! empty( $settings ) ) {
479
				foreach ( (array) $settings as $pod ) {
480
					if ( ! pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod['name'] ) ) ) {
481
						continue;
482
					}
483
484
					$page_title = pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true );
485
					$page_title = apply_filters( 'pods_admin_menu_page_title', $page_title, $pod );
486
487
					$menu_label = pods_v( 'menu_name', $pod['options'], $page_title, true );
488
					$menu_label = apply_filters( 'pods_admin_menu_label', $menu_label, $pod );
489
490
					$menu_position = pods_v( 'menu_position', $pod['options'], '', true );
491
					$menu_icon     = pods_evaluate_tags( pods_v( 'menu_icon', $pod['options'], '', true ), true );
492
493
					if ( empty( $menu_position ) ) {
494
						$menu_position = null;
495
					}
496
497
					$menu_slug            = 'pods-settings-' . $pod['name'];
498
					$menu_location        = pods_v( 'menu_location', $pod['options'], 'settings' );
499
					$menu_location_custom = pods_v( 'menu_location_custom', $pod['options'], '' );
500
501
					if ( 'settings' === $menu_location ) {
502
						add_options_page(
503
							$page_title, $menu_label, 'read', $menu_slug, array(
504
								$this,
505
								'admin_content_settings',
506
							)
507
						);
508
					} elseif ( 'appearances' === $menu_location ) {
509
						add_theme_page(
510
							$page_title, $menu_label, 'read', $menu_slug, array(
511
								$this,
512
								'admin_content_settings',
513
							)
514
						);
515
					} elseif ( 'objects' === $menu_location ) {
516
						if ( empty( $menu_position ) ) {
517
							$menu_position = null;
518
						}
519
						add_menu_page(
520
							$page_title, $menu_label, 'read', $menu_slug, array(
521
								$this,
522
								'admin_content_settings',
523
							), $menu_icon, $menu_position
524
						);
525
					} elseif ( 'top' === $menu_location ) {
526
						add_menu_page(
527
							$page_title, $menu_label, 'read', $menu_slug, array(
528
								$this,
529
								'admin_content_settings',
530
							), $menu_icon, $menu_position
531
						);
532
					} elseif ( 'submenu' === $menu_location && ! empty( $menu_location_custom ) ) {
533
						if ( ! isset( $submenu_items[ $menu_location_custom ] ) ) {
534
							$submenu_items[ $menu_location_custom ] = array();
535
						}
536
537
						$submenu_items[ $menu_location_custom ][] = array(
538
							$menu_location_custom,
539
							$page_title,
540
							$menu_label,
541
							'read',
542
							$menu_slug,
543
							array( $this, 'admin_content_settings' ),
544
						);
545
					}//end if
546
				}//end foreach
547
			}//end if
548
549
			foreach ( $submenu_items as $items ) {
550
				foreach ( $items as $item ) {
551
					call_user_func_array( 'add_submenu_page', $item );
552
				}
553
			}
554
555
			$admin_menus = array(
556
				'pods'            => array(
557
					'label'    => __( 'Edit Pods', 'pods' ),
558
					'function' => array( $this, 'admin_setup' ),
559
					'access'   => 'pods',
560
				),
561
				'pods-add-new'    => array(
562
					'label'    => __( 'Add New', 'pods' ),
563
					'function' => array( $this, 'admin_setup' ),
564
					'access'   => 'pods',
565
				),
566
				'pods-components' => array(
567
					'label'    => __( 'Components', 'pods' ),
568
					'function' => array( $this, 'admin_components' ),
569
					'access'   => 'pods_components',
570
				),
571
				'pods-settings'   => array(
572
					'label'    => __( 'Settings', 'pods' ),
573
					'function' => array( $this, 'admin_settings' ),
574
					'access'   => 'pods_settings',
575
				),
576
				'pods-help'       => array(
577
					'label'    => __( 'Help', 'pods' ),
578
					'function' => array( $this, 'admin_help' ),
579
				),
580
			);
581
582
			if ( empty( $all_pods ) ) {
583
				unset( $admin_menus['pods'] );
584
			}
585
586
			add_filter( 'parent_file', array( $this, 'parent_file' ) );
587
		} else {
588
			$admin_menus = array(
589
				'pods-upgrade'  => array(
590
					'label'    => __( 'Upgrade', 'pods' ),
591
					'function' => array( $this, 'admin_upgrade' ),
592
					'access'   => 'manage_options',
593
				),
594
				'pods-settings' => array(
595
					'label'    => __( 'Settings', 'pods' ),
596
					'function' => array( $this, 'admin_settings' ),
597
					'access'   => 'pods_settings',
598
				),
599
				'pods-help'     => array(
600
					'label'    => __( 'Help', 'pods' ),
601
					'function' => array( $this, 'admin_help' ),
602
				),
603
			);
604
605
			add_action( 'admin_notices', array( $this, 'upgrade_notice' ) );
606
		}//end if
607
608
		/**
609
		 * Add or change Pods Admin menu items
610
		 *
611
		 * @param array $admin_menus The submenu items in Pods Admin menu.
612
		 *
613
		 * @since  unknown
614
		 */
615
		$admin_menus = apply_filters( 'pods_admin_menu', $admin_menus );
616
617
		$parent = false;
618
619
		// PODS_LIGHT disables all Pods components so remove the components menu
620
		if ( defined( 'PODS_LIGHT' ) && true === PODS_LIGHT ) {
621
			unset( $admin_menus['pods-components'] );
622
		}
623
624
		if ( ! empty( $admin_menus ) && ( ! defined( 'PODS_DISABLE_ADMIN_MENU' ) || ! PODS_DISABLE_ADMIN_MENU ) ) {
625
			foreach ( $admin_menus as $page => $menu_item ) {
626
				if ( ! pods_is_admin( pods_v( 'access', $menu_item ) ) ) {
627
					continue;
628
				}
629
630
				// Don't just show the help page
631
				if ( false === $parent && 'pods-help' === $page ) {
632
					continue;
633
				}
634
635
				if ( ! isset( $menu_item['label'] ) ) {
636
					$menu_item['label'] = $page;
637
				}
638
639
				if ( false === $parent ) {
640
					$parent = $page;
641
642
					$menu = __( 'Pods Admin', 'pods' );
643
644
					if ( 'pods-upgrade' === $parent ) {
645
						$menu = __( 'Pods Upgrade', 'pods' );
646
					}
647
648
					add_menu_page( $menu, $menu, 'read', $parent, null, 'dashicons-pods' );
649
				}
650
651
				add_submenu_page( $parent, $menu_item['label'], $menu_item['label'], 'read', $page, $menu_item['function'] );
652
653
				if ( 'pods-components' === $page && is_object( PodsInit::$components ) ) {
654
					PodsInit::$components->menu( $parent );
655
				}
656
			}//end foreach
657
		}//end if
658
	}
659
660
	/**
661
	 * Set the correct parent_file to highlight the correct top level menu
662
	 *
663
	 * @param string $parent_file The parent file.
664
	 *
665
	 * @return mixed|string
666
	 *
667
	 * @since unknown
668
	 */
669
	public function parent_file( $parent_file ) {
670
671
		global $current_screen;
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...
672
673
		if ( isset( $current_screen ) && ! empty( $current_screen->taxonomy ) ) {
674
			$taxonomies = PodsMeta::$taxonomies;
675
			if ( ! empty( $taxonomies ) ) {
676
				foreach ( (array) $taxonomies as $pod ) {
677
					if ( $current_screen->taxonomy !== $pod['name'] ) {
678
						continue;
679
					}
680
681
					$menu_slug            = 'edit-tags.php?taxonomy=' . $pod['name'];
682
					$menu_location        = pods_v( 'menu_location', $pod['options'], 'default' );
683
					$menu_location_custom = pods_v( 'menu_location_custom', $pod['options'], '' );
684
685
					if ( 'settings' === $menu_location ) {
686
						$parent_file = 'options-general.php';
687
					} elseif ( 'appearances' === $menu_location ) {
688
						$parent_file = 'themes.php';
689
					} elseif ( 'objects' === $menu_location ) {
690
						$parent_file = $menu_slug;
691
					} elseif ( 'top' === $menu_location ) {
692
						$parent_file = $menu_slug;
693
					} elseif ( 'submenu' === $menu_location && ! empty( $menu_location_custom ) ) {
694
						$parent_file = $menu_location_custom;
695
					}
696
697
					break;
698
				}//end foreach
699
			}//end if
700
		}//end if
701
702
		if ( isset( $current_screen ) && ! empty( $current_screen->post_type ) && is_object( PodsInit::$components ) ) {
703
			global $submenu_file;
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...
704
705
			$components = PodsInit::$components->components;
706
707
			foreach ( $components as $component => $component_data ) {
708
				if ( ! empty( $component_data['MenuPage'] ) && $parent_file === $component_data['MenuPage'] ) {
709
					$parent_file = 'pods';
710
711
					// @codingStandardsIgnoreLine
712
					$submenu_file = $component_data['MenuPage'];
713
				}
714
			}
715
		}
716
717
		return $parent_file;
718
	}
719
720
	/**
721
	 * Show upgrade notice.
722
	 */
723
	public function upgrade_notice() {
724
725
		echo '<div class="error fade"><p>';
726
		// @codingStandardsIgnoreLine
727
		echo sprintf( __( '<strong>NOTICE:</strong> Pods %1$s requires your action to complete the upgrade. Please run the <a href="%2$s">Upgrade Wizard</a>.', 'pods' ), esc_html( PODS_VERSION ), esc_url( admin_url( 'admin.php?page=pods-upgrade' ) ) );
728
		echo '</p></div>';
729
	}
730
731
	/**
732
	 * Create PodsUI content for the administration pages
733
	 */
734
	public function admin_content() {
735
736
		// @codingStandardsIgnoreLine
737
		$pod_name = str_replace( array( 'pods-manage-', 'pods-add-new-' ), '', $_GET['page'] );
738
739
		$pod = pods( $pod_name, pods_v( 'id', 'get', null, true ) );
740
741
		// @codingStandardsIgnoreLine
742
		if ( false !== strpos( $_GET['page'], 'pods-add-new-' ) ) {
743
			// @codingStandardsIgnoreLine
744
			$_GET['action'] = pods_v( 'action', 'get', 'add' );
745
		}
746
747
		$pod->ui();
748
	}
749
750
	/**
751
	 * Create PodsUI content for the settings administration pages
752
	 */
753
	public function admin_content_settings() {
754
755
		// @codingStandardsIgnoreLine
756
		$pod_name = str_replace( 'pods-settings-', '', $_GET['page'] );
757
758
		$pod = pods( $pod_name );
759
760
		if ( 'custom' !== pods_v( 'ui_style', $pod->pod_data['options'], 'settings', true ) ) {
761
			$actions_disabled = array(
762
				'manage'    => 'manage',
763
				'add'       => 'add',
764
				'delete'    => 'delete',
765
				'duplicate' => 'duplicate',
766
				'view'      => 'view',
767
				'export'    => 'export',
768
			);
769
770
			// @codingStandardsIgnoreLine
771
			$_GET['action'] = 'edit';
772
773
			$page_title = pods_v( 'label', $pod->pod_data, ucwords( str_replace( '_', ' ', $pod->pod_data['name'] ) ), true );
774
			$page_title = apply_filters( 'pods_admin_menu_page_title', $page_title, $pod->pod_data );
775
776
			$ui = array(
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ui. 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...
777
				'pod'              => $pod,
778
				'fields'           => array(
779
					'edit' => $pod->pod_data['fields'],
780
				),
781
				'header'           => array(
782
					'edit' => $page_title,
783
				),
784
				'label'            => array(
785
					'edit' => __( 'Save Changes', 'pods' ),
786
				),
787
				'style'            => pods_v( 'ui_style', $pod->pod_data['options'], 'settings', true ),
788
				'icon'             => pods_evaluate_tags( pods_v( 'menu_icon', $pod->pod_data['options'] ), true ),
789
				'actions_disabled' => $actions_disabled,
790
			);
791
792
			$ui = apply_filters( 'pods_admin_ui_' . $pod->pod, apply_filters( 'pods_admin_ui', $ui, $pod->pod, $pod ), $pod->pod, $pod );
793
794
			// Force disabled actions, do not pass go, do not collect $two_hundred
795
			$ui['actions_disabled'] = $actions_disabled;
796
797
			pods_ui( $ui );
798
		} else {
799
			do_action( 'pods_admin_ui_custom', $pod );
800
			do_action( 'pods_admin_ui_custom_' . $pod->pod, $pod );
801
		}//end if
802
	}
803
804
	/**
805
	 * Add media button for Pods shortcode
806
	 *
807
	 * @param string $context Media button context.
0 ignored issues
show
Should the type for parameter $context not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
808
	 *
809
	 * @return string
0 ignored issues
show
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
810
	 */
811
	public function media_button( $context = null ) {
812
813
		// If shortcodes are disabled don't show the button
814
		if ( defined( 'PODS_DISABLE_SHORTCODE' ) && PODS_DISABLE_SHORTCODE ) {
815
			return '';
816
		}
817
818
		/**
819
		 * Filter to remove Pods shortcode button from the post editor.
820
		 *
821
		 * @param bool   $show_button Set to false to block the shortcode button from appearing.
822
		 * @param string $context     Media button context.
823
		 *
824
		 * @since 2.3.19
825
		 */
826
		if ( ! apply_filters( 'pods_admin_media_button', true, $context ) ) {
827
			return '';
828
		}
829
830
		$current_page = basename( $_SERVER['PHP_SELF'] );
831
		$current_page = explode( '?', $current_page );
832
		$current_page = explode( '#', $current_page[0] );
833
		$current_page = $current_page[0];
834
835
		// Only show the button on post type pages
836
		if ( ! in_array(
837
			$current_page, array(
838
				'post-new.php',
839
				'post.php',
840
			), true
841
		) ) {
842
			return '';
843
		}
844
845
		add_action( 'admin_footer', array( $this, 'mce_popup' ) );
846
847
		echo '<a href="#TB_inline?width=640&inlineId=pods_shortcode_form" class="thickbox button" id="add_pod_button" title="Pods Shortcode"><img style="padding: 0px 6px 0px 0px; margin: -3px 0px 0px;" src="' . esc_url( PODS_URL . 'ui/images/icon16.png' ) . '" alt="' . esc_attr__( 'Pods Shortcode', 'pods' ) . '" />' . esc_html__( 'Pods Shortcode', 'pods' ) . '</a>';
848
	}
849
850
	/**
851
	 * Enqueue assets for Media Library Popup
852
	 */
853
	public function register_media_assets() {
854
855
		if ( 'pods_media_attachment' === pods_v( 'inlineId' ) ) {
856
			wp_enqueue_style( 'pods-styles' );
857
		}
858
	}
859
860
	/**
861
	 * Output Pods shortcode popup window
862
	 */
863
	public function mce_popup() {
864
865
		pods_view( PODS_DIR . 'ui/admin/shortcode.php', compact( array_keys( get_defined_vars() ) ) );
866
	}
867
868
	/**
869
	 * Handle main Pods Setup area for managing Pods and Fields
870
	 */
871
	public function admin_setup() {
872
873
		$pods = pods_api()->load_pods( array( 'fields' => false ) );
874
875
		$view = pods_v( 'view', 'get', 'all', true );
876
877
		// @codingStandardsIgnoreLine
878
		if ( empty( $pods ) && ! isset( $_GET['action'] ) ) {
879
			// @codingStandardsIgnoreLine
880
			$_GET['action'] = 'add';
881
		}
882
883
		// @codingStandardsIgnoreLine
884
		if ( 'pods-add-new' === $_GET['page'] ) {
885
			// @codingStandardsIgnoreLine
886
			if ( isset( $_GET['action'] ) && 'add' !== $_GET['action'] ) {
887
				pods_redirect(
888
					pods_query_arg(
889
						array(
890
							'page'   => 'pods',
891
							// @codingStandardsIgnoreLine
892
							'action' => $_GET['action'],
893
						)
894
					)
895
				);
896
			} else {
897
				// @codingStandardsIgnoreLine
898
				$_GET['action'] = 'add';
899
			}
900
			// @codingStandardsIgnoreLine
901
		} elseif ( isset( $_GET['action'] ) && 'add' === $_GET['action'] ) {
902
			pods_redirect(
903
				pods_query_arg(
904
					array(
905
						'page'   => 'pods-add-new',
906
						'action' => '',
907
					)
908
				)
909
			);
910
		}//end if
911
912
		$types = array(
913
			'post_type' => __( 'Post Type (extended)', 'pods' ),
914
			'taxonomy'  => __( 'Taxonomy (extended)', 'pods' ),
915
			'cpt'       => __( 'Custom Post Type', 'pods' ),
916
			'ct'        => __( 'Custom Taxonomy', 'pods' ),
917
			'user'      => __( 'User (extended)', 'pods' ),
918
			'media'     => __( 'Media (extended)', 'pods' ),
919
			'comment'   => __( 'Comments (extended)', 'pods' ),
920
			'pod'       => __( 'Advanced Content Type', 'pods' ),
921
			'settings'  => __( 'Custom Settings Page', 'pods' ),
922
		);
923
924
		$row = false;
925
926
		$pod_types_found = array();
927
928
		$fields = array(
929
			'label'       => array( 'label' => __( 'Label', 'pods' ) ),
930
			'name'        => array( 'label' => __( 'Name', 'pods' ) ),
931
			'type'        => array( 'label' => __( 'Type', 'pods' ) ),
932
			'storage'     => array(
933
				'label' => __( 'Storage Type', 'pods' ),
934
				'width' => '10%',
935
			),
936
			'field_count' => array(
937
				'label' => __( 'Number of Fields', 'pods' ),
938
				'width' => '8%',
939
			),
940
		);
941
942
		$total_fields = 0;
943
944
		foreach ( $pods as $k => $pod ) {
0 ignored issues
show
The expression $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...
945
			if ( isset( $types[ $pod['type'] ] ) ) {
946
				if ( in_array(
947
					$pod['type'], array(
948
						'post_type',
949
						'taxonomy',
950
					), true
951
				) ) {
952
					if ( empty( $pod['object'] ) ) {
953
						if ( 'post_type' === $pod['type'] ) {
954
							$pod['type'] = 'cpt';
955
						} else {
956
							$pod['type'] = 'ct';
957
						}
958
					}
959
				}
960
961
				if ( ! isset( $pod_types_found[ $pod['type'] ] ) ) {
962
					$pod_types_found[ $pod['type'] ] = 1;
963
				} else {
964
					$pod_types_found[ $pod['type'] ] ++;
965
				}
966
967
				if ( 'all' !== $view && $view !== $pod['type'] ) {
968
					unset( $pods[ $k ] );
969
970
					continue;
971
				}
972
973
				$pod['real_type'] = $pod['type'];
974
				$pod['type']      = $types[ $pod['type'] ];
975
			} elseif ( 'all' !== $view ) {
976
				continue;
977
			}//end if
978
979
			$pod['storage'] = ucwords( $pod['storage'] );
980
981
			// @codingStandardsIgnoreLine
982
			if ( $pod['id'] == pods_v( 'id' ) && 'delete' !== pods_v( 'action' ) ) {
983
				$row = $pod;
984
			}
985
986
			$pod = array(
987
				'id'          => $pod['id'],
988
				'label'       => pods_v( 'label', $pod ),
989
				'name'        => pods_v( 'name', $pod ),
990
				'object'      => pods_v( 'object', $pod ),
991
				'type'        => pods_v( 'type', $pod ),
992
				'real_type'   => pods_v( 'real_type', $pod ),
993
				'storage'     => pods_v( 'storage', $pod ),
994
				'field_count' => count( $pod['fields'] ),
995
			);
996
997
			$total_fields += $pod['field_count'];
998
999
			$pods[ $k ] = $pod;
1000
		}//end foreach
1001
1002
		if ( false === $row && 0 < pods_v( 'id' ) && 'delete' !== pods_v( 'action' ) ) {
1003
			pods_message( 'Pod not found', 'error' );
1004
1005
			// @codingStandardsIgnoreLine
1006
			unset( $_GET['id'], $_GET['action'] );
1007
		}
1008
1009
		$ui = array(
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ui. 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...
1010
			'data'             => $pods,
1011
			'row'              => $row,
1012
			'total'            => count( $pods ),
1013
			'total_found'      => count( $pods ),
1014
			'items'            => 'Pods',
1015
			'item'             => 'Pod',
1016
			'fields'           => array(
1017
				'manage' => $fields,
1018
			),
1019
			'actions_disabled' => array( 'view', 'export' ),
1020
			'actions_custom'   => array(
1021
				'add'       => array( $this, 'admin_setup_add' ),
1022
				'edit'      => array( $this, 'admin_setup_edit' ),
1023
				'duplicate' => array(
1024
					'callback'          => array( $this, 'admin_setup_duplicate' ),
1025
					'restrict_callback' => array( $this, 'admin_setup_duplicate_restrict' ),
1026
				),
1027
				'reset'     => array(
1028
					'label'             => __( 'Delete All Items', 'pods' ),
1029
					'confirm'           => __( 'Are you sure you want to delete all items from this Pod? If this is an extended Pod, it will remove the original items extended too.', 'pods' ),
1030
					'callback'          => array( $this, 'admin_setup_reset' ),
1031
					'restrict_callback' => array( $this, 'admin_setup_reset_restrict' ),
1032
					'nonce'             => true,
1033
				),
1034
				'delete'    => array( $this, 'admin_setup_delete' ),
1035
			),
1036
			'action_links'     => array(
1037
				'add' => pods_query_arg(
1038
					array(
1039
						'page'   => 'pods-add-new',
1040
						'action' => '',
1041
						'id'     => '',
1042
						'do'     => '',
1043
					)
1044
				),
1045
			),
1046
			'search'           => false,
1047
			'searchable'       => false,
1048
			'sortable'         => true,
1049
			'pagination'       => false,
1050
			'extra'            => array(
1051
				'total' => ', ' . number_format_i18n( $total_fields ) . ' ' . _n( 'field', 'fields', $total_fields, 'pods' ),
1052
			),
1053
		);
1054
1055
		if ( 1 < count( $pod_types_found ) ) {
1056
			$ui['views']            = array( 'all' => __( 'All', 'pods' ) );
1057
			$ui['view']             = $view;
1058
			$ui['heading']          = array( 'views' => __( 'Type', 'pods' ) );
1059
			$ui['filters_enhanced'] = true;
1060
1061
			foreach ( $pod_types_found as $pod_type => $number_found ) {
1062
				$ui['views'][ $pod_type ] = $types[ $pod_type ];
1063
			}
1064
		}
1065
1066
		pods_ui( $ui );
1067
	}
1068
1069
	/**
1070
	 * Get the add page of an object
1071
	 *
1072
	 * @param PodsUI $obj PodsUI object.
1073
	 */
1074
	public function admin_setup_add( $obj ) {
1075
1076
		pods_view( PODS_DIR . 'ui/admin/setup-add.php', compact( array_keys( get_defined_vars() ) ) );
1077
	}
1078
1079
	/**
1080
	 * Get the edit page of an object
1081
	 *
1082
	 * @param boolean $duplicate Whether the screen is for duplicating.
1083
	 * @param PodsUI  $obj       PodsUI object.
1084
	 */
1085
	public function admin_setup_edit( $duplicate, $obj ) {
1086
1087
		pods_view( PODS_DIR . 'ui/admin/setup-edit.php', compact( array_keys( get_defined_vars() ) ) );
1088
	}
1089
1090
	/**
1091
	 * Get list of Pod option tabs
1092
	 *
1093
	 * @param array $pod Pod options.
1094
	 *
1095
	 * @return array
1096
	 */
1097
	public function admin_setup_edit_tabs( $pod ) {
1098
1099
		$fields   = true;
1100
		$labels   = false;
1101
		$admin_ui = false;
1102
		$advanced = false;
1103
1104
		if ( 'post_type' === pods_v( 'type', $pod ) && '' === pods_v( 'object', $pod ) ) {
1105
			$labels   = true;
1106
			$admin_ui = true;
1107
			$advanced = true;
1108
		} elseif ( 'taxonomy' === pods_v( 'type', $pod ) && '' === pods_v( 'object', $pod ) ) {
1109
			$labels   = true;
1110
			$admin_ui = true;
1111
			$advanced = true;
1112
		} elseif ( 'pod' === pods_v( 'type', $pod ) ) {
1113
			$labels   = true;
1114
			$admin_ui = true;
1115
			$advanced = true;
1116
		} elseif ( 'settings' === pods_v( 'type', $pod ) ) {
1117
			$labels   = true;
1118
			$admin_ui = true;
1119
		}
1120
1121
		if ( ! function_exists( 'get_term_meta' ) && 'none' === pods_v( 'storage', $pod, 'none', true ) && 'taxonomy' === pods_v( 'type', $pod ) ) {
1122
			$fields = false;
1123
		}
1124
1125
		$tabs = array();
1126
1127
		if ( $fields ) {
1128
			$tabs['manage-fields'] = __( 'Manage Fields', 'pods' );
1129
		}
1130
1131
		if ( $labels ) {
1132
			$tabs['labels'] = __( 'Labels', 'pods' );
1133
		}
1134
1135
		if ( $admin_ui ) {
1136
			$tabs['admin-ui'] = __( 'Admin UI', 'pods' );
1137
		}
1138
1139
		if ( $advanced ) {
1140
			$tabs['advanced'] = __( 'Advanced Options', 'pods' );
1141
		}
1142
1143
		if ( 'taxonomy' === pods_v( 'type', $pod ) && ! $fields ) {
1144
			$tabs['extra-fields'] = __( 'Extra Fields', 'pods' );
1145
		}
1146
1147
		$addtl_args = compact( array( 'fields', 'labels', 'admin_ui', 'advanced' ) );
1148
1149
		/**
1150
		 * Add or modify tabs in Pods editor for a specific Pod
1151
		 *
1152
		 * @param array  $tabs       Tabs to set.
1153
		 * @param object $pod        Current Pods object.
1154
		 * @param array  $addtl_args Additional args.
1155
		 *
1156
		 * @since  unknown
1157
		 */
1158
		$tabs = apply_filters( 'pods_admin_setup_edit_tabs_' . $pod['type'] . '_' . $pod['name'], $tabs, $pod, $addtl_args );
1159
1160
		/**
1161
		 * Add or modify tabs for any Pod in Pods editor of a specific post type.
1162
		 */
1163
		$tabs = apply_filters( 'pods_admin_setup_edit_tabs_' . $pod['type'], $tabs, $pod, $addtl_args );
1164
1165
		/**
1166
		 * Add or modify tabs in Pods editor for all pods.
1167
		 */
1168
		$tabs = apply_filters( 'pods_admin_setup_edit_tabs', $tabs, $pod, $addtl_args );
1169
1170
		return $tabs;
1171
	}
1172
1173
	/**
1174
	 * Get list of Pod options
1175
	 *
1176
	 * @param array $pod Pod options.
1177
	 *
1178
	 * @return array
1179
	 */
1180
	public function admin_setup_edit_options( $pod ) {
1181
1182
		$options = array();
1183
1184
		if ( '' === pods_v( 'object', $pod ) && 'settings' !== pods_v( 'type', $pod ) ) {
1185
			$labels = array(
1186
				'label'                            => array(
1187
					'label'           => __( 'Label', 'pods' ),
1188
					'help'            => __( 'help', 'pods' ),
1189
					'type'            => 'text',
1190
					'default'         => str_replace( '_', ' ', pods_v( 'name', $pod ) ),
1191
					'text_max_length' => 30,
1192
				),
1193
				'label_singular'                   => array(
1194
					'label'           => __( 'Singular Label', 'pods' ),
1195
					'help'            => __( 'help', 'pods' ),
1196
					'type'            => 'text',
1197
					'default'         => pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ),
1198
					'text_max_length' => 30,
1199
				),
1200
				'label_add_new'                    => array(
1201
					'label'       => __( 'Add New', 'pods' ),
1202
					'help'        => __( 'help', 'pods' ),
1203
					'type'        => 'text',
1204
					'default'     => '',
1205
					'object_type' => array( 'post_type', 'pod' ),
1206
				),
1207
				'label_add_new_item'               => array(
1208
					'label'   => __( 'Add new <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1209
					'help'    => __( 'help', 'pods' ),
1210
					'type'    => 'text',
1211
					'default' => '',
1212
				),
1213
				'label_new_item'                   => array(
1214
					'label'       => __( 'New <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1215
					'help'        => __( 'help', 'pods' ),
1216
					'type'        => 'text',
1217
					'default'     => '',
1218
					'object_type' => array( 'post_type', 'pod' ),
1219
				),
1220
				'label_new_item_name'              => array(
1221
					'label'       => __( 'New <span class="pods-slugged" data-sluggable="label_singular">Item</span> Name', 'pods' ),
1222
					'help'        => __( 'help', 'pods' ),
1223
					'type'        => 'text',
1224
					'default'     => '',
1225
					'object_type' => array( 'taxonomy' ),
1226
				),
1227
				'label_edit'                       => array(
1228
					'label'       => __( 'Edit', 'pods' ),
1229
					'help'        => __( 'help', 'pods' ),
1230
					'type'        => 'text',
1231
					'default'     => '',
1232
					'object_type' => array( 'pod' ),
1233
				),
1234
				'label_edit_item'                  => array(
1235
					'label'   => __( 'Edit <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1236
					'help'    => __( 'help', 'pods' ),
1237
					'type'    => 'text',
1238
					'default' => '',
1239
				),
1240
				'label_update_item'                => array(
1241
					'label'       => __( 'Update <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1242
					'help'        => __( 'help', 'pods' ),
1243
					'type'        => 'text',
1244
					'default'     => '',
1245
					'object_type' => array( 'taxonomy', 'pod' ),
1246
				),
1247
				'label_duplicate'                  => array(
1248
					'label'       => __( 'Duplicate', 'pods' ),
1249
					'help'        => __( 'help', 'pods' ),
1250
					'type'        => 'text',
1251
					'default'     => '',
1252
					'object_type' => array( 'pod' ),
1253
				),
1254
				'label_duplicate_item'             => array(
1255
					'label'       => __( 'Duplicate <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1256
					'help'        => __( 'help', 'pods' ),
1257
					'type'        => 'text',
1258
					'default'     => '',
1259
					'object_type' => array( 'pod' ),
1260
				),
1261
				'label_delete_item'                => array(
1262
					'label'       => __( 'Delete <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1263
					'help'        => __( 'help', 'pods' ),
1264
					'type'        => 'text',
1265
					'default'     => '',
1266
					'object_type' => array( 'pod' ),
1267
				),
1268
				'label_view'                       => array(
1269
					'label'       => __( 'View', 'pods' ),
1270
					'help'        => __( 'help', 'pods' ),
1271
					'type'        => 'text',
1272
					'default'     => '',
1273
					'object_type' => array( 'pod' ),
1274
				),
1275
				'label_view_item'                  => array(
1276
					'label'   => __( 'View <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1277
					'help'    => __( 'help', 'pods' ),
1278
					'type'    => 'text',
1279
					'default' => '',
1280
				),
1281
				'label_view_items'                 => array(
1282
					'label'       => __( 'View <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1283
					'help'        => __( 'help', 'pods' ),
1284
					'type'        => 'text',
1285
					'default'     => '',
1286
					'object_type' => array( 'post_type' ),
1287
				),
1288
				'label_back_to_manage'             => array(
1289
					'label'       => __( 'Back to Manage', 'pods' ),
1290
					'help'        => __( 'help', 'pods' ),
1291
					'type'        => 'text',
1292
					'default'     => '',
1293
					'object_type' => array( 'pod' ),
1294
				),
1295
				'label_manage'                     => array(
1296
					'label'       => __( 'Manage', 'pods' ),
1297
					'help'        => __( 'help', 'pods' ),
1298
					'type'        => 'text',
1299
					'default'     => '',
1300
					'object_type' => array( 'pod' ),
1301
				),
1302
				'label_manage_items'               => array(
1303
					'label'       => __( 'Manage <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1304
					'help'        => __( 'help', 'pods' ),
1305
					'type'        => 'text',
1306
					'default'     => '',
1307
					'object_type' => array( 'pod' ),
1308
				),
1309
				'label_reorder'                    => array(
1310
					'label'       => __( 'Reorder', 'pods' ),
1311
					'help'        => __( 'help', 'pods' ),
1312
					'type'        => 'text',
1313
					'default'     => '',
1314
					'object_type' => array( 'pod' ),
1315
				),
1316
				'label_reorder_items'              => array(
1317
					'label'       => __( 'Reorder <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1318
					'help'        => __( 'help', 'pods' ),
1319
					'type'        => 'text',
1320
					'default'     => '',
1321
					'object_type' => array( 'pod' ),
1322
				),
1323
				'label_all_items'                  => array(
1324
					'label'   => __( 'All <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1325
					'help'    => __( 'help', 'pods' ),
1326
					'type'    => 'text',
1327
					'default' => '',
1328
				),
1329
				'label_search'                     => array(
1330
					'label'       => __( 'Search', 'pods' ),
1331
					'help'        => __( 'help', 'pods' ),
1332
					'type'        => 'text',
1333
					'default'     => '',
1334
					'object_type' => array( 'pod' ),
1335
				),
1336
				'label_search_items'               => array(
1337
					'label'   => __( 'Search <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1338
					'help'    => __( 'help', 'pods' ),
1339
					'type'    => 'text',
1340
					'default' => '',
1341
				),
1342
				'label_popular_items'              => array(
1343
					'label'       => __( 'Popular <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1344
					'help'        => __( 'help', 'pods' ),
1345
					'type'        => 'text',
1346
					'default'     => '',
1347
					'object_type' => array( 'taxonomy' ),
1348
				),
1349
				// @todo Why was label_parent added previously? Can't find it in WP
1350
				'label_parent'                     => array(
1351
					'label'       => __( 'Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1352
					'help'        => __( 'help', 'pods' ),
1353
					'type'        => 'text',
1354
					'default'     => '',
1355
					'object_type' => array( 'post_type', 'pod' ),
1356
				),
1357
				'label_parent_item'                => array(
1358
					'label'       => __( 'Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1359
					'help'        => __( 'help', 'pods' ),
1360
					'type'        => 'text',
1361
					'default'     => '',
1362
					'object_type' => array( 'taxonomy' ),
1363
				),
1364
				'label_parent_item_colon'          => array(
1365
					'label'   => __( 'Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>:', 'pods' ),
1366
					'help'    => __( 'help', 'pods' ),
1367
					'type'    => 'text',
1368
					'default' => '',
1369
				),
1370
				'label_not_found'                  => array(
1371
					'label'   => __( 'Not Found', 'pods' ),
1372
					'help'    => __( 'help', 'pods' ),
1373
					'type'    => 'text',
1374
					'default' => '',
1375
				),
1376
				'label_no_items_found'             => array(
1377
					'label'       => __( 'No <span class="pods-slugged" data-sluggable="label_singular">Item</span> Found', 'pods' ),
1378
					'help'        => __( 'help', 'pods' ),
1379
					'type'        => 'text',
1380
					'default'     => '',
1381
					'object_type' => array( 'pod' ),
1382
				),
1383
				'label_not_found_in_trash'         => array(
1384
					'label'       => __( 'Not Found in Trash', 'pods' ),
1385
					'help'        => __( 'help', 'pods' ),
1386
					'type'        => 'text',
1387
					'default'     => '',
1388
					'object_type' => array( 'post_type', 'pod' ),
1389
				),
1390
				'label_archives'                   => array(
1391
					'label'       => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> Archives', 'pods' ),
1392
					'help'        => __( 'help', 'pods' ),
1393
					'type'        => 'text',
1394
					'default'     => '',
1395
					'object_type' => array( 'post_type' ),
1396
				),
1397
				'label_attributes'                 => array(
1398
					'label'       => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> Attributes', 'pods' ),
1399
					'help'        => __( 'help', 'pods' ),
1400
					'type'        => 'text',
1401
					'default'     => '',
1402
					'object_type' => array( 'post_type' ),
1403
				),
1404
				'label_insert_into_item'           => array(
1405
					'label'       => __( 'Insert into <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1406
					'help'        => __( 'help', 'pods' ),
1407
					'type'        => 'text',
1408
					'default'     => '',
1409
					'object_type' => array( 'post_type' ),
1410
				),
1411
				'label_uploaded_to_this_item'      => array(
1412
					'label'       => __( 'Uploaded to this <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1413
					'help'        => __( 'help', 'pods' ),
1414
					'type'        => 'text',
1415
					'default'     => '',
1416
					'object_type' => array( 'post_type' ),
1417
				),
1418
				'label_featured_image'             => array(
1419
					'label'       => __( 'Featured Image', 'pods' ),
1420
					'help'        => __( 'help', 'pods' ),
1421
					'type'        => 'text',
1422
					'default'     => '',
1423
					// 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1424
					'object_type' => array( 'post_type' ),
1425
				),
1426
				'label_set_featured_image'         => array(
1427
					'label'       => __( 'Set featured Image', 'pods' ),
1428
					'help'        => __( 'help', 'pods' ),
1429
					'type'        => 'text',
1430
					'default'     => '',
1431
					// 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1432
					'object_type' => array( 'post_type' ),
1433
				),
1434
				'label_remove_featured_image'      => array(
1435
					'label'       => __( 'Remove featured Image', 'pods' ),
1436
					'help'        => __( 'help', 'pods' ),
1437
					'type'        => 'text',
1438
					'default'     => '',
1439
					// 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1440
					'object_type' => array( 'post_type' ),
1441
				),
1442
				'label_use_featured_image'         => array(
1443
					'label'       => __( 'Use as featured Image', 'pods' ),
1444
					'help'        => __( 'help', 'pods' ),
1445
					'type'        => 'text',
1446
					'default'     => '',
1447
					// 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1448
					'object_type' => array( 'post_type' ),
1449
				),
1450
				'label_filter_items_list'          => array(
1451
					'label'       => __( 'Filter <span class="pods-slugged" data-sluggable="label">Items</span> lists', 'pods' ),
1452
					'help'        => __( 'help', 'pods' ),
1453
					'type'        => 'text',
1454
					'default'     => '',
1455
					'object_type' => array( 'post_type' ),
1456
				),
1457
				'label_items_list_navigation'      => array(
1458
					'label'       => __( '<span class="pods-slugged" data-sluggable="label">Items</span> list navigation', 'pods' ),
1459
					'help'        => __( 'help', 'pods' ),
1460
					'type'        => 'text',
1461
					'default'     => '',
1462
					'object_type' => array( 'post_type', 'taxonomy' ),
1463
				),
1464
				'label_items_list'                 => array(
1465
					'label'       => __( '<span class="pods-slugged" data-sluggable="label">Items</span> list', 'pods' ),
1466
					'help'        => __( 'help', 'pods' ),
1467
					'type'        => 'text',
1468
					'default'     => '',
1469
					'object_type' => array( 'post_type', 'taxonomy' ),
1470
				),
1471
				'label_separate_items_with_commas' => array(
1472
					'label'       => __( 'Separate <span class="pods-slugged-lower" data-sluggable="label">items</span> with commas', 'pods' ),
1473
					'help'        => __( 'help', 'pods' ),
1474
					'type'        => 'text',
1475
					'default'     => '',
1476
					'object_type' => array( 'taxonomy' ),
1477
				),
1478
				'label_add_or_remove_items'        => array(
1479
					'label'       => __( 'Add or remove <span class="pods-slugged-lower" data-sluggable="label">items</span>', 'pods' ),
1480
					'help'        => __( 'help', 'pods' ),
1481
					'type'        => 'text',
1482
					'default'     => '',
1483
					'object_type' => array( 'taxonomy' ),
1484
				),
1485
				'label_choose_from_the_most_used'  => array(
1486
					'label'       => __( 'Choose from the most used <span class="pods-slugged-lower" data-sluggable="label">items</span>', 'pods' ),
1487
					'help'        => __( 'help', 'pods' ),
1488
					'type'        => 'text',
1489
					'default'     => '',
1490
					'object_type' => array( 'taxonomy' ),
1491
				),
1492
				'label_no_terms'                   => array(
1493
					'label'       => __( 'No <span class="pods-slugged-lower" data-sluggable="label">items</span>', 'pods' ),
1494
					'help'        => __( 'help', 'pods' ),
1495
					'type'        => 'text',
1496
					'default'     => '',
1497
					'object_type' => array( 'taxonomy' ),
1498
				),
1499
			);
1500
1501
			$options['labels'] = array();
1502
1503
			/**
1504
			 * Filter through all labels if they have an object_type set and match it against the current object type
1505
			 */
1506
			foreach ( $labels as $label => $labeldata ) {
1507
				if ( array_key_exists( 'object_type', $labeldata ) ) {
1508
					if ( in_array( pods_v( 'type', $pod ), $labeldata['object_type'], true ) ) {
1509
						// Do not add the object_type to the actual label data
1510
						unset( $labeldata['object_type'] );
1511
						$options['labels'][ $label ] = $labeldata;
1512
					}
1513
				} else {
1514
					$options['labels'][ $label ] = $labeldata;
1515
				}
1516
			}
1517
		} elseif ( 'settings' === pods_v( 'type', $pod ) ) {
1518
1519
			$options['labels'] = array(
1520
				'label'     => array(
1521
					'label'           => __( 'Page Title', 'pods' ),
1522
					'help'            => __( 'help', 'pods' ),
1523
					'type'            => 'text',
1524
					'default'         => str_replace( '_', ' ', pods_v( 'name', $pod ) ),
1525
					'text_max_length' => 30,
1526
				),
1527
				'menu_name' => array(
1528
					'label'           => __( 'Menu Name', 'pods' ),
1529
					'help'            => __( 'help', 'pods' ),
1530
					'type'            => 'text',
1531
					'default'         => pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ),
1532
					'text_max_length' => 30,
1533
				),
1534
			);
1535
		}//end if
1536
1537
		if ( 'post_type' === $pod['type'] ) {
1538
			$options['admin-ui'] = array(
1539
				'description'          => array(
1540
					'label'   => __( 'Post Type Description', 'pods' ),
1541
					'help'    => __( 'A short descriptive summary of what the post type is.', 'pods' ),
1542
					'type'    => 'text',
1543
					'default' => '',
1544
				),
1545
				'show_ui'              => array(
1546
					'label'             => __( 'Show Admin UI', 'pods' ),
1547
					'help'              => __( 'Whether to generate a default UI for managing this post type in the admin.', 'pods' ),
1548
					'type'              => 'boolean',
1549
					'default'           => pods_v( 'public', $pod, true ),
1550
					'boolean_yes_label' => '',
1551
				),
1552
				'show_in_menu'         => array(
1553
					'label'             => __( 'Show Admin Menu in Dashboard', 'pods' ),
1554
					'help'              => __( 'Whether to show the post type in the admin menu.', 'pods' ),
1555
					'type'              => 'boolean',
1556
					'default'           => pods_v( 'public', $pod, true ),
1557
					'dependency'        => true,
1558
					'boolean_yes_label' => '',
1559
				),
1560
				'menu_location_custom' => array(
1561
					'label'      => __( 'Parent Menu ID (optional)', 'pods' ),
1562
					'help'       => __( 'help', 'pods' ),
1563
					'type'       => 'text',
1564
					'depends-on' => array( 'show_in_menu' => true ),
1565
				),
1566
				'menu_name'            => array(
1567
					'label'      => __( 'Menu Name', 'pods' ),
1568
					'help'       => __( 'help', 'pods' ),
1569
					'type'       => 'text',
1570
					'default'    => '',
1571
					'depends-on' => array( 'show_in_menu' => true ),
1572
				),
1573
				'menu_position'        => array(
1574
					'label'              => __( 'Menu Position', 'pods' ),
1575
					'help'               => __( 'help', 'pods' ),
1576
					'type'               => 'number',
1577
					'number_decimals'    => 2,
1578
					'number_format'      => '9999.99',
1579
					'number_format_soft' => 1,
1580
					'default'            => 0,
1581
					'depends-on'         => array( 'show_in_menu' => true ),
1582
				),
1583
				'menu_icon'            => array(
1584
					'label'      => __( 'Menu Icon', 'pods' ),
1585
					'help'       => __( 'URL or Dashicon name for the menu icon. You may specify the path to the icon using one of the <a href="https://pods.io/docs/build/special-magic-tags/#site-tags" target="_blank">site tag</a> type <a href="https://pods.io/docs/build/special-magic-tags/" target="_blank">special magic tags</a>. For example, for a file in your theme directory, use "{@template-url}/path/to/image.png". You may also use the name of a <a href="https://developer.wordpress.org/resource/dashicons/" target="_blank">Dashicon</a>. For example, to use the empty star icon, use "dashicons-star-empty".', 'pods' ),
1586
					'type'       => 'text',
1587
					'default'    => '',
1588
					'depends-on' => array( 'show_in_menu' => true ),
1589
				),
1590
				'show_in_nav_menus'    => array(
1591
					'label'             => __( 'Show in Navigation Menus', 'pods' ),
1592
					'help'              => __( 'help', 'pods' ),
1593
					'type'              => 'boolean',
1594
					'default'           => true,
1595
					'boolean_yes_label' => '',
1596
				),
1597
				'show_in_admin_bar'    => array(
1598
					'label'             => __( 'Show in Admin Bar "New" Menu', 'pods' ),
1599
					'help'              => __( 'help', 'pods' ),
1600
					'type'              => 'boolean',
1601
					'default'           => true,
1602
					'dependency'        => true,
1603
					'boolean_yes_label' => '',
1604
				),
1605
				'name_admin_bar'       => array(
1606
					'label'      => __( 'Admin bar name', 'pods' ),
1607
					'help'       => __( 'Defaults to singular name', 'pods' ),
1608
					'type'       => 'text',
1609
					'default'    => '',
1610
					'depends-on' => array( 'show_in_admin_bar' => true ),
1611
				),
1612
			);
1613
1614
			$options['advanced'] = array(
1615
				'public'                  => array(
1616
					'label'             => __( 'Public', 'pods' ),
1617
					'help'              => __( 'help', 'pods' ),
1618
					'type'              => 'boolean',
1619
					'default'           => true,
1620
					'boolean_yes_label' => '',
1621
				),
1622
				'publicly_queryable'      => array(
1623
					'label'             => __( 'Publicly Queryable', 'pods' ),
1624
					'help'              => __( 'help', 'pods' ),
1625
					'type'              => 'boolean',
1626
					'default'           => pods_v( 'public', $pod, true ),
1627
					'boolean_yes_label' => '',
1628
				),
1629
				'exclude_from_search'     => array(
1630
					'label'             => __( 'Exclude from Search', 'pods' ),
1631
					'help'              => __( 'help', 'pods' ),
1632
					'type'              => 'boolean',
1633
					'default'           => ! pods_v( 'public', $pod, true ),
1634
					'boolean_yes_label' => '',
1635
				),
1636
				'capability_type'         => array(
1637
					'label'      => __( 'User Capability', 'pods' ),
1638
					'help'       => __( 'Uses these capabilties for access to this post type: edit_{capability}, read_{capability}, and delete_{capability}', 'pods' ),
1639
					'type'       => 'pick',
1640
					'default'    => 'post',
1641
					'data'       => array(
1642
						'post'   => 'post',
1643
						'page'   => 'page',
1644
						'custom' => __( 'Custom Capability', 'pods' ),
1645
					),
1646
					'dependency' => true,
1647
				),
1648
				'capability_type_custom'  => array(
1649
					'label'      => __( 'Custom User Capability', 'pods' ),
1650
					'help'       => __( 'help', 'pods' ),
1651
					'type'       => 'text',
1652
					'default'    => pods_v( 'name', $pod ),
1653
					'depends-on' => array( 'capability_type' => 'custom' ),
1654
				),
1655
				'capability_type_extra'   => array(
1656
					'label'             => __( 'Additional User Capabilities', 'pods' ),
1657
					'help'              => __( 'Enables additional capabilities for this Post Type including: delete_{capability}s, delete_private_{capability}s, delete_published_{capability}s, delete_others_{capability}s, edit_private_{capability}s, and edit_published_{capability}s', 'pods' ),
1658
					'type'              => 'boolean',
1659
					'default'           => true,
1660
					'boolean_yes_label' => '',
1661
				),
1662
				'has_archive'             => array(
1663
					'label'             => __( 'Enable Archive Page', 'pods' ),
1664
					'help'              => __( 'If enabled, creates an archive page with list of of items in this custom post type. Functions like a category page for posts. Can be controlled with a template in your theme called "archive-{$post-type}.php".', 'pods' ),
1665
					'type'              => 'boolean',
1666
					'default'           => false,
1667
					'dependency'        => true,
1668
					'boolean_yes_label' => '',
1669
				),
1670
				'has_archive_slug'        => array(
1671
					'label'      => __( 'Archive Page Slug Override', 'pods' ),
1672
					'help'       => __( 'If archive page is enabled, you can override the slug used by WordPress, which defaults to the name of the post type.', 'pods' ),
1673
					'type'       => 'text',
1674
					'default'    => '',
1675
					'depends-on' => array( 'has_archive' => true ),
1676
				),
1677
				'hierarchical'            => array(
1678
					'label'             => __( 'Hierarchical', 'pods' ),
1679
					'help'              => __( 'Allows for parent/ child relationships between items, just like with Pages. Note: To edit relationships in the post editor, you must enable "Page Attributes" in the "Supports" section below.', 'pods' ),
1680
					'type'              => 'boolean',
1681
					'default'           => false,
1682
					'dependency'        => true,
1683
					'boolean_yes_label' => '',
1684
				),
1685
				'label_parent_item_colon' => array(
1686
					'label'      => __( '<strong>Label: </strong> Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1687
					'help'       => __( 'help', 'pods' ),
1688
					'type'       => 'text',
1689
					'default'    => '',
1690
					'depends-on' => array( 'hierarchical' => true ),
1691
				),
1692
				'label_parent'            => array(
1693
					'label'      => __( '<strong>Label: </strong> Parent', 'pods' ),
1694
					'help'       => __( 'help', 'pods' ),
1695
					'type'       => 'text',
1696
					'default'    => '',
1697
					'depends-on' => array( 'hierarchical' => true ),
1698
				),
1699
				'rewrite'                 => array(
1700
					'label'             => __( 'Rewrite', 'pods' ),
1701
					'help'              => __( 'Allows you to use pretty permalinks, if set in WordPress Settings->Permalinks. If not enabled, your links will be in the form of "example.com/?pod_name=post_slug" regardless of your permalink settings.', 'pods' ),
1702
					'type'              => 'boolean',
1703
					'default'           => true,
1704
					'dependency'        => true,
1705
					'boolean_yes_label' => '',
1706
				),
1707
				'rewrite_custom_slug'     => array(
1708
					'label'      => __( 'Custom Rewrite Slug', 'pods' ),
1709
					'help'       => __( 'Changes the first segment of the URL, which by default is the name of the Pod. For example, if your Pod is called "foo", if this field is left blank, your link will be "example.com/foo/post_slug", but if you were to enter "bar" your link will be "example.com/bar/post_slug".', 'pods' ),
1710
					'type'       => 'text',
1711
					'default'    => '',
1712
					'depends-on' => array( 'rewrite' => true ),
1713
				),
1714
				'rewrite_with_front'      => array(
1715
					'label'             => __( 'Rewrite with Front', 'pods' ),
1716
					'help'              => __( 'Allows permalinks to be prepended with your front base (example: if your permalink structure is /blog/, then your links will be: Unchecked->/news/, Checked->/blog/news/)', 'pods' ),
1717
					'type'              => 'boolean',
1718
					'default'           => true,
1719
					'depends-on'        => array( 'rewrite' => true ),
1720
					'boolean_yes_label' => '',
1721
				),
1722
				'rewrite_feeds'           => array(
1723
					'label'             => __( 'Rewrite Feeds', 'pods' ),
1724
					'help'              => __( 'help', 'pods' ),
1725
					'type'              => 'boolean',
1726
					'default'           => false,
1727
					'depends-on'        => array( 'rewrite' => true ),
1728
					'boolean_yes_label' => '',
1729
				),
1730
				'rewrite_pages'           => array(
1731
					'label'             => __( 'Rewrite Pages', 'pods' ),
1732
					'help'              => __( 'help', 'pods' ),
1733
					'type'              => 'boolean',
1734
					'default'           => true,
1735
					'depends-on'        => array( 'rewrite' => true ),
1736
					'boolean_yes_label' => '',
1737
				),
1738
				'query_var'               => array(
1739
					'label'             => __( 'Query Var', 'pods' ),
1740
					'help'              => __( 'The Query Var is used in the URL and underneath the WordPress Rewrite API to tell WordPress what page or post type you are on. For a list of reserved Query Vars, read <a href="http://codex.wordpress.org/WordPress_Query_Vars">WordPress Query Vars</a> from the WordPress Codex.', 'pods' ),
1741
					'type'              => 'boolean',
1742
					'default'           => true,
1743
					'boolean_yes_label' => '',
1744
				),
1745
				'can_export'              => array(
1746
					'label'             => __( 'Exportable', 'pods' ),
1747
					'help'              => __( 'help', 'pods' ),
1748
					'type'              => 'boolean',
1749
					'default'           => true,
1750
					'boolean_yes_label' => '',
1751
				),
1752
				'default_status'          => array(
1753
					'label'       => __( 'Default Status', 'pods' ),
1754
					'help'        => __( 'help', 'pods' ),
1755
					'type'        => 'pick',
1756
					'pick_object' => 'post-status',
1757
					'default'     => apply_filters( 'pods_api_default_status_' . pods_v( 'name', $pod, 'post_type', true ), 'draft', $pod ),
1758
				),
1759
			);
1760
		} elseif ( 'taxonomy' === $pod['type'] ) {
1761
			$options['admin-ui'] = array(
1762
				'show_ui'               => array(
1763
					'label'             => __( 'Show Admin UI', 'pods' ),
1764
					'help'              => __( 'Whether to generate a default UI for managing this taxonomy.', 'pods' ),
1765
					'type'              => 'boolean',
1766
					'default'           => pods_v( 'public', $pod, true ),
1767
					'dependency'        => true,
1768
					'boolean_yes_label' => '',
1769
				),
1770
				'show_in_menu'          => array(
1771
					'label'             => __( 'Show Admin Menu in Dashboard', 'pods' ),
1772
					'help'              => __( 'Whether to show the taxonomy in the admin menu.', 'pods' ),
1773
					'type'              => 'boolean',
1774
					'default'           => pods_v( 'public', $pod, true ),
1775
					'dependency'        => true,
1776
					'depends-on'        => array( 'show_ui' => true ),
1777
					'boolean_yes_label' => '',
1778
				),
1779
				'menu_name'             => array(
1780
					'label'      => __( 'Menu Name', 'pods' ),
1781
					'help'       => __( 'help', 'pods' ),
1782
					'type'       => 'text',
1783
					'default'    => '',
1784
					'depends-on' => array( 'show_ui' => true ),
1785
				),
1786
				'menu_location'         => array(
1787
					'label'      => __( 'Menu Location', 'pods' ),
1788
					'help'       => __( 'help', 'pods' ),
1789
					'type'       => 'pick',
1790
					'default'    => 'default',
1791
					'depends-on' => array( 'show_ui' => true ),
1792
					'data'       => array(
1793
						'default'     => __( 'Default - Add to associated Post Type(s) menus', 'pods' ),
1794
						'settings'    => __( 'Add a submenu item to Settings menu', 'pods' ),
1795
						'appearances' => __( 'Add a submenu item to Appearances menu', 'pods' ),
1796
						'submenu'     => __( 'Add a submenu item to another menu', 'pods' ),
1797
						'objects'     => __( 'Make a new menu item', 'pods' ),
1798
						'top'         => __( 'Make a new menu item below Settings', 'pods' ),
1799
					),
1800
					'dependency' => true,
1801
				),
1802
				'menu_location_custom'  => array(
1803
					'label'      => __( 'Custom Menu Location', 'pods' ),
1804
					'help'       => __( 'help', 'pods' ),
1805
					'type'       => 'text',
1806
					'depends-on' => array( 'menu_location' => 'submenu' ),
1807
				),
1808
				'menu_position'         => array(
1809
					'label'              => __( 'Menu Position', 'pods' ),
1810
					'help'               => __( 'help', 'pods' ),
1811
					'type'               => 'number',
1812
					'number_decimals'    => 2,
1813
					'number_format'      => '9999.99',
1814
					'number_format_soft' => 1,
1815
					'default'            => 0,
1816
					'depends-on'         => array( 'menu_location' => array( 'objects', 'top' ) ),
1817
				),
1818
				'menu_icon'             => array(
1819
					'label'      => __( 'Menu Icon URL', 'pods' ),
1820
					'help'       => __( 'help', 'pods' ),
1821
					'type'       => 'text',
1822
					'default'    => '',
1823
					'depends-on' => array( 'menu_location' => array( 'objects', 'top' ) ),
1824
				),
1825
				'show_in_nav_menus'     => array(
1826
					'label'             => __( 'Show in Navigation Menus', 'pods' ),
1827
					'help'              => __( 'help', 'pods' ),
1828
					'type'              => 'boolean',
1829
					'default'           => pods_v( 'public', $pod, true ),
1830
					'boolean_yes_label' => '',
1831
				),
1832
				'show_tagcloud'         => array(
1833
					'label'             => __( 'Allow in Tagcloud Widget', 'pods' ),
1834
					'help'              => __( 'help', 'pods' ),
1835
					'type'              => 'boolean',
1836
					'default'           => pods_v( 'show_ui', $pod, pods_v( 'public', $pod, true ) ),
1837
					'boolean_yes_label' => '',
1838
				),
1839
				// @todo check https://core.trac.wordpress.org/ticket/36964
1840
				'show_tagcloud_in_edit' => array(
1841
					'label'             => __( 'Allow Tagcloud on term edit pages', 'pods' ),
1842
					'help'              => __( 'help', 'pods' ),
1843
					'type'              => 'boolean',
1844
					'default'           => pods_v( 'show_ui', $pod, pods_v( 'show_tagcloud', $pod, true ) ),
1845
					'boolean_yes_label' => '',
1846
				),
1847
				'show_in_quick_edit'    => array(
1848
					'label'             => __( 'Allow in quick/bulk edit panel', 'pods' ),
1849
					'help'              => __( 'help', 'pods' ),
1850
					'type'              => 'boolean',
1851
					'default'           => pods_v( 'show_ui', $pod, pods_v( 'public', $pod, true ) ),
1852
					'boolean_yes_label' => '',
1853
				),
1854
			);
1855
1856
			$options['admin-ui']['show_admin_column'] = array(
1857
				'label'             => __( 'Show Taxonomy column on Post Types', 'pods' ),
1858
				'help'              => __( 'Whether to add a column for this taxonomy on the associated post types manage screens', 'pods' ),
1859
				'type'              => 'boolean',
1860
				'default'           => false,
1861
				'boolean_yes_label' => '',
1862
			);
1863
1864
			// Integration for Single Value Taxonomy UI
1865
			if ( function_exists( 'tax_single_value_meta_box' ) ) {
1866
				$options['admin-ui']['single_value'] = array(
1867
					'label'             => __( 'Single Value Taxonomy', 'pods' ),
1868
					'help'              => __( 'Use a drop-down for the input instead of the WordPress default', 'pods' ),
1869
					'type'              => 'boolean',
1870
					'default'           => false,
1871
					'boolean_yes_label' => '',
1872
				);
1873
1874
				$options['admin-ui']['single_value_required'] = array(
1875
					'label'             => __( 'Single Value Taxonomy - Required', 'pods' ),
1876
					'help'              => __( 'A term will be selected by default in the Post Editor, not optional', 'pods' ),
1877
					'type'              => 'boolean',
1878
					'default'           => false,
1879
					'boolean_yes_label' => '',
1880
				);
1881
			}
1882
1883
			$options['advanced'] = array(
1884
				'public'                  => array(
1885
					'label'             => __( 'Public', 'pods' ),
1886
					'help'              => __( 'help', 'pods' ),
1887
					'type'              => 'boolean',
1888
					'default'           => true,
1889
					'boolean_yes_label' => '',
1890
				),
1891
				'hierarchical'            => array(
1892
					'label'             => __( 'Hierarchical', 'pods' ),
1893
					'help'              => __( 'help', 'pods' ),
1894
					'type'              => 'boolean',
1895
					'default'           => true,
1896
					'dependency'        => true,
1897
					'boolean_yes_label' => '',
1898
				),
1899
				'label_parent_item_colon' => array(
1900
					'label'      => __( '<strong>Label: </strong> Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1901
					'help'       => __( 'help', 'pods' ),
1902
					'type'       => 'text',
1903
					'default'    => '',
1904
					'depends-on' => array( 'hierarchical' => true ),
1905
				),
1906
				'label_parent'            => array(
1907
					'label'      => __( '<strong>Label: </strong> Parent', 'pods' ),
1908
					'help'       => __( 'help', 'pods' ),
1909
					'type'       => 'text',
1910
					'default'    => '',
1911
					'depends-on' => array( 'hierarchical' => true ),
1912
				),
1913
				'label_no_terms'          => array(
1914
					'label'      => __( '<strong>Label: </strong> No <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1915
					'help'       => __( 'help', 'pods' ),
1916
					'type'       => 'text',
1917
					'default'    => '',
1918
					'depends-on' => array( 'hierarchical' => true ),
1919
				),
1920
				'rewrite'                 => array(
1921
					'label'             => __( 'Rewrite', 'pods' ),
1922
					'help'              => __( 'help', 'pods' ),
1923
					'type'              => 'boolean',
1924
					'default'           => true,
1925
					'dependency'        => true,
1926
					'boolean_yes_label' => '',
1927
				),
1928
				'rewrite_custom_slug'     => array(
1929
					'label'      => __( 'Custom Rewrite Slug', 'pods' ),
1930
					'help'       => __( 'help', 'pods' ),
1931
					'type'       => 'text',
1932
					'default'    => '',
1933
					'depends-on' => array( 'rewrite' => true ),
1934
				),
1935
				'rewrite_with_front'      => array(
1936
					'label'             => __( 'Allow Front Prepend', 'pods' ),
1937
					'help'              => __( 'Allows permalinks to be prepended with front base (example: if your permalink structure is /blog/, then your links will be: Checked->/news/, Unchecked->/blog/news/)', 'pods' ),
1938
					'type'              => 'boolean',
1939
					'default'           => true,
1940
					'boolean_yes_label' => '',
1941
					'depends-on'        => array( 'rewrite' => true ),
1942
				),
1943
				'rewrite_hierarchical'    => array(
1944
					'label'             => __( 'Hierarchical Permalinks', 'pods' ),
1945
					'help'              => __( 'help', 'pods' ),
1946
					'type'              => 'boolean',
1947
					'default'           => true,
1948
					'boolean_yes_label' => '',
1949
					'depends-on'        => array( 'rewrite' => true ),
1950
				),
1951
				'capability_type'         => array(
1952
					'label'      => __( 'User Capability', 'pods' ),
1953
					'help'       => __( 'Uses WordPress term capabilities by default', 'pods' ),
1954
					'type'       => 'pick',
1955
					'default'    => 'default',
1956
					'data'       => array(
1957
						'default' => 'Default',
1958
						'custom'  => __( 'Custom Capability', 'pods' ),
1959
					),
1960
					'dependency' => true,
1961
				),
1962
				'capability_type_custom'  => array(
1963
					'label'      => __( 'Custom User Capability', 'pods' ),
1964
					'help'       => __( 'Enables additional capabilities for this Taxonomy including: manage_{capability}_terms, edit_{capability}_terms, assign_{capability}_terms, and delete_{capability}_terms', 'pods' ),
1965
					'type'       => 'text',
1966
					'default'    => pods_v( 'name', $pod ),
1967
					'depends-on' => array( 'capability_type' => 'custom' ),
1968
				),
1969
				'query_var'               => array(
1970
					'label'             => __( 'Query Var', 'pods' ),
1971
					'help'              => __( 'help', 'pods' ),
1972
					'type'              => 'boolean',
1973
					'default'           => false,
1974
					'boolean_yes_label' => '',
1975
				),
1976
				'query_var'               => array(
1977
					'label'             => __( 'Query Var', 'pods' ),
1978
					'help'              => __( 'help', 'pods' ),
1979
					'type'              => 'boolean',
1980
					'default'           => false,
1981
					'dependency'        => true,
1982
					'boolean_yes_label' => '',
1983
				),
1984
				'query_var_string'        => array(
1985
					'label'      => __( 'Custom Query Var Name', 'pods' ),
1986
					'help'       => __( 'help', 'pods' ),
1987
					'type'       => 'text',
1988
					'default'    => '',
1989
					'depends-on' => array( 'query_var' => true ),
1990
				),
1991
				'sort'                    => array(
1992
					'label'             => __( 'Remember order saved on Post Types', 'pods' ),
1993
					'help'              => __( 'help', 'pods' ),
1994
					'type'              => 'boolean',
1995
					'default'           => false,
1996
					'boolean_yes_label' => '',
1997
				),
1998
				'update_count_callback'   => array(
1999
					'label'   => __( 'Function to call when updating counts', 'pods' ),
2000
					'help'    => __( 'help', 'pods' ),
2001
					'type'    => 'text',
2002
					'default' => '',
2003
				),
2004
			);
2005
		} elseif ( 'settings' === $pod['type'] ) {
2006
			$options['admin-ui'] = array(
2007
				'ui_style'             => array(
2008
					'label'      => __( 'Admin UI Style', 'pods' ),
2009
					'help'       => __( 'help', 'pods' ),
2010
					'type'       => 'pick',
2011
					'default'    => 'settings',
2012
					'data'       => array(
2013
						'settings'  => __( 'Normal Settings Form', 'pods' ),
2014
						'post_type' => __( 'Post Type UI', 'pods' ),
2015
						'custom'    => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' ),
2016
					),
2017
					'dependency' => true,
2018
				),
2019
				'menu_location'        => array(
2020
					'label'      => __( 'Menu Location', 'pods' ),
2021
					'help'       => __( 'help', 'pods' ),
2022
					'type'       => 'pick',
2023
					'default'    => 'settings',
2024
					'data'       => array(
2025
						'settings'    => __( 'Add a submenu item to Settings menu', 'pods' ),
2026
						'appearances' => __( 'Add a submenu item to Appearances menu', 'pods' ),
2027
						'submenu'     => __( 'Add a submenu item to another menu', 'pods' ),
2028
						'top'         => __( 'Make a new menu item below Settings', 'pods' ),
2029
					),
2030
					'dependency' => true,
2031
				),
2032
				'menu_location_custom' => array(
2033
					'label'      => __( 'Custom Menu Location', 'pods' ),
2034
					'help'       => __( 'help', 'pods' ),
2035
					'type'       => 'text',
2036
					'depends-on' => array( 'menu_location' => 'submenu' ),
2037
				),
2038
				'menu_position'        => array(
2039
					'label'              => __( 'Menu Position', 'pods' ),
2040
					'help'               => __( 'help', 'pods' ),
2041
					'type'               => 'number',
2042
					'number_decimals'    => 2,
2043
					'number_format'      => '9999.99',
2044
					'number_format_soft' => 1,
2045
					'default'            => 0,
2046
					'depends-on'         => array( 'menu_location' => 'top' ),
2047
				),
2048
				'menu_icon'            => array(
2049
					'label'      => __( 'Menu Icon URL', 'pods' ),
2050
					'help'       => __( 'help', 'pods' ),
2051
					'type'       => 'text',
2052
					'default'    => '',
2053
					'depends-on' => array( 'menu_location' => 'top' ),
2054
				),
2055
			);
2056
2057
			// @todo fill this in
2058
			$options['advanced'] = array(
2059
				'temporary' => 'This type has the fields hardcoded',
2060
			// :(
2061
			);
2062
		} elseif ( 'pod' === $pod['type'] ) {
2063
			$actions_enabled = array(
2064
				'add',
2065
				'edit',
2066
				'duplicate',
2067
				'delete',
2068
			);
2069
2070
			if ( 1 === (int) pods_v( 'ui_export', $pod ) ) {
2071
				$actions_enabled = array(
2072
					'add',
2073
					'edit',
2074
					'duplicate',
2075
					'delete',
2076
					'export',
2077
				);
2078
			}
2079
2080
			$options['admin-ui'] = array(
2081
				'ui_style'             => array(
2082
					'label'      => __( 'Admin UI Style', 'pods' ),
2083
					'help'       => __( 'help', 'pods' ),
2084
					'type'       => 'pick',
2085
					'default'    => 'settings',
2086
					'data'       => array(
2087
						'post_type' => __( 'Normal (Looks like the Post Type UI)', 'pods' ),
2088
						'custom'    => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' ),
2089
					),
2090
					'dependency' => true,
2091
				),
2092
				'show_in_menu'         => array(
2093
					'label'             => __( 'Show Admin Menu in Dashboard', 'pods' ),
2094
					'help'              => __( 'help', 'pods' ),
2095
					'type'              => 'boolean',
2096
					'default'           => false,
2097
					'boolean_yes_label' => '',
2098
					'dependency'        => true,
2099
				),
2100
				'menu_location_custom' => array(
2101
					'label'      => __( 'Parent Menu ID (optional)', 'pods' ),
2102
					'help'       => __( 'help', 'pods' ),
2103
					'type'       => 'text',
2104
					'depends-on' => array( 'show_in_menu' => true ),
2105
				),
2106
				'menu_position'        => array(
2107
					'label'              => __( 'Menu Position', 'pods' ),
2108
					'help'               => __( 'help', 'pods' ),
2109
					'type'               => 'number',
2110
					'number_decimals'    => 2,
2111
					'number_format'      => '9999.99',
2112
					'number_format_soft' => 1,
2113
					'default'            => 0,
2114
					'depends-on'         => array( 'show_in_menu' => true ),
2115
				),
2116
				'menu_icon'            => array(
2117
					'label'      => __( 'Menu Icon URL', 'pods' ),
2118
					'help'       => __( 'This is the icon shown to the left of the menu text for this content type.', 'pods' ),
2119
					'type'       => 'text',
2120
					'default'    => '',
2121
					'depends-on' => array( 'show_in_menu' => true ),
2122
				),
2123
				'ui_icon'              => array(
2124
					'label'           => __( 'Header Icon', 'pods' ),
2125
					'help'            => __( 'This is the icon shown to the left of the heading text at the top of the manage pages for this content type.', 'pods' ),
2126
					'type'            => 'file',
2127
					'default'         => '',
2128
					'file_edit_title' => 0,
2129
					'depends-on'      => array( 'show_in_menu' => true ),
2130
				),
2131
				'ui_actions_enabled'   => array(
2132
					'label'            => __( 'Actions Available', 'pods' ),
2133
					'help'             => __( 'help', 'pods' ),
2134
					'type'             => 'pick',
2135
					'default'          => $actions_enabled,
2136
					'data'             => array(
2137
						'add'       => __( 'Add New', 'pods' ),
2138
						'edit'      => __( 'Edit', 'pods' ),
2139
						'duplicate' => __( 'Duplicate', 'pods' ),
2140
						'delete'    => __( 'Delete', 'pods' ),
2141
						'reorder'   => __( 'Reorder', 'pods' ),
2142
						'export'    => __( 'Export', 'pods' ),
2143
					),
2144
					'pick_format_type' => 'multi',
2145
					'dependency'       => true,
2146
				),
2147
				'ui_reorder_field'     => array(
2148
					'label'      => __( 'Reorder Field', 'pods' ),
2149
					'help'       => __( 'This is the field that will be reordered on, it should be numeric.', 'pods' ),
2150
					'type'       => 'text',
2151
					'default'    => 'menu_order',
2152
					'depends-on' => array( 'ui_actions_enabled' => 'reorder' ),
2153
				),
2154
				'ui_fields_manage'     => array(
2155
					'label'            => __( 'Admin Table Columns', 'pods' ),
2156
					'help'             => __( 'help', 'pods' ),
2157
					'type'             => 'pick',
2158
					'default'          => array(),
2159
					'data'             => array(),
2160
					'pick_format_type' => 'multi',
2161
				),
2162
				'ui_filters'           => array(
2163
					'label'            => __( 'Search Filters', 'pods' ),
2164
					'help'             => __( 'help', 'pods' ),
2165
					'type'             => 'pick',
2166
					'default'          => array(),
2167
					'data'             => array(),
2168
					'pick_format_type' => 'multi',
2169
				),
2170
			);
2171
2172
			if ( ! empty( $pod['fields'] ) ) {
2173
				if ( isset( $pod['fields'][ pods_v( 'pod_index', $pod, 'name' ) ] ) ) {
2174
					$options['admin-ui']['ui_fields_manage']['default'][] = pods_v( 'pod_index', $pod, 'name' );
2175
				}
2176
2177
				if ( isset( $pod['fields']['modified'] ) ) {
2178
					$options['admin-ui']['ui_fields_manage']['default'][] = 'modified';
2179
				}
2180
2181
				foreach ( $pod['fields'] as $field ) {
2182
					$type = '';
2183
2184
					if ( isset( $field_types[ $field['type'] ] ) ) {
2185
						$type = ' <small>(' . $field_types[ $field['type'] ]['label'] . ')</small>';
2186
					}
2187
2188
					$options['admin-ui']['ui_fields_manage']['data'][ $field['name'] ] = $field['label'] . $type;
2189
					$options['admin-ui']['ui_filters']['data'][ $field['name'] ]       = $field['label'] . $type;
2190
				}
2191
2192
				$options['admin-ui']['ui_fields_manage']['data']['id'] = 'ID';
2193
			} else {
2194
				unset( $options['admin-ui']['ui_fields_manage'] );
2195
				unset( $options['admin-ui']['ui_filters'] );
2196
			}//end if
2197
2198
			// @todo fill this in
2199
			$options['advanced'] = array(
2200
				'temporary' => 'This type has the fields hardcoded',
2201
			// :(
2202
			);
2203
		}//end if
2204
2205
		/**
2206
		 * Add admin fields to the Pods editor for a specific Pod
2207
		 *
2208
		 * @param array  $options The Options fields.
2209
		 * @param object $pod     Current Pods object.
2210
		 *
2211
		 * @since  unkown
2212
		 */
2213
		$options = apply_filters( 'pods_admin_setup_edit_options_' . $pod['type'] . '_' . $pod['name'], $options, $pod );
2214
2215
		/**
2216
		 * Add admin fields to the Pods editor for any Pod of a specific content type.
2217
		 *
2218
		 * @param array  $options The Options fields.
2219
		 * @param object $pod     Current Pods object.
2220
		 */
2221
		$options = apply_filters( 'pods_admin_setup_edit_options_' . $pod['type'], $options, $pod );
2222
2223
		/**
2224
		 * Add admin fields to the Pods editor for all Pods
2225
		 *
2226
		 * @param array  $options The Options fields.
2227
		 * @param object $pod     Current Pods object.
2228
		 */
2229
		$options = apply_filters( 'pods_admin_setup_edit_options', $options, $pod );
2230
2231
		return $options;
2232
	}
2233
2234
	/**
2235
	 * Get list of Pod field option tabs
2236
	 *
2237
	 * @param array $pod Pod options.
2238
	 *
2239
	 * @return array
2240
	 */
2241
	public function admin_setup_edit_field_tabs( $pod ) {
2242
2243
		$core_tabs = array(
2244
			'basic'            => __( 'Basic', 'pods' ),
2245
			'additional-field' => __( 'Additional Field Options', 'pods' ),
2246
			'advanced'         => __( 'Advanced', 'pods' ),
2247
		);
2248
2249
		/**
2250
		 * Field option tabs
2251
		 *
2252
		 * Use to add new tabs, default tabs are added after this filter (IE you can't remove/modify them with this, kthanksbye).
2253
		 *
2254
		 * @since unknown
2255
		 *
2256
		 * @param array      $tabs Tabs to add, starts empty.
2257
		 * @param object|Pod $pod  Current Pods object.
2258
		 */
2259
		$tabs = apply_filters( 'pods_admin_setup_edit_field_tabs', array(), $pod );
2260
2261
		$tabs = array_merge( $core_tabs, $tabs );
2262
2263
		return $tabs;
2264
	}
2265
2266
	/**
2267
	 * Get list of Pod field options
2268
	 *
2269
	 * @param array $pod Pod options.
2270
	 *
2271
	 * @return array
2272
	 */
2273
	public function admin_setup_edit_field_options( $pod ) {
2274
2275
		$options = array();
2276
2277
		$options['additional-field'] = array();
2278
2279
		$field_types = PodsForm::field_types();
2280
2281
		foreach ( $field_types as $type => $field_type_data ) {
2282
			/**
2283
			 * @var $field_type PodsField
2284
			 */
2285
			$field_type = PodsForm::field_loader( $type, $field_type_data['file'] );
2286
2287
			$field_type_vars = get_class_vars( get_class( $field_type ) );
2288
2289
			if ( ! isset( $field_type_vars['pod_types'] ) ) {
2290
				$field_type_vars['pod_types'] = true;
2291
			}
2292
2293
			$options['additional-field'][ $type ] = array();
2294
2295
			// Only show supported field types
2296
			if ( true !== $field_type_vars['pod_types'] ) {
2297
				if ( empty( $field_type_vars['pod_types'] ) ) {
2298
					continue;
2299
				} elseif ( is_array( $field_type_vars['pod_types'] ) && ! in_array( pods_v( 'type', $pod ), $field_type_vars['pod_types'], true ) ) {
2300
					continue;
2301
				} elseif ( ! is_array( $field_type_vars['pod_types'] ) && pods_v( 'type', $pod ) !== $field_type_vars['pod_types'] ) {
2302
					continue;
2303
				}
2304
			}
2305
2306
			$options['additional-field'][ $type ] = PodsForm::ui_options( $type );
2307
2308
			/**
2309
			 * Modify Additional Field Options tab
2310
			 *
2311
			 * @since 2.7
2312
			 *
2313
			 * @param array       $options Additional field type options,
2314
			 * @param string      $type    Field type,
2315
			 * @param array       $options Tabs, indexed by label,
2316
			 * @param object|Pods $pod     Pods object for the Pod this UI is for.
2317
			 */
2318
			$options['additional-field'][ $type ] = apply_filters( 'pods_admin_setup_edit_' . $type . '_additional_field_options', $options['additional-field'][ $type ], $type, $options, $pod );
2319
			$options['additional-field'][ $type ] = apply_filters( 'pods_admin_setup_edit_additional_field_options', $options['additional-field'][ $type ], $type, $options, $pod );
2320
		}//end foreach
2321
2322
		$input_helpers = array(
2323
			'' => '-- Select --',
2324
		);
2325
2326
		if ( class_exists( 'Pods_Helpers' ) ) {
2327
			$helpers = pods_api()->load_helpers( array( 'options' => array( 'helper_type' => 'input' ) ) );
2328
2329
			foreach ( $helpers as $helper ) {
2330
				$input_helpers[ $helper['name'] ] = $helper['name'];
2331
			}
2332
		}
2333
2334
		$options['advanced'] = array(
2335
			__( 'Visual', 'pods' )     => array(
2336
				'class'        => array(
2337
					'name'    => 'class',
2338
					'label'   => __( 'Additional CSS Classes', 'pods' ),
2339
					'help'    => __( 'help', 'pods' ),
2340
					'type'    => 'text',
2341
					'default' => '',
2342
				),
2343
				'input_helper' => array(
2344
					'name'    => 'input_helper',
2345
					'label'   => __( 'Input Helper', 'pods' ),
2346
					'help'    => __( 'help', 'pods' ),
2347
					'type'    => 'pick',
2348
					'default' => '',
2349
					'data'    => $input_helpers,
2350
				),
2351
			),
2352
			__( 'Values', 'pods' )     => array(
2353
				'default_value'           => array(
2354
					'name'    => 'default_value',
2355
					'label'   => __( 'Default Value', 'pods' ),
2356
					'help'    => __( 'help', 'pods' ),
2357
					'type'    => 'text',
2358
					'default' => '',
2359
					'options' => array(
2360
						'text_max_length' => - 1,
2361
					),
2362
				),
2363
				'default_value_parameter' => array(
2364
					'name'    => 'default_value_parameter',
2365
					'label'   => __( 'Set Default Value via Parameter', 'pods' ),
2366
					'help'    => __( 'help', 'pods' ),
2367
					'type'    => 'text',
2368
					'default' => '',
2369
				),
2370
			),
2371
			__( 'Visibility', 'pods' ) => array(
2372
				'restrict_access'    => array(
2373
					'name'  => 'restrict_access',
2374
					'label' => __( 'Restrict Access', 'pods' ),
2375
					'group' => array(
2376
						'admin_only'          => array(
2377
							'name'       => 'admin_only',
2378
							'label'      => __( 'Restrict access to Admins?', 'pods' ),
2379
							'default'    => 0,
2380
							'type'       => 'boolean',
2381
							'dependency' => true,
2382
							'help'       => __( 'This field will only be able to be edited by users with the ability to manage_options or delete_users, or super admins of a WordPress Multisite network', 'pods' ),
2383
						),
2384
						'restrict_role'       => array(
2385
							'name'       => 'restrict_role',
2386
							'label'      => __( 'Restrict access by Role?', 'pods' ),
2387
							'default'    => 0,
2388
							'type'       => 'boolean',
2389
							'dependency' => true,
2390
						),
2391
						'restrict_capability' => array(
2392
							'name'       => 'restrict_capability',
2393
							'label'      => __( 'Restrict access by Capability?', 'pods' ),
2394
							'default'    => 0,
2395
							'type'       => 'boolean',
2396
							'dependency' => true,
2397
						),
2398
						'hidden'              => array(
2399
							'name'    => 'hidden',
2400
							'label'   => __( 'Hide field from UI', 'pods' ),
2401
							'default' => 0,
2402
							'type'    => 'boolean',
2403
							'help'    => __( 'This option is overriden by access restrictions. If the user does not have access to edit this field, it will be hidden. If no access restrictions are set, this field will always be hidden.', 'pods' ),
2404
						),
2405
						'read_only'           => array(
2406
							'name'       => 'read_only',
2407
							'label'      => __( 'Make field "Read Only" in UI', 'pods' ),
2408
							'default'    => 0,
2409
							'type'       => 'boolean',
2410
							'help'       => __( 'This option is overriden by access restrictions. If the user does not have access to edit this field, it will be read only. If no access restrictions are set, this field will always be read only.', 'pods' ),
2411
							'depends-on' => array(
2412
								'type' => array(
2413
									'boolean',
2414
									'color',
2415
									'currency',
2416
									'date',
2417
									'datetime',
2418
									'email',
2419
									'number',
2420
									'paragraph',
2421
									'password',
2422
									'phone',
2423
									'slug',
2424
									'text',
2425
									'time',
2426
									'website',
2427
								),
2428
							),
2429
						),
2430
					),
2431
				),
2432
				'roles_allowed'      => array(
2433
					'name'             => 'roles_allowed',
2434
					'label'            => __( 'Role(s) Allowed', 'pods' ),
2435
					'help'             => __( 'help', 'pods' ),
2436
					'type'             => 'pick',
2437
					'pick_object'      => 'role',
2438
					'pick_format_type' => 'multi',
2439
					'default'          => 'administrator',
2440
					'depends-on'       => array(
2441
						'restrict_role' => true,
2442
					),
2443
				),
2444
				'capability_allowed' => array(
2445
					'name'       => 'capability_allowed',
2446
					'label'      => __( 'Capability Allowed', 'pods' ),
2447
					'help'       => __( 'Comma-separated list of cababilities, for example add_podname_item, please see the Roles and Capabilities component for the complete list and a way to add your own.', 'pods' ),
2448
					'type'       => 'text',
2449
					'default'    => '',
2450
					'depends-on' => array(
2451
						'restrict_capability' => true,
2452
					),
2453
				),
2454
			),
2455
		);
2456
2457
		/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
2458
		$options['advanced'][ __( 'Visibility', 'pods' ) ]['search'] = array(
2459
			'label'   => __( 'Include in searches', 'pods' ),
2460
			'help'    => __( 'help', 'pods' ),
2461
			'default' => 1,
2462
			'type'    => 'boolean',
2463
		);
2464
		*/
2465
2466
		/*
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...
2467
		$options['advanced'][ __( 'Validation', 'pods' ) ] = array(
2468
			'regex_validation' => array(
2469
				'label'   => __( 'RegEx Validation', 'pods' ),
2470
				'help'    => __( 'help', 'pods' ),
2471
				'type'    => 'text',
2472
				'default' => '',
2473
			),
2474
			'message_regex'    => array(
2475
				'label'   => __( 'Message if field does not pass RegEx', 'pods' ),
2476
				'help'    => __( 'help', 'pods' ),
2477
				'type'    => 'text',
2478
				'default' => '',
2479
			),
2480
			'message_required' => array(
2481
				'label'      => __( 'Message if field is blank', 'pods' ),
2482
				'help'       => __( 'help', 'pods' ),
2483
				'type'       => 'text',
2484
				'default'    => '',
2485
				'depends-on' => array( 'required' => true ),
2486
			),
2487
			'message_unique'   => array(
2488
				'label'      => __( 'Message if field is not unique', 'pods' ),
2489
				'help'       => __( 'help', 'pods' ),
2490
				'type'       => 'text',
2491
				'default'    => '',
2492
				'depends-on' => array( 'unique' => true ),
2493
			),
2494
		);
2495
		*/
2496
2497
		if ( ! class_exists( 'Pods_Helpers' ) ) {
2498
			unset( $options['advanced']['input_helper'] );
2499
		}
2500
2501
		/**
2502
		 * Modify tabs and their contents for field options
2503
		 *
2504
		 * @since unknown
2505
		 *
2506
		 * @param array       $options Tabs, indexed by label.
2507
		 * @param object|Pods $pod     Pods object for the Pod this UI is for.
2508
		 */
2509
		$options = apply_filters( 'pods_admin_setup_edit_field_options', $options, $pod );
2510
2511
		return $options;
2512
	}
2513
2514
	/**
2515
	 * Duplicate a pod
2516
	 *
2517
	 * @param PodsUI $obj PodsUI object.
2518
	 */
2519
	public function admin_setup_duplicate( $obj ) {
2520
2521
		$new_id = pods_api()->duplicate_pod( array( 'id' => $obj->id ) );
2522
2523
		if ( 0 < $new_id ) {
2524
			pods_redirect(
2525
				pods_query_arg(
2526
					array(
2527
						'action' => 'edit',
2528
						'id'     => $new_id,
2529
						'do'     => 'duplicate',
2530
					)
2531
				)
2532
			);
2533
		}
2534
	}
2535
2536
	/**
2537
	 * Restrict Duplicate action to custom types, not extended
2538
	 *
2539
	 * @param bool   $restricted Whether action is restricted.
2540
	 * @param array  $restrict   Restriction array.
2541
	 * @param string $action     Current action.
2542
	 * @param array  $row        Item data row.
2543
	 * @param PodsUI $obj        PodsUI object.
2544
	 *
2545
	 * @since 2.3.10
2546
	 *
2547
	 * @return bool
2548
	 */
2549
	public function admin_setup_duplicate_restrict( $restricted, $restrict, $action, $row, $obj ) {
2550
2551
		if ( in_array(
2552
			$row['real_type'], array(
2553
				'user',
2554
				'media',
2555
				'comment',
2556
			), true
2557
		) ) {
2558
			$restricted = true;
2559
		}
2560
2561
		return $restricted;
2562
2563
	}
2564
2565
	/**
2566
	 * Reset a pod
2567
	 *
2568
	 * @param PodsUI     $obj PodsUI object.
2569
	 * @param int|string $id  Item ID.
2570
	 *
2571
	 * @return mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use boolean|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
2572
	 */
2573
	public function admin_setup_reset( $obj, $id ) {
2574
2575
		$pod = pods_api()->load_pod( array( 'id' => $id ), false );
2576
2577
		if ( empty( $pod ) ) {
2578
			return $obj->error( __( 'Pod not found.', 'pods' ) );
2579
		}
2580
2581
		pods_api()->reset_pod( array( 'id' => $id ) );
2582
2583
		$obj->message( __( 'Pod reset successfully.', 'pods' ) );
2584
2585
		$obj->manage();
2586
	}
2587
2588
	/**
2589
	 * Restrict Reset action from users and media
2590
	 *
2591
	 * @param bool   $restricted Whether action is restricted.
2592
	 * @param array  $restrict   Restriction array.
2593
	 * @param string $action     Current action.
2594
	 * @param array  $row        Item data row.
2595
	 * @param PodsUI $obj        PodsUI object.
2596
	 *
2597
	 * @since 2.3.10
2598
	 */
2599
	public function admin_setup_reset_restrict( $restricted, $restrict, $action, $row, $obj ) {
2600
2601
		if ( in_array(
2602
			$row['real_type'], array(
2603
				'user',
2604
				'media',
2605
			), true
2606
		) ) {
2607
			$restricted = true;
2608
		}
2609
2610
		return $restricted;
2611
2612
	}
2613
2614
	/**
2615
	 * Delete a pod
2616
	 *
2617
	 * @param int|string $id  Item ID.
2618
	 * @param PodsUI     $obj PodsUI object.
2619
	 *
2620
	 * @return mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use boolean|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
2621
	 */
2622
	public function admin_setup_delete( $id, $obj ) {
2623
2624
		$pod = pods_api()->load_pod( array( 'id' => $id ), false );
2625
2626
		if ( empty( $pod ) ) {
2627
			return $obj->error( __( 'Pod not found.', 'pods' ) );
2628
		}
2629
2630
		pods_api()->delete_pod( array( 'id' => $id ) );
2631
2632
		unset( $obj->data[ $pod['id'] ] );
2633
2634
		$obj->total       = count( $obj->data );
2635
		$obj->total_found = count( $obj->data );
2636
2637
		$obj->message( __( 'Pod deleted successfully.', 'pods' ) );
2638
	}
2639
2640
	/**
2641
	 * Get advanced administration view.
2642
	 */
2643
	public function admin_advanced() {
2644
2645
		pods_view( PODS_DIR . 'ui/admin/advanced.php', compact( array_keys( get_defined_vars() ) ) );
2646
	}
2647
2648
	/**
2649
	 * Get settings administration view
2650
	 */
2651
	public function admin_settings() {
2652
2653
		pods_view( PODS_DIR . 'ui/admin/settings.php', compact( array_keys( get_defined_vars() ) ) );
2654
	}
2655
2656
	/**
2657
	 * Get components administration UI
2658
	 */
2659
	public function admin_components() {
2660
2661
		if ( ! is_object( PodsInit::$components ) ) {
2662
			return;
2663
		}
2664
2665
		$components = PodsInit::$components->components;
2666
2667
		$view = pods_v( 'view', 'get', 'all', true );
2668
2669
		$recommended = array(
2670
			'advanced-relationships',
2671
			'advanced-content-types',
2672
			'migrate-packages',
2673
			'roles-and-capabilities',
2674
			'pages',
2675
			'table-storage',
2676
			'templates',
2677
		);
2678
2679
		foreach ( $components as $component => &$component_data ) {
2680
			if ( ! in_array(
2681
				$view, array(
2682
					'all',
2683
					'recommended',
2684
					'dev',
2685
				), true
2686
			) && ( ! isset( $component_data['Category'] ) || sanitize_title( $component_data['Category'] ) !== $view ) ) {
2687
				unset( $components[ $component ] );
2688
2689
				continue;
2690
			} elseif ( 'recommended' === $view && ! in_array( $component_data['ID'], $recommended, true ) ) {
2691
				unset( $components[ $component ] );
2692
2693
				continue;
2694
			} elseif ( 'dev' === $view && pods_developer() && ! pods_v( 'DeveloperMode', $component_data, false ) ) {
2695
				unset( $components[ $component ] );
2696
2697
				continue;
2698
			} elseif ( pods_v( 'DeveloperMode', $component_data, false ) && ! pods_developer() ) {
2699
				unset( $components[ $component ] );
2700
2701
				continue;
2702
			} elseif ( ! pods_v( 'TablelessMode', $component_data, false ) && pods_tableless() ) {
2703
				unset( $components[ $component ] );
2704
2705
				continue;
2706
			}//end if
2707
2708
			$component_data['Name'] = strip_tags( $component_data['Name'] );
2709
2710
			if ( pods_v( 'DeveloperMode', $component_data, false ) ) {
2711
				$component_data['Name'] .= ' <em style="font-weight: normal; color:#333;">(Developer Preview)</em>';
2712
			}
2713
2714
			$meta = array();
2715
2716
			if ( ! empty( $component_data['Version'] ) ) {
2717
				$meta[] = sprintf( __( 'Version %s', 'pods' ), $component_data['Version'] );
2718
			}
2719
2720
			if ( empty( $component_data['Author'] ) ) {
2721
				$component_data['Author']    = 'Pods Framework Team';
2722
				$component_data['AuthorURI'] = 'https://pods.io/';
2723
			}
2724
2725
			if ( ! empty( $component_data['AuthorURI'] ) ) {
2726
				$component_data['Author'] = '<a href="' . $component_data['AuthorURI'] . '">' . $component_data['Author'] . '</a>';
2727
			}
2728
2729
			$meta[] = sprintf( __( 'by %s', 'pods' ), $component_data['Author'] );
2730
2731
			if ( ! empty( $component_data['URI'] ) ) {
2732
				$meta[] = '<a href="' . $component_data['URI'] . '">' . __( 'Visit component site', 'pods' ) . '</a>';
2733
			}
2734
2735
			$component_data['Description'] = wpautop( trim( make_clickable( strip_tags( $component_data['Description'], 'em,strong' ) ) ) );
2736
2737
			if ( ! empty( $meta ) ) {
2738
				$description_style = '';
2739
2740
				if ( ! empty( $component_data['Description'] ) ) {
2741
					$description_style = ' style="padding:8px 0 4px;"';
2742
				}
2743
2744
				$component_data['Description'] .= '<div class="pods-component-meta" ' . $description_style . '>' . implode( '&nbsp;&nbsp;|&nbsp;&nbsp;', $meta ) . '</div>';
2745
			}
2746
2747
			$component_data = array(
2748
				'id'          => $component_data['ID'],
2749
				'name'        => $component_data['Name'],
2750
				'category'    => $component_data['Category'],
2751
				'version'     => '',
2752
				'description' => $component_data['Description'],
2753
				'mustuse'     => pods_v( 'MustUse', $component_data, false ),
2754
				'toggle'      => 0,
2755
			);
2756
2757
			if ( ! empty( $component_data['category'] ) ) {
2758
				$category_url = pods_query_arg(
2759
					array(
2760
						'view' => sanitize_title( $component_data['category'] ),
2761
						'pg'   => '',
2762
						// @codingStandardsIgnoreLine
2763
						'page' => $_GET['page'],
2764
					)
2765
				);
2766
2767
				$component_data['category'] = '<a href="' . esc_url( $category_url ) . '">' . $component_data['category'] . '</a>';
2768
			}
2769
2770
			if ( isset( PodsInit::$components->settings['components'][ $component_data['id'] ] ) && 0 !== PodsInit::$components->settings['components'][ $component_data['id'] ] ) {
2771
				$component_data['toggle'] = 1;
2772
			} elseif ( $component_data['mustuse'] ) {
2773
				$component_data['toggle'] = 1;
2774
			}
2775
		}//end foreach
2776
2777
		$ui = array(
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ui. 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...
2778
			'data'             => $components,
2779
			'total'            => count( $components ),
2780
			'total_found'      => count( $components ),
2781
			'items'            => __( 'Components', 'pods' ),
2782
			'item'             => __( 'Component', 'pods' ),
2783
			'fields'           => array(
2784
				'manage' => array(
2785
					'name'        => array(
2786
						'label'   => __( 'Name', 'pods' ),
2787
						'width'   => '30%',
2788
						'type'    => 'text',
2789
						'options' => array(
2790
							'text_allow_html' => true,
2791
						),
2792
					),
2793
					'category'    => array(
2794
						'label'   => __( 'Category', 'pods' ),
2795
						'width'   => '10%',
2796
						'type'    => 'text',
2797
						'options' => array(
2798
							'text_allow_html' => true,
2799
						),
2800
					),
2801
					'description' => array(
2802
						'label'   => __( 'Description', 'pods' ),
2803
						'width'   => '60%',
2804
						'type'    => 'text',
2805
						'options' => array(
2806
							'text_allow_html'        => true,
2807
							'text_allowed_html_tags' => 'strong em a ul ol li b i br div',
2808
						),
2809
					),
2810
				),
2811
			),
2812
			'actions_disabled' => array( 'duplicate', 'view', 'export', 'add', 'edit', 'delete' ),
2813
			'actions_custom'   => array(
2814
				'toggle' => array(
2815
					'callback' => array( $this, 'admin_components_toggle' ),
2816
					'nonce'    => true,
2817
				),
2818
			),
2819
			'filters_enhanced' => true,
2820
			'views'            => array(
2821
				'all'         => __( 'All', 'pods' ),
2822
				// 'recommended' => __( 'Recommended', 'pods' ),
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% 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...
2823
				'field-types' => __( 'Field Types', 'pods' ),
2824
				'tools'       => __( 'Tools', 'pods' ),
2825
				'integration' => __( 'Integration', 'pods' ),
2826
				'migration'   => __( 'Migration', 'pods' ),
2827
				'advanced'    => __( 'Advanced', 'pods' ),
2828
			),
2829
			'view'             => $view,
2830
			'heading'          => array(
2831
				'views' => __( 'Category', 'pods' ),
2832
			),
2833
			'search'           => false,
2834
			'searchable'       => false,
2835
			'sortable'         => false,
2836
			'pagination'       => false,
2837
		);
2838
2839
		if ( pods_developer() ) {
2840
			$ui['views']['dev'] = __( 'Developer Preview', 'pods' );
2841
		}
2842
2843
		pods_ui( $ui );
2844
	}
2845
2846
	/**
2847
	 * Toggle a component on or off
2848
	 *
2849
	 * @param PodsUI $ui PodsUI object.
2850
	 *
2851
	 * @return bool
0 ignored issues
show
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
2852
	 */
2853
	public function admin_components_toggle( $ui ) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ui. 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...
2854
2855
		// @codingStandardsIgnoreLine
2856
		$component = $_GET['id'];
2857
2858
		if ( ! empty( PodsInit::$components->components[ $component ]['PluginDependency'] ) ) {
2859
			$dependency = explode( '|', PodsInit::$components->components[ $component ]['PluginDependency'] );
2860
2861
			if ( ! pods_is_plugin_active( $dependency[1] ) ) {
2862
				$website = 'http://wordpress.org/extend/plugins/' . dirname( $dependency[1] ) . '/';
2863
2864
				if ( isset( $dependency[2] ) ) {
2865
					$website = $dependency[2];
2866
				}
2867
2868
				if ( ! empty( $website ) ) {
2869
					$website = ' ' . sprintf( __( 'You can find it at %s', 'pods' ), '<a href="' . $website . '" target="_blank">' . $website . '</a>' );
2870
				}
2871
2872
				$message = sprintf( __( 'The %1$s component requires that you have the <strong>%2$s</strong> plugin installed and activated.', 'pods' ), PodsInit::$components->components[ $component ]['Name'], $dependency[0] ) . $website;
2873
2874
				$ui->error( $message );
2875
2876
				$ui->manage();
2877
2878
				return;
2879
			}
2880
		}//end if
2881
2882
		if ( ! empty( PodsInit::$components->components[ $component ]['ThemeDependency'] ) ) {
2883
			$dependency = explode( '|', PodsInit::$components->components[ $component ]['ThemeDependency'] );
2884
2885
			$check = strtolower( $dependency[1] );
2886
2887
			if ( strtolower( get_template() ) !== $check && strtolower( get_stylesheet() ) !== $check ) {
2888
				$website = '';
2889
2890
				if ( isset( $dependency[2] ) ) {
2891
					$website = ' ' . sprintf( __( 'You can find it at %s', 'pods' ), '<a href="' . $dependency[2] . '" target="_blank">' . $dependency[2] . '</a>' );
2892
				}
2893
2894
				$message = sprintf( __( 'The %1$s component requires that you have the <strong>%2$s</strong> theme installed and activated.', 'pods' ), PodsInit::$components->components[ $component ]['Name'], $dependency[0] ) . $website;
2895
2896
				$ui->error( $message );
2897
2898
				$ui->manage();
2899
2900
				return;
2901
			}
2902
		}//end if
2903
2904
		if ( ! empty( PodsInit::$components->components[ $component ]['MustUse'] ) ) {
2905
			$message = sprintf( __( 'The %s component can not be disabled from here. You must deactivate the plugin or theme that added it.', 'pods' ), PodsInit::$components->components[ $component ]['Name'] );
2906
2907
			$ui->error( $message );
2908
2909
			$ui->manage();
2910
2911
			return;
2912
		}
2913
2914
		if ( 1 === (int) pods_v( 'toggled' ) ) {
2915
			$toggle = PodsInit::$components->toggle( $component );
2916
2917
			if ( true === $toggle ) {
2918
				$ui->message( PodsInit::$components->components[ $component ]['Name'] . ' ' . __( 'Component enabled', 'pods' ) );
2919
			} elseif ( false === $toggle ) {
2920
				$ui->message( PodsInit::$components->components[ $component ]['Name'] . ' ' . __( 'Component disabled', 'pods' ) );
2921
			}
2922
2923
			$components = PodsInit::$components->components;
2924
2925
			foreach ( $components as $component => &$component_data ) {
2926
				$toggle = 0;
2927
2928
				if ( isset( PodsInit::$components->settings['components'][ $component_data['ID'] ] ) ) {
2929
					if ( 0 !== PodsInit::$components->settings['components'][ $component_data['ID'] ] ) {
2930
						$toggle = 1;
2931
					}
2932
				}
2933
				if ( true === $component_data['DeveloperMode'] ) {
2934
					if ( ! pods_developer() ) {
2935
						unset( $components[ $component ] );
2936
						continue;
2937
					}
2938
				}
2939
2940
				$component_data = array(
2941
					'id'          => $component_data['ID'],
2942
					'name'        => $component_data['Name'],
2943
					'description' => make_clickable( $component_data['Description'] ),
2944
					'version'     => $component_data['Version'],
2945
					'author'      => $component_data['Author'],
2946
					'toggle'      => $toggle,
2947
				);
2948
			}//end foreach
2949
2950
			$ui->data = $components;
2951
2952
			pods_transient_clear( 'pods_components' );
2953
2954
			$url = pods_query_arg( array( 'toggled' => null ) );
2955
2956
			pods_redirect( $url );
2957
		} elseif ( 1 === (int) pods_v( 'toggle' ) ) {
2958
			$ui->message( PodsInit::$components->components[ $component ]['Name'] . ' ' . __( 'Component enabled', 'pods' ) );
2959
		} else {
2960
			$ui->message( PodsInit::$components->components[ $component ]['Name'] . ' ' . __( 'Component disabled', 'pods' ) );
2961
		}//end if
2962
2963
		$ui->manage();
2964
	}
2965
2966
	/**
2967
	 * Get the admin upgrade page
2968
	 */
2969
	public function admin_upgrade() {
2970
2971
		foreach ( PodsInit::$upgrades as $old_version => $new_version ) {
2972
			if ( version_compare( $old_version, PodsInit::$version_last, '<=' ) && version_compare( PodsInit::$version_last, $new_version, '<' ) ) {
2973
				$new_version = str_replace( '.', '_', $new_version );
2974
2975
				pods_view( PODS_DIR . 'ui/admin/upgrade/upgrade_' . $new_version . '.php', compact( array_keys( get_defined_vars() ) ) );
2976
2977
				break;
2978
			}
2979
		}
2980
	}
2981
2982
	/**
2983
	 * Get the admin help page
2984
	 */
2985
	public function admin_help() {
2986
2987
		pods_view( PODS_DIR . 'ui/admin/help.php', compact( array_keys( get_defined_vars() ) ) );
2988
	}
2989
2990
	/**
2991
	 * Add pods specific capabilities.
2992
	 *
2993
	 * @param array $capabilities List of extra capabilities to add.
2994
	 *
2995
	 * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use string[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
2996
	 */
2997
	public function admin_capabilities( $capabilities ) {
2998
2999
		$pods = pods_api()->load_pods(
3000
			array(
3001
				'type'       => array(
3002
					'settings',
3003
					'post_type',
3004
					'taxonomy',
3005
				),
3006
				'fields'     => false,
3007
				'table_info' => false,
3008
			)
3009
		);
3010
3011
		$other_pods = pods_api()->load_pods(
3012
			array(
3013
				'type'       => array(
3014
					'pod',
3015
					'table',
3016
				),
3017
				'table_info' => false,
3018
			)
3019
		);
3020
3021
		$pods = array_merge( $pods, $other_pods );
3022
3023
		$capabilities[] = 'pods';
3024
		$capabilities[] = 'pods_content';
3025
		$capabilities[] = 'pods_settings';
3026
		$capabilities[] = 'pods_components';
3027
3028
		foreach ( $pods as $pod ) {
3029
			if ( 'settings' === $pod['type'] ) {
3030
				$capabilities[] = 'pods_edit_' . $pod['name'];
3031
			} elseif ( 'post_type' === $pod['type'] ) {
3032
				$capability_type = pods_v_sanitized( 'capability_type_custom', $pod['options'], pods_v( 'name', $pod ) );
3033
3034
				if ( 'custom' === pods_v( 'capability_type', $pod['options'] ) && 0 < strlen( $capability_type ) ) {
3035
					$capabilities[] = 'read_' . $capability_type;
3036
					$capabilities[] = 'edit_' . $capability_type;
3037
					$capabilities[] = 'delete_' . $capability_type;
3038
3039
					if ( 1 === (int) pods_v( 'capability_type_extra', $pod['options'], 1 ) ) {
3040
						$capability_type_plural = $capability_type . 's';
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $capability_type_plural exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
3041
3042
						$capabilities[] = 'read_private_' . $capability_type_plural;
3043
						$capabilities[] = 'edit_' . $capability_type_plural;
3044
						$capabilities[] = 'edit_others_' . $capability_type_plural;
3045
						$capabilities[] = 'edit_private_' . $capability_type_plural;
3046
						$capabilities[] = 'edit_published_' . $capability_type_plural;
3047
						$capabilities[] = 'publish_' . $capability_type_plural;
3048
						$capabilities[] = 'delete_' . $capability_type_plural;
3049
						$capabilities[] = 'delete_private_' . $capability_type_plural;
3050
						$capabilities[] = 'delete_published_' . $capability_type_plural;
3051
						$capabilities[] = 'delete_others_' . $capability_type_plural;
3052
					}
3053
				}
3054
			} elseif ( 'taxonomy' === $pod['type'] ) {
3055
				if ( 'custom' === pods_v( 'capability_type', $pod['options'], 'terms' ) ) {
3056
					$capability_type = pods_v_sanitized( 'capability_type_custom', $pod['options'], pods_v( 'name', $pod ) . 's' );
3057
3058
					$capability_type       .= '_term';
3059
					$capability_type_plural = $capability_type . 's';
3060
3061
					// Singular
3062
					$capabilities[] = 'edit_' . $capability_type;
3063
					$capabilities[] = 'delete_' . $capability_type;
3064
					$capabilities[] = 'assign_' . $capability_type;
3065
					// Plural
3066
					$capabilities[] = 'manage_' . $capability_type_plural;
3067
					$capabilities[] = 'edit_' . $capability_type_plural;
3068
					$capabilities[] = 'delete_' . $capability_type_plural;
3069
					$capabilities[] = 'assign_' . $capability_type_plural;
3070
				}
3071
			} else {
3072
				$capabilities[] = 'pods_add_' . $pod['name'];
3073
				$capabilities[] = 'pods_edit_' . $pod['name'];
3074
3075
				if ( isset( $pod['fields']['author'] ) && 'pick' === $pod['fields']['author']['type'] && 'user' === $pod['fields']['author']['pick_object'] ) {
3076
					$capabilities[] = 'pods_edit_others_' . $pod['name'];
3077
				}
3078
3079
				$capabilities[] = 'pods_delete_' . $pod['name'];
3080
3081
				if ( isset( $pod['fields']['author'] ) && 'pick' === $pod['fields']['author']['type'] && 'user' === $pod['fields']['author']['pick_object'] ) {
3082
					$capabilities[] = 'pods_delete_others_' . $pod['name'];
3083
				}
3084
3085
				$actions_enabled = pods_v( 'ui_actions_enabled', $pod['options'] );
3086
3087
				if ( ! empty( $actions_enabled ) ) {
3088
					$actions_enabled = (array) $actions_enabled;
3089
				} else {
3090
					$actions_enabled = array();
3091
				}
3092
3093
				$available_actions = array(
3094
					'add',
3095
					'edit',
3096
					'duplicate',
3097
					'delete',
3098
					'reorder',
3099
					'export',
3100
				);
3101
3102
				if ( ! empty( $actions_enabled ) ) {
3103
					$actions_disabled = array(
3104
						'view' => 'view',
3105
					);
3106
3107
					foreach ( $available_actions as $action ) {
3108
						if ( ! in_array( $action, $actions_enabled, true ) ) {
3109
							$actions_disabled[ $action ] = $action;
3110
						}
3111
					}
3112
3113
					if ( ! in_array( 'export', $actions_disabled, true ) ) {
3114
						$capabilities[] = 'pods_export_' . $pod['name'];
3115
					}
3116
3117
					if ( ! in_array( 'reorder', $actions_disabled, true ) ) {
3118
						$capabilities[] = 'pods_reorder_' . $pod['name'];
3119
					}
3120
				} elseif ( 1 === (int) pods_v( 'ui_export', $pod['options'], 0 ) ) {
3121
					$capabilities[] = 'pods_export_' . $pod['name'];
3122
				}//end if
3123
			}//end if
3124
		}//end foreach
3125
3126
		return $capabilities;
3127
	}
3128
3129
	/**
3130
	 * Handle ajax calls for the administration
3131
	 */
3132
	public function admin_ajax() {
3133
3134
		if ( false === headers_sent() ) {
3135
			pods_session_start();
3136
3137
			header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) );
3138
		}
3139
3140
		// Sanitize input
3141
		// @codingStandardsIgnoreLine
3142
		$params = pods_unslash( (array) $_POST );
3143
3144
		foreach ( $params as $key => $value ) {
3145
			if ( 'action' === $key ) {
3146
				continue;
3147
			}
3148
3149
			// Fixup $_POST data @codingStandardsIgnoreLine
3150
			$_POST[ str_replace( '_podsfix_', '', $key ) ] = $_POST[ $key ];
3151
3152
			// Fixup $params with unslashed data
3153
			$params[ str_replace( '_podsfix_', '', $key ) ] = $value;
3154
3155
			// Unset the _podsfix_* keys
3156
			unset( $params[ $key ] );
3157
		}
3158
3159
		$params = (object) $params;
3160
3161
		$methods = array(
3162
			'add_pod'                 => array( 'priv' => true ),
3163
			'save_pod'                => array( 'priv' => true ),
3164
			'load_sister_fields'      => array( 'priv' => true ),
3165
			'process_form'            => array( 'custom_nonce' => true ),
3166
			// priv handled through nonce
3167
							'upgrade' => array( 'priv' => true ),
3168
			'migrate'                 => array( 'priv' => true ),
3169
		);
3170
3171
		/**
3172
		 * AJAX Callbacks in field editor
3173
		 *
3174
		 * @since unknown
3175
		 *
3176
		 * @param array     $methods Callback methods.
3177
		 * @param PodsAdmin $obj     PodsAdmin object.
3178
		 */
3179
		$methods = apply_filters( 'pods_admin_ajax_methods', $methods, $this );
3180
3181
		if ( ! isset( $params->method ) || ! isset( $methods[ $params->method ] ) ) {
3182
			pods_error( 'Invalid AJAX request', $this );
3183
		}
3184
3185
		$defaults = array(
3186
			'priv'         => null,
3187
			'name'         => $params->method,
3188
			'custom_nonce' => null,
3189
		);
3190
3191
		$method = (object) array_merge( $defaults, (array) $methods[ $params->method ] );
3192
3193
		if ( true !== $method->custom_nonce && ( ! isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, 'pods-' . $params->method ) ) ) {
3194
			pods_error( __( 'Unauthorized request', 'pods' ), $this );
3195
		}
3196
3197
		// Cleaning up $params
3198
		unset( $params->action );
3199
		unset( $params->method );
3200
3201
		if ( true !== $method->custom_nonce ) {
3202
			unset( $params->_wpnonce );
3203
		}
3204
3205
		// Check permissions (convert to array to support multiple)
3206
		if ( ! empty( $method->priv ) && ! pods_is_admin( array( 'pods' ) ) && true !== $method->priv && ! pods_is_admin( $method->priv ) ) {
3207
			pods_error( __( 'Access denied', 'pods' ), $this );
3208
		}
3209
3210
		$params->method = $method->name;
3211
3212
		$params = apply_filters( 'pods_api_' . $method->name, $params, $method );
3213
3214
		$api = pods_api();
3215
3216
		$api->display_errors = false;
3217
3218
		if ( 'upgrade' === $method->name ) {
3219
			$output = (string) pods_upgrade( $params->version )->ajax( $params );
3220
		} elseif ( 'migrate' === $method->name ) {
3221
			$output = (string) apply_filters( 'pods_api_migrate_run', $params );
3222
		} else {
3223
			if ( ! method_exists( $api, $method->name ) ) {
3224
				pods_error( 'API method does not exist', $this );
3225
			} elseif ( 'save_pod' === $method->name ) {
3226
				if ( isset( $params->field_data_json ) && is_array( $params->field_data_json ) ) {
3227
					$params->fields = $params->field_data_json;
3228
3229
					unset( $params->field_data_json );
3230
3231
					foreach ( $params->fields as $k => $v ) {
3232
						if ( empty( $v ) ) {
3233
							unset( $params->fields[ $k ] );
3234
						} elseif ( ! is_array( $v ) ) {
3235
							$params->fields[ $k ] = (array) @json_decode( $v, true );
0 ignored issues
show
Silencing errors is discouraged
Loading history...
3236
						}
3237
					}
3238
				}
3239
			}
3240
3241
			// Dynamically call the API method
3242
			$params = (array) $params;
3243
3244
			$output = call_user_func( array( $api, $method->name ), $params );
3245
		}//end if
3246
3247
		// Output in json format
3248
		if ( false !== $output ) {
3249
3250
			/**
3251
			 * Pods Admin AJAX request was successful
3252
			 *
3253
			 * @since  2.6.8
3254
			 *
3255
			 * @param array               $params AJAX parameters.
3256
			 * @param array|object|string $output Output for AJAX request.
3257
			 */
3258
			do_action( "pods_admin_ajax_success_{$method->name}", $params, $output );
3259
3260
			if ( is_array( $output ) || is_object( $output ) ) {
3261
				wp_send_json( $output );
3262
			} else {
3263
				// @codingStandardsIgnoreLine
3264
				echo $output;
3265
			}
3266
		} else {
3267
			pods_error( 'There was a problem with your request.' );
3268
		}//end if
3269
3270
		die();
3271
		// KBAI!
3272
	}
3273
3274
	/**
3275
	 * Profiles the Pods configuration
3276
	 *
3277
	 * @param null|string|array $pod             Which Pod(s) to get configuration for. Can be a the name
3278
	 *                                           of one Pod, or an array of names of Pods, or null, which is the
3279
	 *                                           default, to profile all Pods.
3280
	 * @param bool              $full_field_info If true all info about each field is returned. If false,
3281
	 *                                           which is the default only name and type, will be returned.
3282
	 *
3283
	 * @return array
0 ignored issues
show
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
3284
	 *
3285
	 * @since 2.7
3286
	 */
3287
	public function configuration( $pod = null, $full_field_info = false ) {
3288
3289
		$api = pods_api();
3290
3291
		if ( null === $pod ) {
3292
			$the_pods = $api->load_pods();
3293
		} elseif ( is_array( $pod ) ) {
3294
			foreach ( $pod as $p ) {
3295
				$the_pods[] = $api->load_pod( $p );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$the_pods was never initialized. Although not strictly required by PHP, it is generally a good practice to add $the_pods = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
3296
			}
3297
		} else {
3298
			$the_pods[] = $api->load_pod( $pod );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$the_pods was never initialized. Although not strictly required by PHP, it is generally a good practice to add $the_pods = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
3299
		}
3300
3301
		foreach ( $the_pods as $the_pod ) {
0 ignored issues
show
The variable $the_pods does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
The expression $the_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...
3302
			$configuration[ $the_pod['name'] ] = array(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$configuration was never initialized. Although not strictly required by PHP, it is generally a good practice to add $configuration = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
3303
				'name'    => $the_pod['name'],
3304
				'ID'      => $the_pod['id'],
3305
				'storage' => $the_pod['storage'],
3306
				'fields'  => $the_pod['fields'],
3307
			);
3308
		}
3309
3310
		if ( ! $full_field_info ) {
3311
			foreach ( $the_pods as $the_pod ) {
0 ignored issues
show
The expression $the_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...
3312
				$fields = $configuration[ $the_pod['name'] ]['fields'];
0 ignored issues
show
The variable $configuration does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
3313
3314
				unset( $configuration[ $the_pod['name'] ]['fields'] );
3315
3316
				foreach ( $fields as $field ) {
3317
					$info = array(
3318
						'name' => $field['name'],
3319
						'type' => $field['type'],
3320
					);
3321
3322
					if ( 'pick' === $info['type'] ) {
3323
						$info['pick_object'] = $field['pick_object'];
3324
3325
						if ( isset( $field['pick_val'] ) && '' !== $field['pick_val'] ) {
3326
							$info['pick_val'] = $field['pick_val'];
3327
						}
3328
					}
3329
3330
					if ( is_array( $info ) ) {
3331
						$configuration[ $the_pod['name'] ]['fields'][ $field['name'] ] = $info;
3332
					}
3333
3334
					unset( $info );
3335
3336
				}//end foreach
3337
			}//end foreach
3338
		}//end if
3339
3340
		if ( is_array( $configuration ) ) {
3341
			return $configuration;
3342
		}
3343
3344
	}
3345
3346
	/**
3347
	 * Build UI for extending REST API, if makes sense to do so.
3348
	 *
3349
	 * @since  2.6.0
3350
	 *
3351
	 * @access protected
3352
	 */
3353
	protected function rest_admin() {
3354
3355
		if ( function_exists( 'register_rest_field' ) ) {
3356
			add_filter(
3357
				'pods_admin_setup_edit_field_options', array(
3358
					$this,
3359
					'add_rest_fields_to_field_editor',
3360
				), 12, 2
3361
			);
3362
			add_filter( 'pods_admin_setup_edit_field_tabs', array( $this, 'add_rest_field_tab' ), 12 );
3363
		}
3364
3365
		add_filter( 'pods_admin_setup_edit_tabs', array( $this, 'add_rest_settings_tab' ), 12, 2 );
3366
		add_filter( 'pods_admin_setup_edit_options', array( $this, 'add_rest_settings_tab_fields' ), 12, 2 );
3367
3368
	}
3369
3370
	/**
3371
	 * Check if Pod type <em>could</em> extend core REST API response
3372
	 *
3373
	 * @since  2.5.6
3374
	 *
3375
	 * @access protected
3376
	 *
3377
	 * @param array $pod Pod options.
3378
	 *
3379
	 * @return bool
3380
	 */
3381
	protected function restable_pod( $pod ) {
3382
3383
		$type = $pod['type'];
3384
3385
		$restable_types = array(
3386
			'post_type',
3387
			'user',
3388
			'taxonomy',
3389
			'media',
3390
		);
3391
3392
		return in_array( $type, $restable_types, true );
3393
3394
	}
3395
3396
	/**
3397
	 * Add a rest api tab.
3398
	 *
3399
	 * @since 2.6.0
3400
	 *
3401
	 * @param array $tabs Tab array.
3402
	 * @param array $pod  Pod options.
3403
	 *
3404
	 * @return array
3405
	 */
3406
	public function add_rest_settings_tab( $tabs, $pod ) {
3407
3408
		$tabs['rest-api'] = __( 'REST API', 'pods' );
3409
3410
		return $tabs;
3411
3412
	}
3413
3414
	/**
3415
	 * Populate REST API tab.
3416
	 *
3417
	 * @since 0.1.0
3418
	 *
3419
	 * @param array $options Tab options.
3420
	 * @param array $pod     Pod options.
3421
	 *
3422
	 * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array<string,array<string,array>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
3423
	 */
3424
	public function add_rest_settings_tab_fields( $options, $pod ) {
3425
3426
		if ( ! function_exists( 'register_rest_field' ) ) {
3427
			$options['rest-api'] = array(
3428
				'no_dependencies' => array(
3429
					'label' => __( sprintf( 'Pods REST API support requires WordPress 4.3.1 or later and the %s or later.', '<a href="https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank">WordPress REST API 2.0-beta9</a>' ), 'pods' ),
3430
					'help'  => __( sprintf( 'See %s for more information.', '<a href="https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank">https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/</a>' ), 'pods' ),
3431
					'type'  => 'html',
3432
				),
3433
			);
3434
		} elseif ( $this->restable_pod( $pod ) ) {
3435
			$options['rest-api'] = array(
3436
				'rest_enable' => array(
3437
					'label'      => __( 'Enable', 'pods' ),
3438
					'help'       => __( 'Add REST API support for this Pod.', 'pods' ),
3439
					'type'       => 'boolean',
3440
					'default'    => '',
3441
					'dependency' => true,
3442
				),
3443
				'rest_base'   => array(
3444
					'label'      => __( 'REST Base (if any)', 'pods' ),
3445
					'help'       => __( 'This will form the url for the route. Default / empty value here will use the pod name.', 'pods' ),
3446
					'type'       => 'text',
3447
					'default'    => '',
3448
					'depends-on' => array( 'rest_enable' => true ),
3449
				),
3450
				'read_all'    => array(
3451
					'label'      => __( 'Show All Fields (read-only)', 'pods' ),
3452
					'help'       => __( 'Show all fields in REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ),
3453
					'type'       => 'boolean',
3454
					'default'    => '',
3455
					'depends-on' => array( 'rest_enable' => true ),
3456
				),
3457
				'write_all'   => array(
3458
					'label'             => __( 'Allow All Fields To Be Updated', 'pods' ),
3459
					'help'              => __( 'Allow all fields to be updated via the REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ),
3460
					'type'              => 'boolean',
3461
					'default'           => pods_v( 'name', $pod ),
3462
					'boolean_yes_label' => '',
3463
					'depends-on'        => array( 'rest_enable' => true ),
3464
				),
3465
3466
			);
3467
3468
		} else {
3469
			$options['rest-api'] = array(
3470
				'not_restable' => array(
3471
					'label' => __( 'Pods REST API support covers post type, taxonomy and user Pods.', 'pods' ),
3472
					'help'  => __( sprintf( 'See %s for more information.', '<a href="https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank">https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/"</a>' ), 'pods' ),
3473
					'type'  => 'html',
3474
				),
3475
			);
3476
3477
		}//end if
3478
3479
		return $options;
3480
3481
	}
3482
3483
	/**
3484
	 * Add a REST API section to advanced tab of field editor.
3485
	 *
3486
	 * @since 2.5.6
3487
	 *
3488
	 * @param array $options Tab options.
3489
	 * @param array $pod     Pod options.
3490
	 *
3491
	 * @return array
3492
	 */
3493
	public function add_rest_fields_to_field_editor( $options, $pod ) {
3494
3495
		if ( $this->restable_pod( $pod ) ) {
3496
			$options['rest'][ __( 'Read/ Write', 'pods' ) ]                = array(
3497
				'rest_read'  => array(
3498
					'label'   => __( 'Read via REST API?', 'pods' ),
3499
					'help'    => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
3500
					'type'    => 'boolean',
3501
					'default' => '',
3502
				),
3503
				'rest_write' => array(
3504
					'label'   => __( 'Write via REST API?', 'pods' ),
3505
					'help'    => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
3506
					'type'    => 'boolean',
3507
					'default' => '',
3508
				),
3509
			);
3510
			$options['rest'][ __( 'Relationship Field Options', 'pods' ) ] = array(
3511
				'rest_pick_response' => array(
3512
					'label'      => __( 'Response Type', 'pods' ),
3513
					'help'       => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
3514
					'type'       => 'pick',
3515
					'default'    => 'array',
3516
					'depends-on' => array( 'type' => 'pick' ),
3517
					'data'       => array(
3518
						'array' => __( 'Full', 'pods' ),
3519
						'id'    => __( 'ID only', 'pods' ),
3520
						'name'  => __( 'Name', 'pods' ),
3521
3522
					),
3523
				),
3524
				'rest_pick_depth'    => array(
3525
					'label'      => __( 'Depth', 'pods' ),
3526
					'help'       => __( 'How far to traverse relationships in response', 'pods' ),
3527
					'type'       => 'number',
3528
					'default'    => '2',
3529
					'depends-on' => array( 'type' => 'pick' ),
3530
3531
				),
3532
3533
			);
3534
3535
		}//end if
3536
3537
		return $options;
3538
3539
	}
3540
3541
	/**
3542
	 * Add REST field tab
3543
	 *
3544
	 * @since 2.5.6
3545
	 *
3546
	 * @param array $tabs Tab list.
3547
	 *
3548
	 * @return array
3549
	 */
3550
	public function add_rest_field_tab( $tabs ) {
3551
3552
		$tabs['rest'] = __( 'REST API', 'pods' );
3553
3554
		return $tabs;
3555
	}
3556
3557
}
3558