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/PodsInit.php (32 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 PodsInit {
7
8
	/**
9
	 * @var PodsInit
10
	 */
11
	public static $instance = null;
12
13
	/**
14
	 * @var array
15
	 */
16
	public static $no_conflict = array();
17
18
	/**
19
	 * @var array
20
	 */
21
	public static $content_types_registered = array();
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $content_types_registered 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...
22
23
	/**
24
	 * @var PodsComponents
25
	 */
26
	public static $components;
27
28
	/**
29
	 * @var PodsMeta
30
	 */
31
	public static $meta;
32
33
	/**
34
	 * @var PodsI18n
35
	 */
36
	public static $i18n;
37
38
	/**
39
	 * @var PodsAdmin
40
	 */
41
	public static $admin;
42
43
	/**
44
	 * @var mixed|void
45
	 */
46
	public static $version;
47
48
	/**
49
	 * @var mixed|void
50
	 */
51
	public static $version_last;
52
53
	/**
54
	 * @var mixed|void
55
	 */
56
	public static $db_version;
57
58
	/**
59
	 * Upgrades to trigger (last installed version => upgrade version)
60
	 *
61
	 * @var array
62
	 */
63
	public static $upgrades = array(
64
		'1.0.0' => '2.0.0',
65
		// '2.0.0' => '2.1.0'
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
66
	);
67
68
	/**
69
	 * Whether an Upgrade for 1.x has happened
70
	 *
71
	 * @var bool
72
	 */
73
	public static $upgraded;
74
75
	/**
76
	 * Whether an Upgrade is needed
77
	 *
78
	 * @var bool
79
	 */
80
	public static $upgrade_needed = false;
81
82
	/**
83
	 * Singleton handling for a basic pods_init() request
84
	 *
85
	 * @return \PodsInit
86
	 *
87
	 * @since 2.3.5
88
	 */
89
	public static function init() {
90
91
		if ( ! is_object( self::$instance ) ) {
92
			self::$instance = new self();
93
		}
94
95
		return self::$instance;
96
	}
97
98
	/**
99
	 * Setup and Initiate Pods
100
	 *
101
	 * @return \PodsInit
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...
102
	 *
103
	 * @license http://www.gnu.org/licenses/gpl-2.0.html
104
	 * @since   1.8.9
105
	 */
106
	public function __construct() {
107
108
		self::$version      = get_option( 'pods_framework_version' );
109
		self::$version_last = get_option( 'pods_framework_version_last' );
110
		self::$db_version   = get_option( 'pods_framework_db_version' );
111
		self::$upgraded     = (int) get_option( 'pods_framework_upgraded_1_x' );
112
113
		if ( empty( self::$version_last ) && 0 < strlen( get_option( 'pods_version' ) ) ) {
114
			$old_version = get_option( 'pods_version' );
115
116
			if ( ! empty( $old_version ) ) {
117
				if ( false === strpos( $old_version, '.' ) ) {
118
					$old_version = pods_version_to_point( $old_version );
119
				}
120
121
				update_option( 'pods_framework_version_last', $old_version );
122
123
				self::$version_last = $old_version;
124
			}
125
		}
126
127
		self::$upgrade_needed = $this->needs_upgrade();
128
129
		add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
130
		add_action( 'plugins_loaded', array( $this, 'activate_install' ), 9 );
131
132
		add_action( 'wp_loaded', array( $this, 'flush_rewrite_rules' ) );
133
134
		$this->run();
135
136
	}
137
138
	/**
139
	 * Load the plugin textdomain and set default constants
140
	 */
141
	public function plugins_loaded() {
142
143
		if ( ! defined( 'PODS_LIGHT' ) ) {
144
			define( 'PODS_LIGHT', false );
145
		}
146
147
		if ( ! defined( 'PODS_TABLELESS' ) ) {
148
			define( 'PODS_TABLELESS', false );
149
		}
150
151
		load_plugin_textdomain( 'pods' );
152
153
	}
154
155
	/**
156
	 * Load Pods Components
157
	 */
158
	public function load_components() {
159
160
		if ( empty( self::$version ) ) {
161
			return;
162
		}
163
164
		if ( ! defined( 'PODS_LIGHT' ) || ! PODS_LIGHT ) {
165
			self::$components = pods_components();
166
		}
167
168
	}
169
170
	/**
171
	 * Load Pods Meta
172
	 */
173
	public function load_meta() {
174
175
		self::$meta = pods_meta()->core();
176
	}
177
178
	/**
179
	 *
180
	 */
181
	public function load_i18n() {
182
183
		self::$i18n = pods_i18n();
184
	}
185
186
	/**
187
	 * Set up the Pods core
188
	 */
189
	public function core() {
190
191
		if ( empty( self::$version ) ) {
192
			return;
193
		}
194
195
		// Session start
196
		pods_session_start();
197
198
		add_shortcode( 'pods', 'pods_shortcode' );
199
		add_shortcode( 'pods-form', 'pods_shortcode_form' );
200
201
		$security_settings = array(
202
			'pods_disable_file_browser'     => 0,
203
			'pods_files_require_login'      => 1,
204
			'pods_files_require_login_cap'  => '',
205
			'pods_disable_file_upload'      => 0,
206
			'pods_upload_require_login'     => 1,
207
			'pods_upload_require_login_cap' => '',
208
		);
209
210
		foreach ( $security_settings as $security_setting => $setting ) {
211
			$setting = get_option( $security_setting );
212
			if ( ! empty( $setting ) ) {
213
				$security_settings[ $security_setting ] = $setting;
214
			}
215
		}
216
217
		foreach ( $security_settings as $security_setting => $setting ) {
218
			if ( 0 === (int) $setting ) {
219
				$setting = false;
220
			} elseif ( 1 === (int) $setting ) {
221
				$setting = true;
222
			}
223
224
			if ( in_array(
225
				$security_setting, array(
226
					'pods_files_require_login',
227
					'pods_upload_require_login',
228
				), true
229
			) ) {
230
				if ( 0 < strlen( $security_settings[ $security_setting . '_cap' ] ) ) {
231
					$setting = $security_settings[ $security_setting . '_cap' ];
232
				}
233
			} elseif ( in_array(
234
				$security_setting, array(
235
					'pods_files_require_login_cap',
236
					'pods_upload_require_login_cap',
237
				), true
238
			) ) {
239
				continue;
240
			}
241
242
			if ( ! defined( strtoupper( $security_setting ) ) ) {
243
				define( strtoupper( $security_setting ), $setting );
244
			}
245
		}//end foreach
246
247
		$this->register_pods();
248
249
		$avatar = PodsForm::field_loader( 'avatar' );
250
251
		if ( method_exists( $avatar, 'get_avatar' ) ) {
252
			add_filter( 'get_avatar', array( $avatar, 'get_avatar' ), 10, 4 );
253
		}
254
	}
255
256
	/**
257
	 * Register Scripts and Styles
258
	 */
259
	public function register_assets() {
260
261
		$maybe_min = SCRIPT_DEBUG ? '' : '.min';
262
263
		wp_register_script( 'pods-json', PODS_URL . 'ui/js/jquery.json.js', array( 'jquery' ), '2.3' );
264
265
		if ( ! wp_script_is( 'jquery-qtip2', 'registered' ) ) {
266
			wp_register_script( 'jquery-qtip2', PODS_URL . 'ui/js/jquery.qtip.min.js', array( 'jquery' ), '2.2' );
267
		}
268
269
		wp_register_script(
270
			'pods', PODS_URL . 'ui/js/jquery.pods.js', array(
271
				'jquery',
272
				'pods-dfv',
273
				'pods-i18n',
274
				'pods-json',
275
				'jquery-qtip2',
276
			), PODS_VERSION, true
277
		);
278
279
		wp_register_script( 'pods-cleditor', PODS_URL . 'ui/js/jquery.cleditor.min.js', array( 'jquery' ), '1.3.0' );
280
281
		wp_register_script( 'pods-codemirror', PODS_URL . 'ui/js/codemirror.js', array(), '4.8', true );
282
		wp_register_script( 'pods-codemirror-loadmode', PODS_URL . 'ui/js/codemirror/addon/mode/loadmode.js', array( 'pods-codemirror' ), '4.8', true );
283
		wp_register_script( 'pods-codemirror-overlay', PODS_URL . 'ui/js/codemirror/addon/mode/overlay.js', array( 'pods-codemirror' ), '4.8', true );
284
		wp_register_script( 'pods-codemirror-hints', PODS_URL . 'ui/js/codemirror/addon/mode/show-hint.js', array( 'pods-codemirror' ), '4.8', true );
285
		wp_register_script( 'pods-codemirror-mode-xml', PODS_URL . 'ui/js/codemirror/mode/xml/xml.js', array( 'pods-codemirror' ), '4.8', true );
286
		wp_register_script( 'pods-codemirror-mode-html', PODS_URL . 'ui/js/codemirror/mode/htmlmixed/htmlmixed.js', array( 'pods-codemirror' ), '4.8', true );
287
		wp_register_script( 'pods-codemirror-mode-css', PODS_URL . 'ui/js/codemirror/mode/css/css.js', array( 'pods-codemirror' ), '4.8', true );
288
289
		if ( ! wp_script_is( 'jquery-ui-slideraccess', 'registered' ) ) {
290
			// No need to add dependencies. All managed by jquery-ui-timepicker.
291
			wp_register_script( 'jquery-ui-slideraccess', PODS_URL . 'ui/js/timepicker/jquery-ui-sliderAccess.js', array(), '0.3' );
292
		}
293
294
		if ( ! wp_script_is( 'jquery-ui-timepicker', 'registered' ) ) {
295
			wp_register_script(
296
				'jquery-ui-timepicker', PODS_URL . 'ui/js/timepicker/jquery-ui-timepicker-addon.min.js', array(
297
					'jquery',
298
					'jquery-ui-core',
299
					'jquery-ui-datepicker',
300
					'jquery-ui-slider',
301
					'jquery-ui-slideraccess',
302
				), '1.6.3'
303
			);
304
		}
305
		if ( ! wp_style_is( 'jquery-ui-timepicker', 'registered' ) ) {
306
			wp_register_style( 'jquery-ui-timepicker', PODS_URL . 'ui/js/timepicker/jquery-ui-timepicker-addon.min.css', array(), '1.6.3' );
307
		}
308
309
		wp_register_script(
310
			'pods-select2', PODS_URL . "ui/js/selectWoo/selectWoo{$maybe_min}.js", array(
311
				'jquery',
312
				'pods-i18n',
313
			), '1.0.1'
314
		);
315
		wp_register_style( 'pods-select2', PODS_URL . "ui/js/selectWoo/selectWoo{$maybe_min}.css", array(), '1.0.1' );
316
317
		// Marionette dependencies for MV fields
318
		wp_register_script( 'backbone.radio', PODS_URL . 'ui/js/marionette/backbone.radio.js', array( 'backbone' ), '2.0.0', true );
319
		wp_register_script(
320
			'marionette', PODS_URL . 'ui/js/marionette/backbone.marionette.js', array(
321
				'backbone',
322
				'backbone.radio',
323
			), '3.1.0', true
324
		);
325
326
		// MV stuff
327
		wp_register_script(
328
			'pods-dfv', PODS_URL . 'ui/js/pods-dfv/pods-dfv.min.js', array(
329
				'jquery',
330
				'jquery-ui-core',
331
				'jquery-ui-sortable',
332
				'pods-i18n',
333
				'marionette',
334
				'media-views',
335
				'media-models',
336
			), PODS_VERSION, true
337
		);
338
339
		// Check if Pod is a Modal Window
340
		if ( pods_is_modal_window() ) {
341
			add_filter( 'body_class', array( $this, 'add_classes_to_body_class' ) );
342
			add_filter( 'admin_body_class', array( $this, 'add_classes_to_body_class' ) );
343
		}
344
345
		// Deal with specifics on admin pages
346
		if ( is_admin() ) {
347
			$screen = get_current_screen();
348
349
			// DFV must be enqueued on the media library page for items in grid mode (see #4785)
350
			if ( $screen->base && 'upload' === $screen->base ) {
351
				wp_enqueue_script( 'pods-dfv' );
352
			}
353
		}
354
355
		$this->maybe_register_handlebars();
356
357
		// As of 2.7 we combine styles to just three .css files
358
		wp_register_style( 'pods-styles', PODS_URL . 'ui/styles/dist/pods.css', array(), PODS_VERSION );
359
		wp_register_style( 'pods-wizard', PODS_URL . 'ui/styles/dist/pods-wizard.css', array(), PODS_VERSION );
360
		wp_register_style( 'pods-form', PODS_URL . 'ui/styles/dist/pods-form.css', array(), PODS_VERSION );
361
	}
362
363
	/**
364
	 * Register handlebars where needed
365
	 *
366
	 * @since 2.7.2
367
	 */
368
	private function maybe_register_handlebars() {
369
370
		$register_handlebars = apply_filters( 'pods_script_register_handlebars', true );
371
372
		if ( is_admin() ) {
373
			$screen = get_current_screen();
374
375
			// Deregister the outdated Pods handlebars script on TEC event screen
376
			if ( $screen && 'tribe_events' === $screen->post_type ) {
377
				$register_handlebars = false;
378
			}
379
		}
380
381
		if ( $register_handlebars ) {
382
			wp_register_script( 'pods-handlebars', PODS_URL . 'ui/js/handlebars.js', array(), '1.0.0.beta.6' );
383
		}
384
	}
385
386
	/**
387
	 * @param string $classes Body classes.
388
	 *
389
	 * @return string
390
	 */
391
	public function add_classes_to_body_class( $classes ) {
392
393
		$classes .= 'pods-modal-window';
394
395
		return $classes;
396
	}
397
398
	/**
399
	 * Register internal Post Types
400
	 */
401
	public function register_pods() {
402
403
		$args = array(
404
			'label'           => 'Pods',
405
			'labels'          => array( 'singular_name' => 'Pod' ),
406
			'public'          => false,
407
			'can_export'      => false,
408
			'query_var'       => false,
409
			'rewrite'         => false,
410
			'capability_type' => 'pods_pod',
411
			'has_archive'     => false,
412
			'hierarchical'    => false,
413
			'supports'        => array( 'title', 'author' ),
414
			'menu_icon'       => 'dashicons-pods',
415
		);
416
417
		$args = self::object_label_fix( $args, 'post_type' );
418
419
		register_post_type( '_pods_pod', apply_filters( 'pods_internal_register_post_type_pod', $args ) );
420
421
		$args = array(
422
			'label'           => 'Pod Fields',
423
			'labels'          => array( 'singular_name' => 'Pod Field' ),
424
			'public'          => false,
425
			'can_export'      => false,
426
			'query_var'       => false,
427
			'rewrite'         => false,
428
			'capability_type' => 'pods_pod',
429
			'has_archive'     => false,
430
			'hierarchical'    => true,
431
			'supports'        => array( 'title', 'editor', 'author' ),
432
			'menu_icon'       => 'dashicons-pods',
433
		);
434
435
		$args = self::object_label_fix( $args, 'post_type' );
436
437
		register_post_type( '_pods_field', apply_filters( 'pods_internal_register_post_type_field', $args ) );
438
	}
439
440
	/**
441
	 * Include Admin
442
	 */
443
	public function admin_init() {
444
445
		self::$admin = pods_admin();
446
	}
447
448
	/**
449
	 * Register Post Types and Taxonomies
450
	 *
451
	 * @param bool $force
452
	 */
453
	public function setup_content_types( $force = false ) {
454
455
		if ( empty( self::$version ) ) {
456
			return;
457
		}
458
459
		require_once PODS_DIR . 'classes/PodsRESTHandlers.php';
460
		require_once PODS_DIR . 'classes/PodsRESTFields.php';
461
462
		$post_types = PodsMeta::$post_types;
463
		$taxonomies = PodsMeta::$taxonomies;
464
465
		$existing_post_types = get_post_types();
466
		$existing_taxonomies = get_taxonomies();
467
468
		$pods_cpt_ct = pods_transient_get( 'pods_wp_cpt_ct' );
469
470
		$cpt_positions = array();
471
472
		if ( empty( $pods_cpt_ct ) && ( ! empty( $post_types ) || ! empty( $taxonomies ) ) ) {
473
			$force = true;
474
		} elseif ( ! empty( $pods_cpt_ct ) && empty( $pods_cpt_ct['post_types'] ) && ! empty( $post_types ) ) {
475
			$force = true;
476
		} elseif ( ! empty( $pods_cpt_ct ) && empty( $pods_cpt_ct['taxonomies'] ) && ! empty( $taxonomies ) ) {
477
			$force = true;
478
		}
479
480
		if ( false === $pods_cpt_ct || $force ) {
481
			/**
482
			 * @var WP_Query
483
			 */
484
			global $wp_query;
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...
485
486
			$reserved_query_vars = array(
487
				'post_type',
488
				'taxonomy',
489
				'output',
490
			);
491
492
			if ( is_object( $wp_query ) ) {
493
				$reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
494
			}
495
496
			$pods_cpt_ct = array(
497
				'post_types' => array(),
498
				'taxonomies' => array(),
499
			);
500
501
			$pods_post_types      = $pods_taxonomies = array();
502
			$supported_post_types = $supported_taxonomies = array();
503
504
			$post_format_post_types = array();
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $post_format_post_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...
505
506
			foreach ( $post_types as $post_type ) {
507
				if ( isset( $pods_cpt_ct['post_types'][ $post_type['name'] ] ) ) {
508
					// Post type was setup already
509
					continue;
510
				} elseif ( ! empty( $post_type['object'] ) && isset( $existing_post_types[ $post_type['object'] ] ) ) {
511
					// Post type exists already
512
					continue;
513
				} elseif ( ! $force && isset( $existing_post_types[ $post_type['name'] ] ) ) {
514
					// Post type was setup and exists already, but we aren't forcing it to be setup again
515
					continue;
516
				}
517
518
				$post_type['options']['name'] = $post_type['name'];
519
				$post_type                    = array_merge( $post_type, (array) $post_type['options'] );
520
521
				$post_type_name = pods_v_sanitized( 'name', $post_type );
522
523
				// Labels
524
				$cpt_label    = esc_html( pods_v( 'label', $post_type, ucwords( str_replace( '_', ' ', pods_v( 'name', $post_type ) ) ), true ) );
525
				$cpt_singular = esc_html( pods_v( 'label_singular', $post_type, ucwords( str_replace( '_', ' ', pods_v( 'label', $post_type, $post_type_name, true ) ) ), true ) );
526
527
				$cpt_labels                          = array();
528
				$cpt_labels['name']                  = $cpt_label;
529
				$cpt_labels['singular_name']         = $cpt_singular;
530
				$cpt_labels['menu_name']             = pods_v( 'menu_name', $post_type, '', true );
531
				$cpt_labels['name_admin_bar']        = pods_v( 'name_admin_bar', $post_type, '', true );
532
				$cpt_labels['add_new']               = pods_v( 'label_add_new', $post_type, '', true );
533
				$cpt_labels['add_new_item']          = pods_v( 'label_add_new_item', $post_type, '', true );
534
				$cpt_labels['new_item']              = pods_v( 'label_new_item', $post_type, '', true );
535
				$cpt_labels['edit']                  = pods_v( 'label_edit', $post_type, '', true );
536
				$cpt_labels['edit_item']             = pods_v( 'label_edit_item', $post_type, '', true );
537
				$cpt_labels['view']                  = pods_v( 'label_view', $post_type, '', true );
538
				$cpt_labels['view_item']             = pods_v( 'label_view_item', $post_type, '', true );
539
				$cpt_labels['view_items']            = pods_v( 'label_view_items', $post_type, '', true );
540
				$cpt_labels['all_items']             = pods_v( 'label_all_items', $post_type, '', true );
541
				$cpt_labels['search_items']          = pods_v( 'label_search_items', $post_type, '', true );
542
				$cpt_labels['not_found']             = pods_v( 'label_not_found', $post_type, '', true );
543
				$cpt_labels['not_found_in_trash']    = pods_v( 'label_not_found_in_trash', $post_type, '', true );
544
				$cpt_labels['parent']                = pods_v( 'label_parent', $post_type, '', true );
545
				$cpt_labels['parent_item_colon']     = pods_v( 'label_parent_item_colon', $post_type, '', true );
546
				$cpt_labels['archives']              = pods_v( 'label_archives', $post_type, '', true );
547
				$cpt_labels['attributes']            = pods_v( 'label_attributes', $post_type, '', true );
548
				$cpt_labels['insert_into_item']      = pods_v( 'label_insert_into_item', $post_type, '', true );
549
				$cpt_labels['uploaded_to_this_item'] = pods_v( 'label_uploaded_to_this_item', $post_type, '', true );
550
				$cpt_labels['featured_image']        = pods_v( 'label_featured_image', $post_type, '', true );
551
				$cpt_labels['set_featured_image']    = pods_v( 'label_set_featured_image', $post_type, '', true );
552
				$cpt_labels['remove_featured_image'] = pods_v( 'label_remove_featured_image', $post_type, '', true );
553
				$cpt_labels['use_featured_image']    = pods_v( 'label_use_featured_image', $post_type, '', true );
554
				$cpt_labels['filter_items_list']     = pods_v( 'label_filter_items_list', $post_type, '', true );
555
				$cpt_labels['items_list_navigation'] = pods_v( 'label_items_list_navigation', $post_type, '', true );
556
				$cpt_labels['items_list']            = pods_v( 'label_items_list', $post_type, '', true );
557
558
				// Supported
559
				$cpt_supported = array(
560
					'title'           => (boolean) pods_v( 'supports_title', $post_type, false ),
561
					'editor'          => (boolean) pods_v( 'supports_editor', $post_type, false ),
562
					'author'          => (boolean) pods_v( 'supports_author', $post_type, false ),
563
					'thumbnail'       => (boolean) pods_v( 'supports_thumbnail', $post_type, false ),
564
					'excerpt'         => (boolean) pods_v( 'supports_excerpt', $post_type, false ),
565
					'trackbacks'      => (boolean) pods_v( 'supports_trackbacks', $post_type, false ),
566
					'custom-fields'   => (boolean) pods_v( 'supports_custom_fields', $post_type, false ),
567
					'comments'        => (boolean) pods_v( 'supports_comments', $post_type, false ),
568
					'revisions'       => (boolean) pods_v( 'supports_revisions', $post_type, false ),
569
					'page-attributes' => (boolean) pods_v( 'supports_page_attributes', $post_type, false ),
570
					'post-formats'    => (boolean) pods_v( 'supports_post_formats', $post_type, false ),
571
				);
572
573
				// Custom Supported
574
				$cpt_supported_custom = pods_v_sanitized( 'supports_custom', $post_type, '' );
575
576
				if ( ! empty( $cpt_supported_custom ) ) {
577
					$cpt_supported_custom = explode( ',', $cpt_supported_custom );
578
					$cpt_supported_custom = array_filter( array_unique( $cpt_supported_custom ) );
579
580
					foreach ( $cpt_supported_custom as $cpt_support ) {
581
						$cpt_supported[ $cpt_support ] = true;
582
					}
583
				}
584
585
				// Genesis Support
586
				if ( function_exists( 'genesis' ) ) {
587
					$cpt_supported['genesis-seo']             = (boolean) pods_v( 'supports_genesis_seo', $post_type, false );
588
					$cpt_supported['genesis-layouts']         = (boolean) pods_v( 'supports_genesis_layouts', $post_type, false );
589
					$cpt_supported['genesis-simple-sidebars'] = (boolean) pods_v( 'supports_genesis_simple_sidebars', $post_type, false );
590
				}
591
592
				// YARPP Support
593
				if ( defined( 'YARPP_VERSION' ) ) {
594
					$cpt_supported['yarpp_support'] = (boolean) pods_v( 'supports_yarpp_support', $post_type, false );
595
				}
596
597
				// Jetpack Support
598
				if ( class_exists( 'Jetpack' ) ) {
599
					$cpt_supported['supports_jetpack_publicize'] = (boolean) pods_v( 'supports_jetpack_publicize', $post_type, false );
600
					$cpt_supported['supports_jetpack_markdown']  = (boolean) pods_v( 'supports_jetpack_markdown', $post_type, false );
601
				}
602
603
				$cpt_supports = array();
604
605
				foreach ( $cpt_supported as $cpt_support => $supported ) {
606
					if ( true === $supported ) {
607
						$cpt_supports[] = $cpt_support;
608
609
						if ( 'post-formats' === $cpt_support ) {
610
							$post_format_post_types[] = $post_type_name;
611
						}
612
					}
613
				}
614
615
				if ( empty( $cpt_supports ) ) {
616
					$cpt_supports = false;
617
				}
618
619
				// Rewrite
620
				$cpt_rewrite       = (boolean) pods_v( 'rewrite', $post_type, true );
621
				$cpt_rewrite_array = array(
622
					'slug'       => pods_v( 'rewrite_custom_slug', $post_type, str_replace( '_', '-', $post_type_name ), true ),
623
					'with_front' => (boolean) pods_v( 'rewrite_with_front', $post_type, true ),
624
					'feeds'      => (boolean) pods_v( 'rewrite_feeds', $post_type, (boolean) pods_v( 'has_archive', $post_type, false ) ),
625
					'pages'      => (boolean) pods_v( 'rewrite_pages', $post_type, true ),
626
				);
627
628
				if ( false !== $cpt_rewrite ) {
629
					$cpt_rewrite = $cpt_rewrite_array;
630
				}
631
632
				$capability_type = pods_v( 'capability_type', $post_type, 'post' );
633
634
				if ( 'custom' === $capability_type ) {
635
					$capability_type = pods_v( 'capability_type_custom', $post_type, 'post' );
636
				}
637
638
				$show_in_menu = (boolean) pods_v( 'show_in_menu', $post_type, true );
639
640
				if ( $show_in_menu && 0 < strlen( pods_v( 'menu_location_custom', $post_type ) ) ) {
641
					$show_in_menu = pods_v( 'menu_location_custom', $post_type );
642
				}
643
644
				$menu_icon = pods_v( 'menu_icon', $post_type );
645
646
				if ( ! empty( $menu_icon ) ) {
647
					$menu_icon = pods_evaluate_tags( $menu_icon );
648
				}
649
650
				// Register Post Type
651
				$pods_post_types[ $post_type_name ] = array(
652
					'label'               => $cpt_label,
653
					'labels'              => $cpt_labels,
654
					'description'         => esc_html( pods_v( 'description', $post_type ) ),
655
					'public'              => (boolean) pods_v( 'public', $post_type, true ),
656
					'publicly_queryable'  => (boolean) pods_v( 'publicly_queryable', $post_type, (boolean) pods_v( 'public', $post_type, true ) ),
657
					'exclude_from_search' => (boolean) pods_v( 'exclude_from_search', $post_type, ( (boolean) pods_v( 'public', $post_type, true ) ? false : true ) ),
658
					'show_ui'             => (boolean) pods_v( 'show_ui', $post_type, (boolean) pods_v( 'public', $post_type, true ) ),
659
					'show_in_menu'        => $show_in_menu,
660
					'show_in_nav_menus'   => (boolean) pods_v( 'show_in_nav_menus', $post_type, (boolean) pods_v( 'public', $post_type, true ) ),
661
					'show_in_admin_bar'   => (boolean) pods_v( 'show_in_admin_bar', $post_type, (boolean) pods_v( 'show_in_menu', $post_type, true ) ),
662
					'menu_position'       => (int) pods_v( 'menu_position', $post_type, 0, true ),
663
					'menu_icon'           => $menu_icon,
664
					'capability_type'     => $capability_type,
665
					// 'capabilities' => $cpt_capabilities,
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...
666
					'map_meta_cap'        => (boolean) pods_v( 'capability_type_extra', $post_type, true ),
667
					'hierarchical'        => (boolean) pods_v( 'hierarchical', $post_type, false ),
668
					'supports'            => $cpt_supports,
669
					// 'register_meta_box_cb' => array($this, 'manage_meta_box'),
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% 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...
670
					// 'permalink_epmask' => EP_PERMALINK,
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
671
					'has_archive'         => pods_v( 'has_archive_slug', $post_type, (boolean) pods_v( 'has_archive', $post_type, false ), true ),
672
					'rewrite'             => $cpt_rewrite,
673
					'query_var'           => ( false !== (boolean) pods_v( 'query_var', $post_type, true ) ? pods_v( 'query_var_string', $post_type, $post_type_name, true ) : false ),
674
					'can_export'          => (boolean) pods_v( 'can_export', $post_type, true ),
675
				);
676
677
				// REST API
678
				$rest_enabled = (boolean) pods_v( 'rest_enable', $post_type, false );
679
680
				if ( $rest_enabled ) {
681
					$rest_base = sanitize_title( pods_v( 'rest_base', $post_type, $post_type_name ) );
682
683
					$pods_post_types[ $post_type_name ]['show_in_rest']          = true;
684
					$pods_post_types[ $post_type_name ]['rest_base']             = $rest_base;
685
					$pods_post_types[ $post_type_name ]['rest_controller_class'] = 'WP_REST_Posts_Controller';
686
				}
687
688
				// YARPP doesn't use 'supports' array option (yet)
689
				if ( ! empty( $cpt_supports['yarpp_support'] ) ) {
690
					$pods_post_types[ $post_type_name ]['yarpp_support'] = true;
691
				}
692
693
				// Prevent reserved query_var issues
694
				if ( in_array( $pods_post_types[ $post_type_name ]['query_var'], $reserved_query_vars, true ) ) {
695
					$pods_post_types[ $post_type_name ]['query_var'] = 'post_type_' . $pods_post_types[ $post_type_name ]['query_var'];
696
				}
697
698
				if ( 25 === (int) $pods_post_types[ $post_type_name ]['menu_position'] ) {
699
					$pods_post_types[ $post_type_name ]['menu_position'] ++;
700
				}
701
702
				if ( $pods_post_types[ $post_type_name ]['menu_position'] < 1 || in_array( $pods_post_types[ $post_type_name ]['menu_position'], $cpt_positions, true ) ) {
703
					unset( $pods_post_types[ $post_type_name ]['menu_position'] );
704
				} else {
705
					$cpt_positions[] = $pods_post_types[ $post_type_name ]['menu_position'];
706
707
					// This would be nice if WP supported floats in menu_position
708
					// $pods_post_types[ $post_type_name ][ 'menu_position' ] = $pods_post_types[ $post_type_name ][ 'menu_position' ] . '.1';
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% 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...
709
				}
710
711
				// Taxonomies
712
				$cpt_taxonomies = array();
713
				$_taxonomies    = get_taxonomies();
714
				$_taxonomies    = array_merge_recursive( $_taxonomies, $pods_taxonomies );
715
				$ignore         = array( 'nav_menu', 'link_category', 'post_format' );
716
717
				foreach ( $_taxonomies as $taxonomy => $label ) {
718
					if ( in_array( $taxonomy, $ignore, true ) ) {
719
						continue;
720
					}
721
722
					if ( false !== (boolean) pods_v( 'built_in_taxonomies_' . $taxonomy, $post_type, false ) ) {
723
						$cpt_taxonomies[] = $taxonomy;
724
725
						if ( isset( $supported_post_types[ $taxonomy ] ) && ! in_array( $post_type_name, $supported_post_types[ $taxonomy ], true ) ) {
726
							$supported_post_types[ $taxonomy ][] = $post_type_name;
727
						}
728
					}
729
				}
730
731
				if ( isset( $supported_taxonomies[ $post_type_name ] ) ) {
732
					$supported_taxonomies[ $post_type_name ] = array_merge( (array) $supported_taxonomies[ $post_type_name ], $cpt_taxonomies );
733
				} else {
734
					$supported_taxonomies[ $post_type_name ] = $cpt_taxonomies;
735
				}
736
			}//end foreach
737
738
			foreach ( $taxonomies as $taxonomy ) {
739
				if ( isset( $pods_cpt_ct['taxonomies'][ $taxonomy['name'] ] ) ) {
740
					// Taxonomy was setup already
741
					continue;
742
				} elseif ( ! empty( $taxonomy['object'] ) && isset( $existing_taxonomies[ $taxonomy['object'] ] ) ) {
743
					// Taxonomy exists already
744
					continue;
745
				} elseif ( ! $force && isset( $existing_taxonomies[ $taxonomy['name'] ] ) ) {
746
					// Taxonomy was setup and exists already, but we aren't forcing it to be setup again
747
					continue;
748
				}
749
750
				$taxonomy['options']['name'] = $taxonomy['name'];
751
				$taxonomy                    = array_merge( $taxonomy, (array) $taxonomy['options'] );
752
753
				$taxonomy_name = pods_v( 'name', $taxonomy );
754
755
				// Labels
756
				$ct_label    = esc_html( pods_v( 'label', $taxonomy, ucwords( str_replace( '_', ' ', pods_v( 'name', $taxonomy ) ) ), true ) );
757
				$ct_singular = esc_html( pods_v( 'label_singular', $taxonomy, ucwords( str_replace( '_', ' ', pods_v( 'label', $taxonomy, pods_v( 'name', $taxonomy ), true ) ) ), true ) );
758
759
				$ct_labels                               = array();
760
				$ct_labels['name']                       = $ct_label;
761
				$ct_labels['singular_name']              = $ct_singular;
762
				$ct_labels['menu_name']                  = pods_v( 'menu_name', $taxonomy, '', true );
763
				$ct_labels['search_items']               = pods_v( 'label_search_items', $taxonomy, '', true );
764
				$ct_labels['popular_items']              = pods_v( 'label_popular_items', $taxonomy, '', true );
765
				$ct_labels['all_items']                  = pods_v( 'label_all_items', $taxonomy, '', true );
766
				$ct_labels['parent_item']                = pods_v( 'label_parent_item', $taxonomy, '', true );
767
				$ct_labels['parent_item_colon']          = pods_v( 'label_parent_item_colon', $taxonomy, '', true );
768
				$ct_labels['edit_item']                  = pods_v( 'label_edit_item', $taxonomy, '', true );
769
				$ct_labels['update_item']                = pods_v( 'label_update_item', $taxonomy, '', true );
770
				$ct_labels['view_item']                  = pods_v( 'label_view_item', $taxonomy, '', true );
771
				$ct_labels['add_new_item']               = pods_v( 'label_add_new_item', $taxonomy, '', true );
772
				$ct_labels['new_item_name']              = pods_v( 'label_new_item_name', $taxonomy, '', true );
773
				$ct_labels['separate_items_with_commas'] = pods_v( 'label_separate_items_with_commas', $taxonomy, '', true );
774
				$ct_labels['add_or_remove_items']        = pods_v( 'label_add_or_remove_items', $taxonomy, '', true );
775
				$ct_labels['choose_from_most_used']      = pods_v( 'label_choose_from_the_most_used', $taxonomy, '', true );
776
				$ct_labels['not_found']                  = pods_v( 'label_not_found', $taxonomy, '', true );
777
				$ct_labels['no_terms']                   = pods_v( 'label_no_terms', $taxonomy, '', true );
778
				$ct_labels['items_list']                 = pods_v( 'label_items_list', $taxonomy, '', true );
779
				$ct_labels['items_list_navigation']      = pods_v( 'label_items_list_navigation', $taxonomy, '', true );
780
781
				// Rewrite
782
				$ct_rewrite       = (boolean) pods_v( 'rewrite', $taxonomy, true );
783
				$ct_rewrite_array = array(
784
					'slug'         => pods_v( 'rewrite_custom_slug', $taxonomy, str_replace( '_', '-', $taxonomy_name ), true ),
785
					'with_front'   => (boolean) pods_v( 'rewrite_with_front', $taxonomy, true ),
786
					'hierarchical' => (boolean) pods_v( 'rewrite_hierarchical', $taxonomy, (boolean) pods_v( 'hierarchical', $taxonomy, false ) ),
787
				);
788
789
				if ( false !== $ct_rewrite ) {
790
					$ct_rewrite = $ct_rewrite_array;
791
				}
792
793
				/**
794
				 * Default tax capabilities
795
				 *
796
				 * @see https://codex.wordpress.org/Function_Reference/register_taxonomy
797
				 */
798
				$capability_type  = pods_v( 'capability_type', $taxonomy, 'default' );
799
				$tax_capabilities = array();
800
801
				if ( 'custom' === $capability_type ) {
802
					$capability_type = pods_v( 'capability_type_custom', $taxonomy, 'default' );
803
					if ( ! empty( $capability_type ) && 'default' !== $capability_type ) {
804
						$capability_type       .= '_term';
805
						$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...
806
						$tax_capabilities       = array(
807
							// Singular
808
							'edit_term'    => 'edit_' . $capability_type,
809
							'delete_term'  => 'delete_' . $capability_type,
810
							'assign_term'  => 'assign_' . $capability_type,
811
							// Plural
812
							'manage_terms' => 'manage_' . $capability_type_plural,
813
							'edit_terms'   => 'edit_' . $capability_type_plural,
814
							'delete_terms' => 'delete_' . $capability_type_plural,
815
							'assign_terms' => 'assign_' . $capability_type_plural,
816
						);
817
					}
818
				}
819
820
				// Register Taxonomy
821
				$pods_taxonomies[ $taxonomy_name ] = array(
822
					'label'                 => $ct_label,
823
					'labels'                => $ct_labels,
824
					'public'                => (boolean) pods_v( 'public', $taxonomy, true ),
825
					'show_ui'               => (boolean) pods_v( 'show_ui', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ),
826
					'show_in_menu'          => (boolean) pods_v( 'show_in_menu', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ),
827
					'show_in_nav_menus'     => (boolean) pods_v( 'show_in_nav_menus', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ),
828
					'show_tagcloud'         => (boolean) pods_v( 'show_tagcloud', $taxonomy, (boolean) pods_v( 'show_ui', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ) ),
829
					'show_tagcloud_in_edit' => (boolean) pods_v( 'show_tagcloud_in_edit', $taxonomy, (boolean) pods_v( 'show_tagcloud', $taxonomy, (boolean) pods_v( 'show_ui', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ) ) ),
830
					'show_in_quick_edit'    => (boolean) pods_v( 'show_in_quick_edit', $taxonomy, (boolean) pods_v( 'show_ui', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ) ),
831
					'hierarchical'          => (boolean) pods_v( 'hierarchical', $taxonomy, false ),
832
					// 'capability_type'       => $capability_type,
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...
833
					'capabilities'          => $tax_capabilities,
834
					// 'map_meta_cap'          => (boolean) pods_v( 'capability_type_extra', $taxonomy, true ),
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
835
					'update_count_callback' => pods_v( 'update_count_callback', $taxonomy, null, true ),
836
					'query_var'             => ( false !== (boolean) pods_v( 'query_var', $taxonomy, true ) ? pods_v( 'query_var_string', $taxonomy, $taxonomy_name, true ) : false ),
837
					'rewrite'               => $ct_rewrite,
838
					'show_admin_column'     => (boolean) pods_v( 'show_admin_column', $taxonomy, false ),
839
					'sort'                  => (boolean) pods_v( 'sort', $taxonomy, false ),
840
				);
841
842
				if ( is_array( $ct_rewrite ) && ! $pods_taxonomies[ $taxonomy_name ]['query_var'] ) {
843
					$pods_taxonomies[ $taxonomy_name ]['query_var'] = pods_v( 'query_var_string', $taxonomy, $taxonomy_name, true );
844
				}
845
846
				// Prevent reserved query_var issues
847
				if ( in_array( $pods_taxonomies[ $taxonomy_name ]['query_var'], $reserved_query_vars, true ) ) {
848
					$pods_taxonomies[ $taxonomy_name ]['query_var'] = 'taxonomy_' . $pods_taxonomies[ $taxonomy_name ]['query_var'];
849
				}
850
851
				// REST API
852
				$rest_enabled = (boolean) pods_v( 'rest_enable', $taxonomy, false );
853
854
				if ( $rest_enabled ) {
855
					$rest_base = sanitize_title( pods_v( 'rest_base', $taxonomy, $taxonomy_name ) );
856
857
					$pods_taxonomies[ $taxonomy_name ]['show_in_rest']          = true;
858
					$pods_taxonomies[ $taxonomy_name ]['rest_base']             = $rest_base;
859
					$pods_taxonomies[ $taxonomy_name ]['rest_controller_class'] = 'WP_REST_Terms_Controller';
860
				}
861
862
				// Integration for Single Value Taxonomy UI
863
				if ( function_exists( 'tax_single_value_meta_box' ) ) {
864
					$pods_taxonomies[ $taxonomy_name ]['single_value'] = (boolean) pods_v( 'single_value', $taxonomy, false );
865
					$pods_taxonomies[ $taxonomy_name ]['required']     = (boolean) pods_v( 'single_value_required', $taxonomy, false );
866
				}
867
868
				// Post Types
869
				$ct_post_types = array();
870
				$_post_types   = get_post_types();
871
				$_post_types   = array_merge_recursive( $_post_types, $pods_post_types );
872
				$ignore        = array( 'revision' );
873
874
				foreach ( $_post_types as $post_type => $options ) {
875
					if ( in_array( $post_type, $ignore, true ) ) {
876
						continue;
877
					}
878
879
					if ( false !== (boolean) pods_v( 'built_in_post_types_' . $post_type, $taxonomy, false ) ) {
880
						$ct_post_types[] = $post_type;
881
882
						if ( isset( $supported_taxonomies[ $post_type ] ) && ! in_array( $taxonomy_name, $supported_taxonomies[ $post_type ], true ) ) {
883
							$supported_taxonomies[ $post_type ][] = $taxonomy_name;
884
						}
885
					}
886
				}
887
888
				if ( isset( $supported_post_types[ $taxonomy_name ] ) ) {
889
					$supported_post_types[ $taxonomy_name ] = array_merge( $supported_post_types[ $taxonomy_name ], $ct_post_types );
890
				} else {
891
					$supported_post_types[ $taxonomy_name ] = $ct_post_types;
892
				}
893
			}//end foreach
894
895
			$pods_post_types = apply_filters( 'pods_wp_post_types', $pods_post_types );
896
			$pods_taxonomies = apply_filters( 'pods_wp_taxonomies', $pods_taxonomies );
897
898
			$supported_post_types = apply_filters( 'pods_wp_supported_post_types', $supported_post_types );
899
			$supported_taxonomies = apply_filters( 'pods_wp_supported_taxonomies', $supported_taxonomies );
900
901
			foreach ( $pods_taxonomies as $taxonomy => $options ) {
902
				$ct_post_types = null;
903
904
				if ( isset( $supported_post_types[ $taxonomy ] ) && ! empty( $supported_post_types[ $taxonomy ] ) ) {
905
					$ct_post_types = $supported_post_types[ $taxonomy ];
906
				}
907
908
				$pods_cpt_ct['taxonomies'][ $taxonomy ] = array(
909
					'post_types' => $ct_post_types,
910
					'options'    => $options,
911
				);
912
			}
913
914
			foreach ( $pods_post_types as $post_type => $options ) {
915
				if ( isset( $supported_taxonomies[ $post_type ] ) && ! empty( $supported_taxonomies[ $post_type ] ) ) {
916
					$options['taxonomies'] = $supported_taxonomies[ $post_type ];
917
				}
918
919
				$pods_cpt_ct['post_types'][ $post_type ] = $options;
920
			}
921
922
			$pods_cpt_ct['post_format_post_types'] = $post_format_post_types;
923
924
			pods_transient_set( 'pods_wp_cpt_ct', $pods_cpt_ct );
925
		}//end if
926
927
		foreach ( $pods_cpt_ct['taxonomies'] as $taxonomy => $options ) {
928
			if ( isset( self::$content_types_registered['taxonomies'] ) && in_array( $taxonomy, self::$content_types_registered['taxonomies'], true ) ) {
929
				continue;
930
			}
931
932
			$ct_post_types = $options['post_types'];
933
			$options       = $options['options'];
934
935
			$options = self::object_label_fix( $options, 'taxonomy' );
936
937
			/**
938
			 * Hide tagcloud compatibility
939
			 *
940
			 * @todo check https://core.trac.wordpress.org/ticket/36964
941
			 * @see  wp-admin/edit-tags.php L389
942
			 */
943
			if ( true !== (boolean) pods_v( 'show_tagcloud_in_edit', $options, (boolean) pods_v( 'show_tagcloud', $options, true ) ) ) {
944
				$options['labels']['popular_items'] = null;
945
			}
946
947
			// Max length for taxonomies are 32 characters
948
			$taxonomy = substr( $taxonomy, 0, 32 );
949
950
			// i18n compatibility for plugins that override it
951
			if ( is_array( $options['rewrite'] ) && isset( $options['rewrite']['slug'] ) && ! empty( $options['rewrite']['slug'] ) ) {
952
				$options['rewrite']['slug'] = _x( $options['rewrite']['slug'], 'URL taxonomy slug', 'pods' );
953
			}
954
955
			/**
956
			 * Allow filtering of taxonomy options per taxonomy.
957
			 *
958
			 * @param array  $options       Taxonomy options
959
			 * @param string $taxonomy      Taxonomy name
960
			 * @param array  $ct_post_types Associated Post Types
961
			 */
962
			$options = apply_filters( 'pods_register_taxonomy_' . $taxonomy, $options, $taxonomy, $ct_post_types );
963
964
			/**
965
			 * Allow filtering of taxonomy options.
966
			 *
967
			 * @param array  $options       Taxonomy options
968
			 * @param string $taxonomy      Taxonomy name
969
			 * @param array  $ct_post_types Associated post types
970
			 */
971
			$options = apply_filters( 'pods_register_taxonomy', $options, $taxonomy, $ct_post_types );
972
973
			if ( 1 === (int) pods_v( 'pods_debug_register', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
974
				pods_debug( array( 'register_taxonomy', compact( 'taxonomy', 'ct_post_types', 'options' ) ) );
975
			}
976
977
			register_taxonomy( $taxonomy, $ct_post_types, $options );
978
979
			if ( ! empty( $options['show_in_rest'] ) ) {
980
				new PodsRESTFields( $taxonomy );
981
			}
982
983
			if ( ! isset( self::$content_types_registered['taxonomies'] ) ) {
984
				self::$content_types_registered['taxonomies'] = array();
985
			}
986
987
			self::$content_types_registered['taxonomies'][] = $taxonomy;
988
		}//end foreach
989
990
		foreach ( $pods_cpt_ct['post_types'] as $post_type => $options ) {
991
			if ( isset( self::$content_types_registered['post_types'] ) && in_array( $post_type, self::$content_types_registered['post_types'], true ) ) {
992
				continue;
993
			}
994
995
			$options = self::object_label_fix( $options, 'post_type' );
996
997
			// Max length for post types are 20 characters
998
			$post_type = substr( $post_type, 0, 20 );
999
1000
			// i18n compatibility for plugins that override it
1001
			if ( is_array( $options['rewrite'] ) && isset( $options['rewrite']['slug'] ) && ! empty( $options['rewrite']['slug'] ) ) {
1002
				$options['rewrite']['slug'] = _x( $options['rewrite']['slug'], 'URL slug', 'pods' );
1003
			}
1004
1005
			/**
1006
			 * Allow filtering of post type options per post type.
1007
			 *
1008
			 * @param array  $options   Post type options
1009
			 * @param string $post_type Post type name
1010
			 */
1011
			$options = apply_filters( 'pods_register_post_type_' . $post_type, $options, $post_type );
1012
1013
			/**
1014
			 * Allow filtering of post type options.
1015
			 *
1016
			 * @param array  $options   Post type options
1017
			 * @param string $post_type Post type name
1018
			 */
1019
			$options = apply_filters( 'pods_register_post_type', $options, $post_type );
1020
1021
			if ( 1 === (int) pods_v( 'pods_debug_register', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
1022
				pods_debug( array( 'register_post_type', compact( 'post_type', 'options' ) ) );
1023
			}
1024
1025
			register_post_type( $post_type, $options );
1026
1027
			// Register post format taxonomy for this post type
1028
			if ( isset( $pods_cpt_ct['post_format_post_types'] ) && in_array( $post_type, $pods_cpt_ct['post_format_post_types'], true ) ) {
1029
				register_taxonomy_for_object_type( 'post_format', $post_type );
1030
			}
1031
1032
			if ( ! empty( $options['show_in_rest'] ) ) {
1033
				new PodsRESTFields( $post_type );
1034
			}
1035
1036
			if ( ! isset( self::$content_types_registered['post_types'] ) ) {
1037
				self::$content_types_registered['post_types'] = array();
1038
			}
1039
1040
			self::$content_types_registered['post_types'][] = $post_type;
1041
		}//end foreach
1042
1043
		// Handle existing post types / taxonomies settings (just REST for now)
1044
		global $wp_post_types, $wp_taxonomies;
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...
1045
1046
		$post_type_names = wp_list_pluck( $post_types, 'name', 'id' );
1047
		$taxonomy_names  = wp_list_pluck( $taxonomies, 'name', 'id' );
1048
1049
		foreach ( $existing_post_types as $post_type_name => $post_type_name_again ) {
1050
			if ( isset( self::$content_types_registered['post_types'] ) && in_array( $post_type_name, self::$content_types_registered['post_types'], true ) ) {
1051
				// Post type already registered / setup by Pods
1052
				continue;
1053
			}
1054
1055
			$pod_id = array_search( $post_type_name, $post_type_names, true );
1056
1057
			if ( ! $pod_id ) {
1058
				// Post type not a pod
1059
				continue;
1060
			}
1061
1062
			$pod = $post_types[ $pod_id ];
1063
1064
			// REST API
1065
			$rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1066
1067
			if ( $rest_enabled ) {
1068
				if ( empty( $wp_post_types[ $post_type_name ]->show_in_rest ) ) {
1069
					$rest_base = sanitize_title( pods_v( 'rest_base', $pod['options'], pods_v( 'rest_base', $wp_post_types[ $post_type_name ] ), true ) );
1070
1071
					$wp_post_types[ $post_type_name ]->show_in_rest          = true;
1072
					$wp_post_types[ $post_type_name ]->rest_base             = $rest_base;
1073
					$wp_post_types[ $post_type_name ]->rest_controller_class = 'WP_REST_Posts_Controller';
1074
				}
1075
1076
				new PodsRESTFields( $post_type_name );
1077
			}
1078
		}//end foreach
1079
1080
		foreach ( $existing_taxonomies as $taxonomy_name => $taxonomy_name_again ) {
1081
			if ( isset( self::$content_types_registered['taxonomies'] ) && in_array( $taxonomy_name, self::$content_types_registered['taxonomies'], true ) ) {
1082
				// Taxonomy already registered / setup by Pods
1083
				continue;
1084
			}
1085
1086
			$pod_id = array_search( $taxonomy_name, $taxonomy_names, true );
1087
1088
			if ( ! $pod_id ) {
1089
				// Taxonomy not a pod
1090
				continue;
1091
			}
1092
1093
			$pod = $taxonomies[ $pod_id ];
1094
1095
			// REST API
1096
			$rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1097
1098
			if ( $rest_enabled ) {
1099
				if ( empty( $wp_taxonomies[ $taxonomy_name ]->show_in_rest ) ) {
1100
					$rest_base = sanitize_title( pods_v( 'rest_base', $pod['options'], pods_v( 'rest_base', $wp_taxonomies[ $taxonomy_name ] ), true ) );
1101
1102
					$wp_taxonomies[ $taxonomy_name ]->show_in_rest          = true;
1103
					$wp_taxonomies[ $taxonomy_name ]->rest_base             = $rest_base;
1104
					$wp_taxonomies[ $taxonomy_name ]->rest_controller_class = 'WP_REST_Terms_Controller';
1105
				}
1106
1107
				new PodsRESTFields( $taxonomy_name );
1108
			}
1109
		}//end foreach
1110
1111
		if ( ! empty( PodsMeta::$user ) ) {
1112
			$pod = current( PodsMeta::$user );
1113
1114
			$rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1115
1116
			if ( $rest_enabled ) {
1117
				new PodsRESTFields( $pod['name'] );
1118
			}
1119
		}
1120
1121
		if ( ! empty( PodsMeta::$media ) ) {
1122
			$pod = current( PodsMeta::$media );
1123
1124
			$rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1125
1126
			if ( $rest_enabled ) {
1127
				new PodsRESTFields( $pod['name'] );
1128
			}
1129
		}
1130
1131
	}
1132
1133
	/**
1134
	 * Check if we need to flush WordPress rewrite rules
1135
	 * This gets run during 'init' action late in the game to give other plugins time to register their rewrite rules
1136
	 */
1137
	public function flush_rewrite_rules() {
1138
1139
		$flush = (int) pods_transient_get( 'pods_flush_rewrites' );
1140
1141
		if ( 1 === $flush ) {
1142
			/**
1143
			 * @var $wp_rewrite WP_Rewrite
1144
			 */
1145
			global $wp_rewrite;
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...
1146
			$wp_rewrite->flush_rules();
1147
			$wp_rewrite->init();
1148
1149
			pods_transient_set( 'pods_flush_rewrites', 0 );
1150
		}
1151
	}
1152
1153
	/**
1154
	 * Update Post Type messages
1155
	 *
1156
	 * @param array $messages
1157
	 *
1158
	 * @return array
1159
	 * @since 2.0.2
1160
	 */
1161
	public function setup_updated_messages( $messages ) {
1162
1163
		global $post, $post_ID;
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...
1164
1165
		$post_types          = PodsMeta::$post_types;
1166
		$existing_post_types = get_post_types();
1167
1168
		$pods_cpt_ct = pods_transient_get( 'pods_wp_cpt_ct' );
1169
1170
		if ( empty( $pods_cpt_ct ) || empty( $post_types ) ) {
1171
			return $messages;
1172
		}
1173
1174
		/**
1175
		 * Use get_preview_post_link function added in 4.4, which eventually applies preview_post_link filter
1176
		 * Before 4.4, this filter is defined in wp-admin/includes/meta-boxes.php, $post parameter added in 4.0
1177
		 * there wasn't post parameter back in 3.8
1178
		 * Let's add $post in the filter as it won't hurt anyway.
1179
		 *
1180
		 * @since 2.6.8.1
1181
		 */
1182
		$preview_post_link = function_exists( 'get_preview_post_link' ) ? get_preview_post_link( $post ) : apply_filters( 'preview_post_link', add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ), $post );
1183
1184
		foreach ( $post_types as $post_type ) {
1185
			if ( ! isset( $pods_cpt_ct['post_types'][ $post_type['name'] ] ) ) {
1186
				continue;
1187
			}
1188
1189
			$labels = self::object_label_fix( $pods_cpt_ct['post_types'][ $post_type['name'] ], 'post_type' );
1190
			$labels = $labels['labels'];
1191
1192
			$messages[ $post_type['name'] ] = array(
1193
				1  => sprintf( __( '%1$s updated. <a href="%2$s">%3$s</a>', 'pods' ), $labels['singular_name'], esc_url( get_permalink( $post_ID ) ), $labels['view_item'] ),
1194
				2  => __( 'Custom field updated.', 'pods' ),
1195
				3  => __( 'Custom field deleted.', 'pods' ),
1196
				4  => sprintf( __( '%s updated.', 'pods' ), $labels['singular_name'] ),
1197
				/* translators: %s: date and time of the revision */
1198
				5  => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'pods' ), $labels['singular_name'], wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
1199
				6  => sprintf( __( '%1$s published. <a href="%2$s">%3$s</a>', 'pods' ), $labels['singular_name'], esc_url( get_permalink( $post_ID ) ), $labels['view_item'] ),
1200
				7  => sprintf( __( '%s saved.', 'pods' ), $labels['singular_name'] ),
1201
				8  => sprintf( __( '%1$s submitted. <a target="_blank" href="%2$s">Preview %3$s</a>', 'pods' ), $labels['singular_name'], esc_url( $preview_post_link ), $labels['singular_name'] ),
1202
				9  => sprintf(
1203
					__( '%1$s scheduled for: <strong>%2$s</strong>. <a target="_blank" href="%3$s">Preview %4$s</a>', 'pods' ), $labels['singular_name'],
1204
					// translators: Publish box date format, see http://php.net/date
1205
					date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ), $labels['singular_name']
1206
				),
1207
				10 => sprintf( __( '%1$s draft updated. <a target="_blank" href="%2$s">Preview %3$s</a>', 'pods' ), $labels['singular_name'], esc_url( $preview_post_link ), $labels['singular_name'] ),
1208
			);
1209
1210
			if ( false === (boolean) $pods_cpt_ct['post_types'][ $post_type['name'] ]['public'] ) {
1211
				$messages[ $post_type['name'] ][1] = sprintf( __( '%s updated.', 'pods' ), $labels['singular_name'] );
1212
				$messages[ $post_type['name'] ][6] = sprintf( __( '%s published.', 'pods' ), $labels['singular_name'] );
1213
				$messages[ $post_type['name'] ][8] = sprintf( __( '%s submitted.', 'pods' ), $labels['singular_name'] );
1214
				$messages[ $post_type['name'] ][9] = sprintf(
1215
					__( '%s scheduled for: <strong>%1$s</strong>.', 'pods' ), $labels['singular_name'],
1216
					// translators: Publish box date format, see http://php.net/date
1217
					date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) )
1218
				);
1219
				$messages[ $post_type['name'] ][10] = sprintf( __( '%s draft updated.', 'pods' ), $labels['singular_name'] );
1220
			}
1221
		}//end foreach
1222
1223
		return $messages;
1224
	}
1225
1226
	/**
1227
	 * @param        $args
1228
	 * @param string $type
1229
	 *
1230
	 * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use 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...
1231
	 */
1232
	public static function object_label_fix( $args, $type = 'post_type' ) {
1233
1234
		if ( empty( $args ) || ! is_array( $args ) ) {
1235
			$args = array();
1236
		}
1237
1238
		if ( ! isset( $args['labels'] ) || ! is_array( $args['labels'] ) ) {
1239
			$args['labels'] = array();
1240
		}
1241
1242
		$label          = pods_v( 'name', $args['labels'], pods_v( 'label', $args, __( 'Items', 'pods' ), true ), true );
1243
		$singular_label = pods_v( 'singular_name', $args['labels'], pods_v( 'label_singular', $args, __( 'Item', 'pods' ), true ), true );
1244
1245
		$labels = $args['labels'];
1246
1247
		$labels['name']          = $label;
1248
		$labels['singular_name'] = $singular_label;
1249
1250
		if ( 'post_type' === $type ) {
1251
			$labels['menu_name']             = pods_v( 'menu_name', $labels, $label, true );
1252
			$labels['name_admin_bar']        = pods_v( 'name_admin_bar', $labels, $singular_label, true );
1253
			$labels['add_new']               = pods_v( 'add_new', $labels, __( 'Add New', 'pods' ), true );
1254
			$labels['add_new_item']          = pods_v( 'add_new_item', $labels, sprintf( __( 'Add New %s', 'pods' ), $singular_label ), true );
1255
			$labels['new_item']              = pods_v( 'new_item', $labels, sprintf( __( 'New %s', 'pods' ), $singular_label ), true );
1256
			$labels['edit']                  = pods_v( 'edit', $labels, __( 'Edit', 'pods' ), true );
1257
			$labels['edit_item']             = pods_v( 'edit_item', $labels, sprintf( __( 'Edit %s', 'pods' ), $singular_label ), true );
1258
			$labels['view']                  = pods_v( 'view', $labels, sprintf( __( 'View %s', 'pods' ), $singular_label ), true );
1259
			$labels['view_item']             = pods_v( 'view_item', $labels, sprintf( __( 'View %s', 'pods' ), $singular_label ), true );
1260
			$labels['view_items']            = pods_v( 'view_items', $labels, sprintf( __( 'View %s', 'pods' ), $label ), true );
1261
			$labels['all_items']             = pods_v( 'all_items', $labels, sprintf( __( 'All %s', 'pods' ), $label ), true );
1262
			$labels['search_items']          = pods_v( 'search_items', $labels, sprintf( __( 'Search %s', 'pods' ), $label ), true );
1263
			$labels['not_found']             = pods_v( 'not_found', $labels, sprintf( __( 'No %s Found', 'pods' ), $label ), true );
1264
			$labels['not_found_in_trash']    = pods_v( 'not_found_in_trash', $labels, sprintf( __( 'No %s Found in Trash', 'pods' ), $label ), true );
1265
			$labels['parent']                = pods_v( 'parent', $labels, sprintf( __( 'Parent %s', 'pods' ), $singular_label ), true );
1266
			$labels['parent_item_colon']     = pods_v( 'parent_item_colon', $labels, sprintf( __( 'Parent %s:', 'pods' ), $singular_label ), true );
1267
			$labels['featured_image']        = pods_v( 'featured_image', $labels, __( 'Featured Image', 'pods' ), true );
1268
			$labels['set_featured_image']    = pods_v( 'set_featured_image', $labels, __( 'Set featured image', 'pods' ), true );
1269
			$labels['remove_featured_image'] = pods_v( 'remove_featured_image', $labels, __( 'Remove featured image', 'pods' ), true );
1270
			$labels['use_featured_image']    = pods_v( 'use_featured_image', $labels, __( 'Use as featured image', 'pods' ), true );
1271
			$labels['archives']              = pods_v( 'archives', $labels, sprintf( __( '%s Archives', 'pods' ), $singular_label ), true );
1272
			$labels['attributes']            = pods_v( 'attributes', $labels, sprintf( __( '%s Attributes', 'pods' ), $singular_label ), true );
1273
			$labels['insert_into_item']      = pods_v( 'insert_into_item', $labels, sprintf( __( 'Insert into %s', 'pods' ), $singular_label ), true );
1274
			$labels['uploaded_to_this_item'] = pods_v( 'uploaded_to_this_item', $labels, sprintf( __( 'Uploaded to this %s', 'pods' ), $singular_label ), true );
1275
			$labels['filter_items_list']     = pods_v( 'filter_items_list', $labels, sprintf( __( 'Filter %s lists', 'pods' ), $label ), true );
1276
			$labels['items_list_navigation'] = pods_v( 'items_list_navigation', $labels, sprintf( __( '%s navigation', 'pods' ), $label ), true );
1277
			$labels['items_list']            = pods_v( 'items_list', $labels, sprintf( __( '%s list', 'pods' ), $label ), true );
1278
		} elseif ( 'taxonomy' === $type ) {
1279
			$labels['menu_name']                  = pods_v( 'menu_name', $labels, $label, true );
1280
			$labels['search_items']               = pods_v( 'search_items', $labels, sprintf( __( 'Search %s', 'pods' ), $label ), true );
1281
			$labels['popular_items']              = pods_v( 'popular_items', $labels, sprintf( __( 'Popular %s', 'pods' ), $label ), true );
1282
			$labels['all_items']                  = pods_v( 'all_items', $labels, sprintf( __( 'All %s', 'pods' ), $label ), true );
1283
			$labels['parent_item']                = pods_v( 'parent_item', $labels, sprintf( __( 'Parent %s', 'pods' ), $singular_label ), true );
1284
			$labels['parent_item_colon']          = pods_v( 'parent_item_colon', $labels, sprintf( __( 'Parent %s :', 'pods' ), $singular_label ), true );
1285
			$labels['edit_item']                  = pods_v( 'edit_item', $labels, sprintf( __( 'Edit %s', 'pods' ), $singular_label ), true );
1286
			$labels['view_item']                  = pods_v( 'view_item', $labels, sprintf( __( 'View %s', 'pods' ), $singular_label ), true );
1287
			$labels['update_item']                = pods_v( 'update_item', $labels, sprintf( __( 'Update %s', 'pods' ), $singular_label ), true );
1288
			$labels['add_new_item']               = pods_v( 'add_new_item', $labels, sprintf( __( 'Add New %s', 'pods' ), $singular_label ), true );
1289
			$labels['new_item_name']              = pods_v( 'new_item_name', $labels, sprintf( __( 'New %s Name', 'pods' ), $singular_label ), true );
1290
			$labels['separate_items_with_commas'] = pods_v( 'separate_items_with_commas', $labels, sprintf( __( 'Separate %s with commas', 'pods' ), $label ), true );
1291
			$labels['add_or_remove_items']        = pods_v( 'add_or_remove_items', $labels, sprintf( __( 'Add or remove %s', 'pods' ), $label ), true );
1292
			$labels['choose_from_most_used']      = pods_v( 'choose_from_most_used', $labels, sprintf( __( 'Choose from the most used %s', 'pods' ), $label ), true );
1293
			$labels['not_found']                  = pods_v( 'not_found', $labels, sprintf( __( 'No %s found.', 'pods' ), $label ), true );
1294
			$labels['no_terms']                   = pods_v( 'no_terms', $labels, sprintf( __( 'No %s', 'pods' ), $label ), true );
1295
			$labels['items_list_navigation']      = pods_v( 'items_list_navigation', $labels, sprintf( __( '%s navigation', 'pods' ), $label ), true );
1296
			$labels['items_list']                 = pods_v( 'items_list', $labels, sprintf( __( '%s list', 'pods' ), $label ), true );
1297
		}//end if
1298
1299
		$args['labels'] = $labels;
1300
1301
		return $args;
1302
	}
1303
1304
	/**
1305
	 * Activate and Install
1306
	 */
1307
	public function activate_install() {
1308
1309
		register_activation_hook( PODS_DIR . 'init.php', array( $this, 'activate' ) );
1310
		register_deactivation_hook( PODS_DIR . 'init.php', array( $this, 'deactivate' ) );
1311
1312
		add_action( 'wpmu_new_blog', array( $this, 'new_blog' ), 10, 6 );
1313
1314
		if ( empty( self::$version ) || version_compare( self::$version, PODS_VERSION, '<' ) || version_compare( self::$version, PODS_DB_VERSION, '<=' ) || self::$upgrade_needed ) {
1315
			$this->setup();
1316
		} elseif ( self::$version !== PODS_VERSION ) {
1317
			delete_option( 'pods_framework_version' );
1318
			add_option( 'pods_framework_version', PODS_VERSION, '', 'yes' );
1319
1320
			self::$version = PODS_VERSION;
1321
1322
			pods_api()->cache_flush_pods();
1323
		}
1324
1325
	}
1326
1327
	/**
1328
	 *
1329
	 */
1330
	public function activate() {
1331
1332
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1333
1334
		if ( is_multisite() && 1 === (int) pods_v( 'networkwide' ) ) {
1335
			$_blog_ids = $wpdb->get_col( "SELECT `blog_id` FROM `{$wpdb->blogs}`" );
0 ignored issues
show
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1336
1337
			foreach ( $_blog_ids as $_blog_id ) {
1338
				$this->setup( $_blog_id );
1339
			}
1340
		} else {
1341
			$this->setup();
1342
		}
1343
	}
1344
1345
	/**
1346
	 *
1347
	 */
1348
	public function deactivate() {
1349
1350
		pods_api()->cache_flush_pods();
1351
1352
	}
1353
1354
	/**
1355
	 * @param null $current
1356
	 * @param null $last
1357
	 *
1358
	 * @return bool
1359
	 */
1360
	public function needs_upgrade( $current = null, $last = null ) {
1361
1362
		if ( null === $current ) {
1363
			$current = self::$version;
1364
		}
1365
1366
		if ( null === $last ) {
1367
			$last = self::$version_last;
1368
		}
1369
1370
		$upgrade_needed = false;
1371
1372
		if ( ! empty( $current ) ) {
1373
			foreach ( self::$upgrades as $old_version => $new_version ) {
1374
				/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% 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...
1375
				if ( '2.1.0' === $new_version && ( is_developer() ) )
1376
					continue;*/
1377
1378
				if ( version_compare( $last, $old_version, '>=' ) && version_compare( $last, $new_version, '<' ) && version_compare( $current, $new_version, '>=' ) && 1 !== self::$upgraded ) {
1379
					$upgrade_needed = true;
1380
1381
					break;
1382
				}
1383
			}
1384
		}
1385
1386
		return $upgrade_needed;
1387
	}
1388
1389
	/**
1390
	 * @param $_blog_id
1391
	 * @param $user_id
1392
	 * @param $domain
1393
	 * @param $path
1394
	 * @param $site_id
1395
	 * @param $meta
1396
	 */
1397
	public function new_blog( $_blog_id, $user_id, $domain, $path, $site_id, $meta ) {
1398
1399
		if ( is_multisite() && is_plugin_active_for_network( basename( PODS_DIR ) . '/init.php' ) ) {
1400
			$this->setup( $_blog_id );
1401
		}
1402
	}
1403
1404
	/**
1405
	 * @param null $_blog_id
1406
	 */
1407
	public function setup( $_blog_id = null ) {
1408
1409
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1410
1411
		// Switch DB table prefixes
1412
		if ( null !== $_blog_id && $_blog_id !== $wpdb->blogid ) {
1413
			switch_to_blog( pods_absint( $_blog_id ) );
0 ignored issues
show
switch_to_blog is not something you should ever need to do in a VIP theme context. Instead use an API (XML-RPC, REST) to interact with other sites if needed.
Loading history...
1414
		} else {
1415
			$_blog_id = null;
1416
		}
1417
1418
		// Setup DB tables
1419
		$pods_version      = get_option( 'pods_framework_version' );
1420
		$pods_version_last = get_option( 'pods_framework_version_last' );
1421
1422
		if ( empty( $pods_version ) ) {
1423
			// Install Pods
1424
			pods_upgrade()->install( $_blog_id );
1425
1426
			$old_version = get_option( 'pods_version' );
1427
1428
			if ( ! empty( $old_version ) ) {
1429
				if ( false === strpos( $old_version, '.' ) ) {
1430
					$old_version = pods_version_to_point( $old_version );
1431
				}
1432
1433
				delete_option( 'pods_framework_version_last' );
1434
				add_option( 'pods_framework_version_last', $pods_version, '', 'yes' );
1435
1436
				self::$version_last = $old_version;
1437
			}
1438
		} elseif ( $this->needs_upgrade( $pods_version, $pods_version_last ) ) {
1439
			// Upgrade Wizard needed
1440
			// Do not do anything
1441
			return;
1442
		} elseif ( version_compare( $pods_version, PODS_VERSION, '<=' ) ) {
1443
			// Update Pods and run any required DB updates
1444
			if ( false !== apply_filters( 'pods_update_run', null, PODS_VERSION, $pods_version, $_blog_id ) && ! isset( $_GET['pods_bypass_update'] ) ) {
1445
				do_action( 'pods_update', PODS_VERSION, $pods_version, $_blog_id );
1446
1447
				// Update 2.0 alpha / beta sites
1448
				if ( version_compare( '2.0.0-a-1', $pods_version, '<=' ) && version_compare( $pods_version, '2.0.0-b-15', '<=' ) ) {
1449
					include PODS_DIR . 'sql/update-2.0-beta.php';
1450
				}
1451
1452
				if ( version_compare( $pods_version, PODS_DB_VERSION, '<=' ) ) {
1453
					include PODS_DIR . 'sql/update.php';
1454
				}
1455
1456
				do_action( 'pods_update_post', PODS_VERSION, $pods_version, $_blog_id );
1457
			}
1458
1459
			delete_option( 'pods_framework_version_last' );
1460
			add_option( 'pods_framework_version_last', $pods_version, '', 'yes' );
1461
1462
			self::$version_last = $pods_version;
1463
		}//end if
1464
1465
		delete_option( 'pods_framework_version' );
1466
		add_option( 'pods_framework_version', PODS_VERSION, '', 'yes' );
1467
1468
		delete_option( 'pods_framework_db_version' );
1469
		add_option( 'pods_framework_db_version', PODS_DB_VERSION, '', 'yes' );
1470
1471
		self::$version    = PODS_VERSION;
1472
		self::$db_version = PODS_DB_VERSION;
1473
1474
		pods_api()->cache_flush_pods();
1475
1476
		// Restore DB table prefix (if switched)
1477
		if ( null !== $_blog_id ) {
1478
			restore_current_blog();
1479
		}
1480
1481
	}
1482
1483
	/**
1484
	 * @param null $_blog_id
1485
	 */
1486
	public function reset( $_blog_id = null ) {
1487
1488
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1489
1490
		// Switch DB table prefixes
1491
		if ( null !== $_blog_id && $_blog_id !== $wpdb->blogid ) {
1492
			switch_to_blog( pods_absint( $_blog_id ) );
0 ignored issues
show
switch_to_blog is not something you should ever need to do in a VIP theme context. Instead use an API (XML-RPC, REST) to interact with other sites if needed.
Loading history...
1493
		} else {
1494
			$_blog_id = null;
1495
		}
1496
1497
		$api = pods_api();
1498
1499
		$pods = $api->load_pods(
1500
			array(
1501
				'names_ids'  => true,
1502
				'table_info' => false,
1503
			)
1504
		);
1505
1506
		foreach ( $pods as $pod_id => $pod_label ) {
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...
1507
			$api->delete_pod( array( 'id' => $pod_id ) );
1508
		}
1509
1510
		$templates = $api->load_templates();
1511
1512
		foreach ( $templates as $template ) {
1513
			$api->delete_template( array( 'id' => $template['id'] ) );
1514
		}
1515
1516
		$pages = $api->load_pages();
1517
1518
		foreach ( $pages as $page ) {
1519
			$api->delete_page( array( 'id' => $page['id'] ) );
1520
		}
1521
1522
		$helpers = $api->load_helpers();
1523
1524
		foreach ( $helpers as $helper ) {
1525
			$api->delete_helper( array( 'id' => $helper['id'] ) );
1526
		}
1527
1528
		$tables = $wpdb->get_results( "SHOW TABLES LIKE '{$wpdb->prefix}pods%'", ARRAY_N );
0 ignored issues
show
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1529
1530
		if ( ! empty( $tables ) ) {
1531
			foreach ( $tables as $table ) {
1532
				$table = $table[0];
1533
1534
				pods_query( "DROP TABLE `{$table}`", false );
1535
			}
1536
		}
1537
1538
		// Remove any orphans
1539
		$wpdb->query(
0 ignored issues
show
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1540
			"
1541
                DELETE `p`, `pm`
1542
                FROM `{$wpdb->posts}` AS `p`
1543
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1544
                    ON `pm`.`post_id` = `p`.`ID`
1545
                WHERE
1546
                    `p`.`post_type` LIKE '_pods_%'
1547
            "
1548
		);
1549
1550
		delete_option( 'pods_framework_version' );
1551
		delete_option( 'pods_framework_db_version' );
1552
		delete_option( 'pods_framework_upgrade_2_0' );
1553
		delete_option( 'pods_framework_upgraded_1_x' );
1554
1555
		// @todo Make sure all entries are being cleaned and do something about the pods_framework_upgrade_{version} dynamic entries created by PodsUpgrade
1556
		delete_option( 'pods_framework_upgrade_2_0_0' );
1557
		delete_option( 'pods_framework_upgrade_2_0_sister_ids' );
1558
		delete_option( 'pods_framework_version_last' );
1559
1560
		delete_option( 'pods_component_settings' );
1561
1562
		$api->cache_flush_pods();
1563
1564
		pods_transient_clear( 'pods_flush_rewrites' );
1565
1566
		self::$version = '';
1567
1568
		// Restore DB table prefix (if switched)
1569
		if ( null !== $_blog_id ) {
1570
			restore_current_blog();
1571
		}
1572
	}
1573
1574
	public function run() {
1575
1576
		static $ran;
1577
1578
		if ( ! empty( $ran ) ) {
1579
			return;
1580
		}
1581
1582
		$ran = true;
1583
1584
		$this->load_i18n();
1585
1586
		if ( ! did_action( 'plugins_loaded' ) ) {
1587
			add_action( 'plugins_loaded', array( $this, 'load_components' ), 11 );
1588
		} else {
1589
			$this->load_components();
1590
		}
1591
1592
		if ( ! did_action( 'setup_theme' ) ) {
1593
			add_action( 'setup_theme', array( $this, 'load_meta' ), 14 );
1594
		} else {
1595
			$this->load_meta();
1596
		}
1597
1598
		if ( ! did_action( 'init' ) ) {
1599
			add_action( 'init', array( $this, 'core' ), 11 );
1600
			add_action( 'init', array( $this, 'setup_content_types' ), 11 );
1601
1602
			if ( is_admin() ) {
1603
				add_action( 'init', array( $this, 'admin_init' ), 12 );
1604
			}
1605
		} else {
1606
			$this->core();
1607
			$this->setup_content_types();
1608
1609
			if ( is_admin() ) {
1610
				$this->admin_init();
1611
			}
1612
		}
1613
1614
		add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1615
		add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1616
		add_action( 'login_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1617
1618
		add_filter( 'post_updated_messages', array( $this, 'setup_updated_messages' ), 10, 1 );
1619
		add_action( 'delete_attachment', array( $this, 'delete_attachment' ) );
1620
1621
		// Register widgets
1622
		add_action( 'widgets_init', array( $this, 'register_widgets' ) );
1623
1624
		// Show admin bar links
1625
		add_action( 'admin_bar_menu', array( $this, 'admin_bar_links' ), 81 );
1626
1627
		// Add WP-CLI commands
1628
		if ( defined( 'WP_CLI' ) && WP_CLI ) {
1629
			require_once PODS_DIR . 'classes/cli/Pods_CLI_Command.php';
1630
			require_once PODS_DIR . 'classes/cli/PodsAPI_CLI_Command.php';
1631
		}
1632
1633
	}
1634
1635
	/**
1636
	 * Delete Attachments from relationships
1637
	 *
1638
	 * @param int $_ID
1639
	 */
1640
	public function delete_attachment( $_ID ) {
1641
1642
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1643
1644
		$_ID = (int) $_ID;
1645
1646
		do_action( 'pods_delete_attachment', $_ID );
1647
1648
		$file_types = "'" . implode( "', '", PodsForm::file_field_types() ) . "'";
1649
1650
		if ( ! pods_tableless() ) {
1651
			$sql = "
1652
                DELETE `rel`
1653
                FROM `@wp_podsrel` AS `rel`
1654
                LEFT JOIN `{$wpdb->posts}` AS `p`
1655
                    ON
1656
                        `p`.`post_type` = '_pods_field'
1657
                        AND ( `p`.`ID` = `rel`.`field_id` OR `p`.`ID` = `rel`.`related_field_id` )
1658
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1659
                    ON
1660
                        `pm`.`post_id` = `p`.`ID`
1661
                        AND `pm`.`meta_key` = 'type'
1662
                        AND `pm`.`meta_value` IN ( {$file_types} )
1663
                WHERE
1664
                    `p`.`ID` IS NOT NULL
1665
                    AND `pm`.`meta_id` IS NOT NULL
1666
                    AND `rel`.`item_id` = {$_ID}";
1667
1668
			pods_query( $sql, false );
1669
		}
1670
1671
		// Post Meta
1672
		if ( ! empty( PodsMeta::$post_types ) ) {
1673
			$sql = "
1674
                DELETE `rel`
1675
                FROM `@wp_postmeta` AS `rel`
1676
                LEFT JOIN `{$wpdb->posts}` AS `p`
1677
                    ON
1678
                        `p`.`post_type` = '_pods_field'
1679
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1680
                    ON
1681
                        `pm`.`post_id` = `p`.`ID`
1682
                        AND `pm`.`meta_key` = 'type'
1683
                        AND `pm`.`meta_value` IN ( {$file_types} )
1684
                WHERE
1685
                    `p`.`ID` IS NOT NULL
1686
                    AND `pm`.`meta_id` IS NOT NULL
1687
                    AND `rel`.`meta_key` = `p`.`post_name`
1688
                    AND `rel`.`meta_value` = '{$_ID}'";
1689
1690
			pods_query( $sql, false );
1691
		}
1692
1693
		// User Meta
1694
		if ( ! empty( PodsMeta::$user ) ) {
1695
			$sql = "
1696
                DELETE `rel`
1697
                FROM `@wp_usermeta` AS `rel`
1698
                LEFT JOIN `{$wpdb->posts}` AS `p`
1699
                    ON
1700
                        `p`.`post_type` = '_pods_field'
1701
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1702
                    ON
1703
                        `pm`.`post_id` = `p`.`ID`
1704
                        AND `pm`.`meta_key` = 'type'
1705
                        AND `pm`.`meta_value` IN ( {$file_types} )
1706
                WHERE
1707
                    `p`.`ID` IS NOT NULL
1708
                    AND `pm`.`meta_id` IS NOT NULL
1709
                    AND `rel`.`meta_key` = `p`.`post_name`
1710
                    AND `rel`.`meta_value` = '{$_ID}'";
1711
1712
			pods_query( $sql, false );
1713
		}
1714
1715
		// Comment Meta
1716
		if ( ! empty( PodsMeta::$comment ) ) {
1717
			$sql = "
1718
                DELETE `rel`
1719
                FROM `@wp_commentmeta` AS `rel`
1720
                LEFT JOIN `{$wpdb->posts}` AS `p`
1721
                    ON
1722
                        `p`.`post_type` = '_pods_field'
1723
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1724
                    ON
1725
                        `pm`.`post_id` = `p`.`ID`
1726
                        AND `pm`.`meta_key` = 'type'
1727
                        AND `pm`.`meta_value` IN ( {$file_types} )
1728
                WHERE
1729
                    `p`.`ID` IS NOT NULL
1730
                    AND `pm`.`meta_id` IS NOT NULL
1731
                    AND `rel`.`meta_key` = `p`.`post_name`
1732
                    AND `rel`.`meta_value` = '{$_ID}'";
1733
1734
			pods_query( $sql, false );
1735
		}
1736
	}
1737
1738
	/**
1739
	 * Register widgets for Pods
1740
	 */
1741
	public function register_widgets() {
1742
1743
		$widgets = array(
1744
			'PodsWidgetSingle',
1745
			'PodsWidgetList',
1746
			'PodsWidgetField',
1747
			'PodsWidgetForm',
1748
			'PodsWidgetView',
1749
		);
1750
1751
		foreach ( $widgets as $widget ) {
1752
			if ( ! file_exists( PODS_DIR . 'classes/widgets/' . $widget . '.php' ) ) {
1753
				continue;
1754
			}
1755
1756
			require_once PODS_DIR . 'classes/widgets/' . $widget . '.php';
1757
1758
			register_widget( $widget );
1759
		}
1760
	}
1761
1762
	/**
1763
	 * Add Admin Bar links
1764
	 */
1765
	public function admin_bar_links() {
1766
1767
		global $wp_admin_bar, $pods;
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...
1768
1769
		if ( ! is_user_logged_in() || ! is_admin_bar_showing() ) {
1770
			return;
1771
		}
1772
1773
		$all_pods = pods_api()->load_pods(
1774
			array(
1775
				'type'       => 'pod',
1776
				'fields'     => false,
1777
				'table_info' => false,
1778
			)
1779
		);
1780
1781
		// Add New item links for all pods
1782
		foreach ( $all_pods as $pod ) {
0 ignored issues
show
The expression $all_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...
1783
			if ( 0 === (int) $pod['options']['show_in_menu'] ) {
1784
				continue;
1785
			}
1786
1787
			if ( ! pods_is_admin( array( 'pods', 'pods_content', 'pods_add_' . $pod['name'] ) ) ) {
1788
				continue;
1789
			}
1790
1791
			$singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
1792
1793
			$wp_admin_bar->add_node(
1794
				array(
1795
					'id'     => 'new-pod-' . $pod['name'],
1796
					'title'  => $singular_label,
1797
					'parent' => 'new-content',
1798
					'href'   => admin_url( 'admin.php?page=pods-manage-' . $pod['name'] . '&action=add' ),
1799
				)
1800
			);
1801
		}
1802
1803
		// Add edit link if we're on a pods page
1804
		if ( is_object( $pods ) && ! is_wp_error( $pods ) && ! empty( $pods->id ) && isset( $pods->pod_data ) && ! empty( $pods->pod_data ) && 'pod' === $pods->pod_data['type'] ) {
1805
			$pod = $pods->pod_data;
1806
1807
			if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod['name'] ) ) ) {
1808
				$singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
1809
1810
				$wp_admin_bar->add_node(
1811
					array(
1812
						'title' => sprintf( __( 'Edit %s', 'pods' ), $singular_label ),
1813
						'id'    => 'edit-pod',
1814
						'href'  => admin_url( 'admin.php?page=pods-manage-' . $pod['name'] . '&action=edit&id=' . $pods->id() ),
1815
					)
1816
				);
1817
			}
1818
		}
1819
1820
	}
1821
}
1822