Completed
Pull Request — 2.x (#4855)
by Scott Kingsley
07:42
created

PodsInit::plugins_loaded()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 4
nop 0
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
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
		add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) );
132
133
		add_action( 'wp_loaded', array( $this, 'flush_rewrite_rules' ) );
134
135
		$this->run();
136
137
	}
138
139
	/**
140
	 * Load the plugin textdomain and set default constants
141
	 */
142
	public function plugins_loaded() {
143
144
		if ( ! defined( 'PODS_LIGHT' ) ) {
145
			define( 'PODS_LIGHT', false );
146
		}
147
148
		if ( ! defined( 'PODS_TABLELESS' ) ) {
149
			define( 'PODS_TABLELESS', false );
150
		}
151
152
		load_plugin_textdomain( 'pods' );
153
154
	}
155
156
	/**
157
	 * Add compatibility for other plugins.
158
	 */
159
	public function after_setup_theme() {
160
161
		if ( ! defined( 'PODS_COMPATIBILITY' ) ) {
162
			define( 'PODS_COMPATIBILITY', true );
163
		}
164
165
		if ( ! PODS_COMPATIBILITY ) {
166
			return;
167
		}
168
169
		require_once PODS_DIR . 'includes/compatibility/acf.php';
170
171
	}
172
173
	/**
174
	 * Load Pods Components
175
	 */
176
	public function load_components() {
177
178
		if ( empty( self::$version ) ) {
179
			return;
180
		}
181
182
		if ( ! defined( 'PODS_LIGHT' ) || ! PODS_LIGHT ) {
183
			self::$components = pods_components();
184
		}
185
186
	}
187
188
	/**
189
	 * Load Pods Meta
190
	 */
191
	public function load_meta() {
192
193
		self::$meta = pods_meta()->core();
194
	}
195
196
	/**
197
	 *
198
	 */
199
	public function load_i18n() {
200
201
		self::$i18n = pods_i18n();
202
	}
203
204
	/**
205
	 * Set up the Pods core
206
	 */
207
	public function core() {
208
209
		if ( empty( self::$version ) ) {
210
			return;
211
		}
212
213
		// Session start
214
		pods_session_start();
215
216
		add_shortcode( 'pods', 'pods_shortcode' );
217
		add_shortcode( 'pods-form', 'pods_shortcode_form' );
218
219
		$security_settings = array(
220
			'pods_disable_file_browser'     => 0,
221
			'pods_files_require_login'      => 1,
222
			'pods_files_require_login_cap'  => '',
223
			'pods_disable_file_upload'      => 0,
224
			'pods_upload_require_login'     => 1,
225
			'pods_upload_require_login_cap' => '',
226
		);
227
228
		foreach ( $security_settings as $security_setting => $setting ) {
229
			$setting = get_option( $security_setting );
230
			if ( ! empty( $setting ) ) {
231
				$security_settings[ $security_setting ] = $setting;
232
			}
233
		}
234
235
		foreach ( $security_settings as $security_setting => $setting ) {
236
			if ( 0 === (int) $setting ) {
237
				$setting = false;
238
			} elseif ( 1 === (int) $setting ) {
239
				$setting = true;
240
			}
241
242
			if ( in_array(
243
				$security_setting, array(
244
					'pods_files_require_login',
245
					'pods_upload_require_login',
246
				), true
247
			) ) {
248
				if ( 0 < strlen( $security_settings[ $security_setting . '_cap' ] ) ) {
249
					$setting = $security_settings[ $security_setting . '_cap' ];
250
				}
251
			} elseif ( in_array(
252
				$security_setting, array(
253
					'pods_files_require_login_cap',
254
					'pods_upload_require_login_cap',
255
				), true
256
			) ) {
257
				continue;
258
			}
259
260
			if ( ! defined( strtoupper( $security_setting ) ) ) {
261
				define( strtoupper( $security_setting ), $setting );
262
			}
263
		}//end foreach
264
265
		$this->register_pods();
266
267
		$avatar = PodsForm::field_loader( 'avatar' );
268
269
		if ( method_exists( $avatar, 'get_avatar' ) ) {
270
			add_filter( 'get_avatar', array( $avatar, 'get_avatar' ), 10, 4 );
271
		}
272
	}
273
274
	/**
275
	 * Register Scripts and Styles
276
	 */
277
	public function register_assets() {
278
279
		$maybe_min = SCRIPT_DEBUG ? '' : '.min';
280
281
		wp_register_script( 'pods-json', PODS_URL . 'ui/js/jquery.json.js', array( 'jquery' ), '2.3' );
282
283
		if ( ! wp_script_is( 'jquery-qtip2', 'registered' ) ) {
284
			wp_register_script( 'jquery-qtip2', PODS_URL . 'ui/js/jquery.qtip.min.js', array( 'jquery' ), '2.2' );
285
		}
286
287
		wp_register_script(
288
			'pods', PODS_URL . 'ui/js/jquery.pods.js', array(
289
				'jquery',
290
				'pods-dfv',
291
				'pods-i18n',
292
				'pods-json',
293
				'jquery-qtip2',
294
			), PODS_VERSION, true
295
		);
296
297
		wp_register_script( 'pods-cleditor', PODS_URL . 'ui/js/jquery.cleditor.min.js', array( 'jquery' ), '1.3.0' );
298
299
		wp_register_script( 'pods-codemirror', PODS_URL . 'ui/js/codemirror.js', array(), '4.8', true );
300
		wp_register_script( 'pods-codemirror-loadmode', PODS_URL . 'ui/js/codemirror/addon/mode/loadmode.js', array( 'pods-codemirror' ), '4.8', true );
301
		wp_register_script( 'pods-codemirror-overlay', PODS_URL . 'ui/js/codemirror/addon/mode/overlay.js', array( 'pods-codemirror' ), '4.8', true );
302
		wp_register_script( 'pods-codemirror-hints', PODS_URL . 'ui/js/codemirror/addon/mode/show-hint.js', array( 'pods-codemirror' ), '4.8', true );
303
		wp_register_script( 'pods-codemirror-mode-xml', PODS_URL . 'ui/js/codemirror/mode/xml/xml.js', array( 'pods-codemirror' ), '4.8', true );
304
		wp_register_script( 'pods-codemirror-mode-html', PODS_URL . 'ui/js/codemirror/mode/htmlmixed/htmlmixed.js', array( 'pods-codemirror' ), '4.8', true );
305
		wp_register_script( 'pods-codemirror-mode-css', PODS_URL . 'ui/js/codemirror/mode/css/css.js', array( 'pods-codemirror' ), '4.8', true );
306
307
		if ( ! wp_script_is( 'jquery-ui-slideraccess', 'registered' ) ) {
308
			// No need to add dependencies. All managed by jquery-ui-timepicker.
309
			wp_register_script( 'jquery-ui-slideraccess', PODS_URL . 'ui/js/timepicker/jquery-ui-sliderAccess.js', array(), '0.3' );
310
		}
311
312
		if ( ! wp_script_is( 'jquery-ui-timepicker', 'registered' ) ) {
313
			wp_register_script(
314
				'jquery-ui-timepicker', PODS_URL . 'ui/js/timepicker/jquery-ui-timepicker-addon.min.js', array(
315
					'jquery',
316
					'jquery-ui-core',
317
					'jquery-ui-datepicker',
318
					'jquery-ui-slider',
319
					'jquery-ui-slideraccess',
320
				), '1.6.3'
321
			);
322
		}
323
		if ( ! wp_style_is( 'jquery-ui-timepicker', 'registered' ) ) {
324
			wp_register_style( 'jquery-ui-timepicker', PODS_URL . 'ui/js/timepicker/jquery-ui-timepicker-addon.min.css', array(), '1.6.3' );
325
		}
326
327
		wp_register_script(
328
			'pods-select2', PODS_URL . "ui/js/selectWoo/selectWoo{$maybe_min}.js", array(
329
				'jquery',
330
				'pods-i18n',
331
			), '1.0.1'
332
		);
333
		wp_register_style( 'pods-select2', PODS_URL . "ui/js/selectWoo/selectWoo{$maybe_min}.css", array(), '1.0.1' );
334
335
		// Marionette dependencies for MV fields
336
		wp_register_script( 'backbone.radio', PODS_URL . 'ui/js/marionette/backbone.radio.js', array( 'backbone' ), '2.0.0', true );
337
		wp_register_script(
338
			'marionette', PODS_URL . 'ui/js/marionette/backbone.marionette.js', array(
339
				'backbone',
340
				'backbone.radio',
341
			), '3.1.0', true
342
		);
343
344
		// MV stuff
345
		wp_register_script(
346
			'pods-dfv', PODS_URL . 'ui/js/pods-dfv/pods-dfv.min.js', array(
347
				'jquery',
348
				'jquery-ui-core',
349
				'jquery-ui-sortable',
350
				'pods-i18n',
351
				'marionette',
352
				'media-views',
353
				'media-models',
354
			), PODS_VERSION, true
355
		);
356
357
		// Check if Pod is a Modal Window
358
		if ( pods_is_modal_window() ) {
359
			add_filter( 'body_class', array( $this, 'add_classes_to_body_class' ) );
360
			add_filter( 'admin_body_class', array( $this, 'add_classes_to_body_class' ) );
361
		}
362
363
		// Deal with specifics on admin pages
364
		if ( is_admin() ) {
365
			$screen = get_current_screen();
366
367
			// DFV must be enqueued on the media library page for items in grid mode (see #4785)
368
			if ( $screen->base && 'upload' === $screen->base ) {
369
				wp_enqueue_script( 'pods-dfv' );
370
			}
371
		}
372
373
		$this->maybe_register_handlebars();
374
375
		// As of 2.7 we combine styles to just three .css files
376
		wp_register_style( 'pods-styles', PODS_URL . 'ui/styles/dist/pods.css', array(), PODS_VERSION );
377
		wp_register_style( 'pods-wizard', PODS_URL . 'ui/styles/dist/pods-wizard.css', array(), PODS_VERSION );
378
		wp_register_style( 'pods-form', PODS_URL . 'ui/styles/dist/pods-form.css', array(), PODS_VERSION );
379
	}
380
381
	/**
382
	 * Register handlebars where needed
383
	 *
384
	 * @since 2.7.2
385
	 */
386
	private function maybe_register_handlebars() {
387
388
		$register_handlebars = apply_filters( 'pods_script_register_handlebars', true );
389
390
		if ( is_admin() ) {
391
			$screen = get_current_screen();
392
393
			// Deregister the outdated Pods handlebars script on TEC event screen
394
			if ( $screen && 'tribe_events' === $screen->post_type ) {
395
				$register_handlebars = false;
396
			}
397
		}
398
399
		if ( $register_handlebars ) {
400
			wp_register_script( 'pods-handlebars', PODS_URL . 'ui/js/handlebars.js', array(), '1.0.0.beta.6' );
401
		}
402
	}
403
404
	/**
405
	 * @param string $classes Body classes.
406
	 *
407
	 * @return string
408
	 */
409
	public function add_classes_to_body_class( $classes ) {
410
411
		$classes .= 'pods-modal-window';
412
413
		return $classes;
414
	}
415
416
	/**
417
	 * Register internal Post Types
418
	 */
419
	public function register_pods() {
420
421
		$args = array(
422
			'label'           => 'Pods',
423
			'labels'          => array( 'singular_name' => 'Pod' ),
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'    => false,
431
			'supports'        => array( 'title', 'author' ),
432
			'menu_icon'       => 'dashicons-pods',
433
		);
434
435
		$args = self::object_label_fix( $args, 'post_type' );
436
437
		register_post_type( '_pods_pod', apply_filters( 'pods_internal_register_post_type_pod', $args ) );
438
439
		$args = array(
440
			'label'           => 'Pod Fields',
441
			'labels'          => array( 'singular_name' => 'Pod Field' ),
442
			'public'          => false,
443
			'can_export'      => false,
444
			'query_var'       => false,
445
			'rewrite'         => false,
446
			'capability_type' => 'pods_pod',
447
			'has_archive'     => false,
448
			'hierarchical'    => true,
449
			'supports'        => array( 'title', 'editor', 'author' ),
450
			'menu_icon'       => 'dashicons-pods',
451
		);
452
453
		$args = self::object_label_fix( $args, 'post_type' );
454
455
		register_post_type( '_pods_field', apply_filters( 'pods_internal_register_post_type_field', $args ) );
456
	}
457
458
	/**
459
	 * Include Admin
460
	 */
461
	public function admin_init() {
462
463
		self::$admin = pods_admin();
464
	}
465
466
	/**
467
	 * Register Post Types and Taxonomies
468
	 *
469
	 * @param bool $force
470
	 */
471
	public function setup_content_types( $force = false ) {
472
473
		if ( empty( self::$version ) ) {
474
			return;
475
		}
476
477
		require_once PODS_DIR . 'classes/PodsRESTHandlers.php';
478
		require_once PODS_DIR . 'classes/PodsRESTFields.php';
479
480
		$post_types = PodsMeta::$post_types;
481
		$taxonomies = PodsMeta::$taxonomies;
482
483
		$existing_post_types = get_post_types();
484
		$existing_taxonomies = get_taxonomies();
485
486
		$pods_cpt_ct = pods_transient_get( 'pods_wp_cpt_ct' );
487
488
		$cpt_positions = array();
489
490
		if ( empty( $pods_cpt_ct ) && ( ! empty( $post_types ) || ! empty( $taxonomies ) ) ) {
491
			$force = true;
492
		} elseif ( ! empty( $pods_cpt_ct ) && empty( $pods_cpt_ct['post_types'] ) && ! empty( $post_types ) ) {
493
			$force = true;
494
		} elseif ( ! empty( $pods_cpt_ct ) && empty( $pods_cpt_ct['taxonomies'] ) && ! empty( $taxonomies ) ) {
495
			$force = true;
496
		}
497
498
		if ( false === $pods_cpt_ct || $force ) {
499
			/**
500
			 * @var WP_Query
501
			 */
502
			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...
503
504
			$reserved_query_vars = array(
505
				'post_type',
506
				'taxonomy',
507
				'output',
508
			);
509
510
			if ( is_object( $wp_query ) ) {
511
				$reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
512
			}
513
514
			$pods_cpt_ct = array(
515
				'post_types' => array(),
516
				'taxonomies' => array(),
517
			);
518
519
			$pods_post_types      = $pods_taxonomies = array();
520
			$supported_post_types = $supported_taxonomies = array();
521
522
			$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...
523
524
			foreach ( $post_types as $post_type ) {
525
				if ( isset( $pods_cpt_ct['post_types'][ $post_type['name'] ] ) ) {
526
					// Post type was setup already
527
					continue;
528
				} elseif ( ! empty( $post_type['object'] ) && isset( $existing_post_types[ $post_type['object'] ] ) ) {
529
					// Post type exists already
530
					continue;
531
				} elseif ( ! $force && isset( $existing_post_types[ $post_type['name'] ] ) ) {
532
					// Post type was setup and exists already, but we aren't forcing it to be setup again
533
					continue;
534
				}
535
536
				$post_type['options']['name'] = $post_type['name'];
537
				$post_type                    = array_merge( $post_type, (array) $post_type['options'] );
538
539
				$post_type_name = pods_v_sanitized( 'name', $post_type );
540
541
				// Labels
542
				$cpt_label    = esc_html( pods_v( 'label', $post_type, ucwords( str_replace( '_', ' ', pods_v( 'name', $post_type ) ) ), true ) );
543
				$cpt_singular = esc_html( pods_v( 'label_singular', $post_type, ucwords( str_replace( '_', ' ', pods_v( 'label', $post_type, $post_type_name, true ) ) ), true ) );
544
545
				$cpt_labels                          = array();
546
				$cpt_labels['name']                  = $cpt_label;
547
				$cpt_labels['singular_name']         = $cpt_singular;
548
				$cpt_labels['menu_name']             = pods_v( 'menu_name', $post_type, '', true );
549
				$cpt_labels['name_admin_bar']        = pods_v( 'name_admin_bar', $post_type, '', true );
550
				$cpt_labels['add_new']               = pods_v( 'label_add_new', $post_type, '', true );
551
				$cpt_labels['add_new_item']          = pods_v( 'label_add_new_item', $post_type, '', true );
552
				$cpt_labels['new_item']              = pods_v( 'label_new_item', $post_type, '', true );
553
				$cpt_labels['edit']                  = pods_v( 'label_edit', $post_type, '', true );
554
				$cpt_labels['edit_item']             = pods_v( 'label_edit_item', $post_type, '', true );
555
				$cpt_labels['view']                  = pods_v( 'label_view', $post_type, '', true );
556
				$cpt_labels['view_item']             = pods_v( 'label_view_item', $post_type, '', true );
557
				$cpt_labels['view_items']            = pods_v( 'label_view_items', $post_type, '', true );
558
				$cpt_labels['all_items']             = pods_v( 'label_all_items', $post_type, '', true );
559
				$cpt_labels['search_items']          = pods_v( 'label_search_items', $post_type, '', true );
560
				$cpt_labels['not_found']             = pods_v( 'label_not_found', $post_type, '', true );
561
				$cpt_labels['not_found_in_trash']    = pods_v( 'label_not_found_in_trash', $post_type, '', true );
562
				$cpt_labels['parent']                = pods_v( 'label_parent', $post_type, '', true );
563
				$cpt_labels['parent_item_colon']     = pods_v( 'label_parent_item_colon', $post_type, '', true );
564
				$cpt_labels['archives']              = pods_v( 'label_archives', $post_type, '', true );
565
				$cpt_labels['attributes']            = pods_v( 'label_attributes', $post_type, '', true );
566
				$cpt_labels['insert_into_item']      = pods_v( 'label_insert_into_item', $post_type, '', true );
567
				$cpt_labels['uploaded_to_this_item'] = pods_v( 'label_uploaded_to_this_item', $post_type, '', true );
568
				$cpt_labels['featured_image']        = pods_v( 'label_featured_image', $post_type, '', true );
569
				$cpt_labels['set_featured_image']    = pods_v( 'label_set_featured_image', $post_type, '', true );
570
				$cpt_labels['remove_featured_image'] = pods_v( 'label_remove_featured_image', $post_type, '', true );
571
				$cpt_labels['use_featured_image']    = pods_v( 'label_use_featured_image', $post_type, '', true );
572
				$cpt_labels['filter_items_list']     = pods_v( 'label_filter_items_list', $post_type, '', true );
573
				$cpt_labels['items_list_navigation'] = pods_v( 'label_items_list_navigation', $post_type, '', true );
574
				$cpt_labels['items_list']            = pods_v( 'label_items_list', $post_type, '', true );
575
576
				// Supported
577
				$cpt_supported = array(
578
					'title'           => (boolean) pods_v( 'supports_title', $post_type, false ),
579
					'editor'          => (boolean) pods_v( 'supports_editor', $post_type, false ),
580
					'author'          => (boolean) pods_v( 'supports_author', $post_type, false ),
581
					'thumbnail'       => (boolean) pods_v( 'supports_thumbnail', $post_type, false ),
582
					'excerpt'         => (boolean) pods_v( 'supports_excerpt', $post_type, false ),
583
					'trackbacks'      => (boolean) pods_v( 'supports_trackbacks', $post_type, false ),
584
					'custom-fields'   => (boolean) pods_v( 'supports_custom_fields', $post_type, false ),
585
					'comments'        => (boolean) pods_v( 'supports_comments', $post_type, false ),
586
					'revisions'       => (boolean) pods_v( 'supports_revisions', $post_type, false ),
587
					'page-attributes' => (boolean) pods_v( 'supports_page_attributes', $post_type, false ),
588
					'post-formats'    => (boolean) pods_v( 'supports_post_formats', $post_type, false ),
589
				);
590
591
				// Custom Supported
592
				$cpt_supported_custom = pods_v_sanitized( 'supports_custom', $post_type, '' );
593
594
				if ( ! empty( $cpt_supported_custom ) ) {
595
					$cpt_supported_custom = explode( ',', $cpt_supported_custom );
596
					$cpt_supported_custom = array_filter( array_unique( $cpt_supported_custom ) );
597
598
					foreach ( $cpt_supported_custom as $cpt_support ) {
599
						$cpt_supported[ $cpt_support ] = true;
600
					}
601
				}
602
603
				// Genesis Support
604
				if ( function_exists( 'genesis' ) ) {
605
					$cpt_supported['genesis-seo']             = (boolean) pods_v( 'supports_genesis_seo', $post_type, false );
606
					$cpt_supported['genesis-layouts']         = (boolean) pods_v( 'supports_genesis_layouts', $post_type, false );
607
					$cpt_supported['genesis-simple-sidebars'] = (boolean) pods_v( 'supports_genesis_simple_sidebars', $post_type, false );
608
				}
609
610
				// YARPP Support
611
				if ( defined( 'YARPP_VERSION' ) ) {
612
					$cpt_supported['yarpp_support'] = (boolean) pods_v( 'supports_yarpp_support', $post_type, false );
613
				}
614
615
				// Jetpack Support
616
				if ( class_exists( 'Jetpack' ) ) {
617
					$cpt_supported['supports_jetpack_publicize'] = (boolean) pods_v( 'supports_jetpack_publicize', $post_type, false );
618
					$cpt_supported['supports_jetpack_markdown']  = (boolean) pods_v( 'supports_jetpack_markdown', $post_type, false );
619
				}
620
621
				$cpt_supports = array();
622
623
				foreach ( $cpt_supported as $cpt_support => $supported ) {
624
					if ( true === $supported ) {
625
						$cpt_supports[] = $cpt_support;
626
627
						if ( 'post-formats' === $cpt_support ) {
628
							$post_format_post_types[] = $post_type_name;
629
						}
630
					}
631
				}
632
633
				if ( empty( $cpt_supports ) ) {
634
					$cpt_supports = false;
635
				}
636
637
				// Rewrite
638
				$cpt_rewrite       = (boolean) pods_v( 'rewrite', $post_type, true );
639
				$cpt_rewrite_array = array(
640
					'slug'       => pods_v( 'rewrite_custom_slug', $post_type, str_replace( '_', '-', $post_type_name ), true ),
641
					'with_front' => (boolean) pods_v( 'rewrite_with_front', $post_type, true ),
642
					'feeds'      => (boolean) pods_v( 'rewrite_feeds', $post_type, (boolean) pods_v( 'has_archive', $post_type, false ) ),
643
					'pages'      => (boolean) pods_v( 'rewrite_pages', $post_type, true ),
644
				);
645
646
				if ( false !== $cpt_rewrite ) {
647
					$cpt_rewrite = $cpt_rewrite_array;
648
				}
649
650
				$capability_type = pods_v( 'capability_type', $post_type, 'post' );
651
652
				if ( 'custom' === $capability_type ) {
653
					$capability_type = pods_v( 'capability_type_custom', $post_type, 'post' );
654
				}
655
656
				$show_in_menu = (boolean) pods_v( 'show_in_menu', $post_type, true );
657
658
				if ( $show_in_menu && 0 < strlen( pods_v( 'menu_location_custom', $post_type ) ) ) {
659
					$show_in_menu = pods_v( 'menu_location_custom', $post_type );
660
				}
661
662
				$menu_icon = pods_v( 'menu_icon', $post_type );
663
664
				if ( ! empty( $menu_icon ) ) {
665
					$menu_icon = pods_evaluate_tags( $menu_icon );
666
				}
667
668
				// Register Post Type
669
				$pods_post_types[ $post_type_name ] = array(
670
					'label'               => $cpt_label,
671
					'labels'              => $cpt_labels,
672
					'description'         => esc_html( pods_v( 'description', $post_type ) ),
673
					'public'              => (boolean) pods_v( 'public', $post_type, true ),
674
					'publicly_queryable'  => (boolean) pods_v( 'publicly_queryable', $post_type, (boolean) pods_v( 'public', $post_type, true ) ),
675
					'exclude_from_search' => (boolean) pods_v( 'exclude_from_search', $post_type, ( (boolean) pods_v( 'public', $post_type, true ) ? false : true ) ),
676
					'show_ui'             => (boolean) pods_v( 'show_ui', $post_type, (boolean) pods_v( 'public', $post_type, true ) ),
677
					'show_in_menu'        => $show_in_menu,
678
					'show_in_nav_menus'   => (boolean) pods_v( 'show_in_nav_menus', $post_type, (boolean) pods_v( 'public', $post_type, true ) ),
679
					'show_in_admin_bar'   => (boolean) pods_v( 'show_in_admin_bar', $post_type, (boolean) pods_v( 'show_in_menu', $post_type, true ) ),
680
					'menu_position'       => (int) pods_v( 'menu_position', $post_type, 0, true ),
681
					'menu_icon'           => $menu_icon,
682
					'capability_type'     => $capability_type,
683
					// '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...
684
					'map_meta_cap'        => (boolean) pods_v( 'capability_type_extra', $post_type, true ),
685
					'hierarchical'        => (boolean) pods_v( 'hierarchical', $post_type, false ),
686
					'supports'            => $cpt_supports,
687
					// '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...
688
					// '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...
689
					'has_archive'         => pods_v( 'has_archive_slug', $post_type, (boolean) pods_v( 'has_archive', $post_type, false ), true ),
690
					'rewrite'             => $cpt_rewrite,
691
					'query_var'           => ( false !== (boolean) pods_v( 'query_var', $post_type, true ) ? pods_v( 'query_var_string', $post_type, $post_type_name, true ) : false ),
692
					'can_export'          => (boolean) pods_v( 'can_export', $post_type, true ),
693
				);
694
695
				// REST API
696
				$rest_enabled = (boolean) pods_v( 'rest_enable', $post_type, false );
697
698
				if ( $rest_enabled ) {
699
					$rest_base = sanitize_title( pods_v( 'rest_base', $post_type, $post_type_name ) );
700
701
					$pods_post_types[ $post_type_name ]['show_in_rest']          = true;
702
					$pods_post_types[ $post_type_name ]['rest_base']             = $rest_base;
703
					$pods_post_types[ $post_type_name ]['rest_controller_class'] = 'WP_REST_Posts_Controller';
704
				}
705
706
				// YARPP doesn't use 'supports' array option (yet)
707
				if ( ! empty( $cpt_supports['yarpp_support'] ) ) {
708
					$pods_post_types[ $post_type_name ]['yarpp_support'] = true;
709
				}
710
711
				// Prevent reserved query_var issues
712
				if ( in_array( $pods_post_types[ $post_type_name ]['query_var'], $reserved_query_vars, true ) ) {
713
					$pods_post_types[ $post_type_name ]['query_var'] = 'post_type_' . $pods_post_types[ $post_type_name ]['query_var'];
714
				}
715
716
				if ( 25 === (int) $pods_post_types[ $post_type_name ]['menu_position'] ) {
717
					$pods_post_types[ $post_type_name ]['menu_position'] ++;
718
				}
719
720
				if ( $pods_post_types[ $post_type_name ]['menu_position'] < 1 || in_array( $pods_post_types[ $post_type_name ]['menu_position'], $cpt_positions, true ) ) {
721
					unset( $pods_post_types[ $post_type_name ]['menu_position'] );
722
				} else {
723
					$cpt_positions[] = $pods_post_types[ $post_type_name ]['menu_position'];
724
725
					// This would be nice if WP supported floats in menu_position
726
					// $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...
727
				}
728
729
				// Taxonomies
730
				$cpt_taxonomies = array();
731
				$_taxonomies    = get_taxonomies();
732
				$_taxonomies    = array_merge_recursive( $_taxonomies, $pods_taxonomies );
733
				$ignore         = array( 'nav_menu', 'link_category', 'post_format' );
734
735
				foreach ( $_taxonomies as $taxonomy => $label ) {
736
					if ( in_array( $taxonomy, $ignore, true ) ) {
737
						continue;
738
					}
739
740
					if ( false !== (boolean) pods_v( 'built_in_taxonomies_' . $taxonomy, $post_type, false ) ) {
741
						$cpt_taxonomies[] = $taxonomy;
742
743
						if ( isset( $supported_post_types[ $taxonomy ] ) && ! in_array( $post_type_name, $supported_post_types[ $taxonomy ], true ) ) {
744
							$supported_post_types[ $taxonomy ][] = $post_type_name;
745
						}
746
					}
747
				}
748
749
				if ( isset( $supported_taxonomies[ $post_type_name ] ) ) {
750
					$supported_taxonomies[ $post_type_name ] = array_merge( (array) $supported_taxonomies[ $post_type_name ], $cpt_taxonomies );
751
				} else {
752
					$supported_taxonomies[ $post_type_name ] = $cpt_taxonomies;
753
				}
754
			}//end foreach
755
756
			foreach ( $taxonomies as $taxonomy ) {
757
				if ( isset( $pods_cpt_ct['taxonomies'][ $taxonomy['name'] ] ) ) {
758
					// Taxonomy was setup already
759
					continue;
760
				} elseif ( ! empty( $taxonomy['object'] ) && isset( $existing_taxonomies[ $taxonomy['object'] ] ) ) {
761
					// Taxonomy exists already
762
					continue;
763
				} elseif ( ! $force && isset( $existing_taxonomies[ $taxonomy['name'] ] ) ) {
764
					// Taxonomy was setup and exists already, but we aren't forcing it to be setup again
765
					continue;
766
				}
767
768
				$taxonomy['options']['name'] = $taxonomy['name'];
769
				$taxonomy                    = array_merge( $taxonomy, (array) $taxonomy['options'] );
770
771
				$taxonomy_name = pods_v( 'name', $taxonomy );
772
773
				// Labels
774
				$ct_label    = esc_html( pods_v( 'label', $taxonomy, ucwords( str_replace( '_', ' ', pods_v( 'name', $taxonomy ) ) ), true ) );
775
				$ct_singular = esc_html( pods_v( 'label_singular', $taxonomy, ucwords( str_replace( '_', ' ', pods_v( 'label', $taxonomy, pods_v( 'name', $taxonomy ), true ) ) ), true ) );
776
777
				$ct_labels                               = array();
778
				$ct_labels['name']                       = $ct_label;
779
				$ct_labels['singular_name']              = $ct_singular;
780
				$ct_labels['menu_name']                  = pods_v( 'menu_name', $taxonomy, '', true );
781
				$ct_labels['search_items']               = pods_v( 'label_search_items', $taxonomy, '', true );
782
				$ct_labels['popular_items']              = pods_v( 'label_popular_items', $taxonomy, '', true );
783
				$ct_labels['all_items']                  = pods_v( 'label_all_items', $taxonomy, '', true );
784
				$ct_labels['parent_item']                = pods_v( 'label_parent_item', $taxonomy, '', true );
785
				$ct_labels['parent_item_colon']          = pods_v( 'label_parent_item_colon', $taxonomy, '', true );
786
				$ct_labels['edit_item']                  = pods_v( 'label_edit_item', $taxonomy, '', true );
787
				$ct_labels['update_item']                = pods_v( 'label_update_item', $taxonomy, '', true );
788
				$ct_labels['view_item']                  = pods_v( 'label_view_item', $taxonomy, '', true );
789
				$ct_labels['add_new_item']               = pods_v( 'label_add_new_item', $taxonomy, '', true );
790
				$ct_labels['new_item_name']              = pods_v( 'label_new_item_name', $taxonomy, '', true );
791
				$ct_labels['separate_items_with_commas'] = pods_v( 'label_separate_items_with_commas', $taxonomy, '', true );
792
				$ct_labels['add_or_remove_items']        = pods_v( 'label_add_or_remove_items', $taxonomy, '', true );
793
				$ct_labels['choose_from_most_used']      = pods_v( 'label_choose_from_the_most_used', $taxonomy, '', true );
794
				$ct_labels['not_found']                  = pods_v( 'label_not_found', $taxonomy, '', true );
795
				$ct_labels['no_terms']                   = pods_v( 'label_no_terms', $taxonomy, '', true );
796
				$ct_labels['items_list']                 = pods_v( 'label_items_list', $taxonomy, '', true );
797
				$ct_labels['items_list_navigation']      = pods_v( 'label_items_list_navigation', $taxonomy, '', true );
798
799
				// Rewrite
800
				$ct_rewrite       = (boolean) pods_v( 'rewrite', $taxonomy, true );
801
				$ct_rewrite_array = array(
802
					'slug'         => pods_v( 'rewrite_custom_slug', $taxonomy, str_replace( '_', '-', $taxonomy_name ), true ),
803
					'with_front'   => (boolean) pods_v( 'rewrite_with_front', $taxonomy, true ),
804
					'hierarchical' => (boolean) pods_v( 'rewrite_hierarchical', $taxonomy, (boolean) pods_v( 'hierarchical', $taxonomy, false ) ),
805
				);
806
807
				if ( false !== $ct_rewrite ) {
808
					$ct_rewrite = $ct_rewrite_array;
809
				}
810
811
				/**
812
				 * Default tax capabilities
813
				 *
814
				 * @see https://codex.wordpress.org/Function_Reference/register_taxonomy
815
				 */
816
				$capability_type  = pods_v( 'capability_type', $taxonomy, 'default' );
817
				$tax_capabilities = array();
818
819
				if ( 'custom' === $capability_type ) {
820
					$capability_type = pods_v( 'capability_type_custom', $taxonomy, 'default' );
821
					if ( ! empty( $capability_type ) && 'default' !== $capability_type ) {
822
						$capability_type       .= '_term';
823
						$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...
824
						$tax_capabilities       = array(
825
							// Singular
826
							'edit_term'    => 'edit_' . $capability_type,
827
							'delete_term'  => 'delete_' . $capability_type,
828
							'assign_term'  => 'assign_' . $capability_type,
829
							// Plural
830
							'manage_terms' => 'manage_' . $capability_type_plural,
831
							'edit_terms'   => 'edit_' . $capability_type_plural,
832
							'delete_terms' => 'delete_' . $capability_type_plural,
833
							'assign_terms' => 'assign_' . $capability_type_plural,
834
						);
835
					}
836
				}
837
838
				// Register Taxonomy
839
				$pods_taxonomies[ $taxonomy_name ] = array(
840
					'label'                 => $ct_label,
841
					'labels'                => $ct_labels,
842
					'public'                => (boolean) pods_v( 'public', $taxonomy, true ),
843
					'show_ui'               => (boolean) pods_v( 'show_ui', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ),
844
					'show_in_menu'          => (boolean) pods_v( 'show_in_menu', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ),
845
					'show_in_nav_menus'     => (boolean) pods_v( 'show_in_nav_menus', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ),
846
					'show_tagcloud'         => (boolean) pods_v( 'show_tagcloud', $taxonomy, (boolean) pods_v( 'show_ui', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ) ),
847
					'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 ) ) ) ),
848
					'show_in_quick_edit'    => (boolean) pods_v( 'show_in_quick_edit', $taxonomy, (boolean) pods_v( 'show_ui', $taxonomy, (boolean) pods_v( 'public', $taxonomy, true ) ) ),
849
					'hierarchical'          => (boolean) pods_v( 'hierarchical', $taxonomy, false ),
850
					// '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...
851
					'capabilities'          => $tax_capabilities,
852
					// '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...
853
					'update_count_callback' => pods_v( 'update_count_callback', $taxonomy, null, true ),
854
					'query_var'             => ( false !== (boolean) pods_v( 'query_var', $taxonomy, true ) ? pods_v( 'query_var_string', $taxonomy, $taxonomy_name, true ) : false ),
855
					'rewrite'               => $ct_rewrite,
856
					'show_admin_column'     => (boolean) pods_v( 'show_admin_column', $taxonomy, false ),
857
					'sort'                  => (boolean) pods_v( 'sort', $taxonomy, false ),
858
				);
859
860
				if ( is_array( $ct_rewrite ) && ! $pods_taxonomies[ $taxonomy_name ]['query_var'] ) {
861
					$pods_taxonomies[ $taxonomy_name ]['query_var'] = pods_v( 'query_var_string', $taxonomy, $taxonomy_name, true );
862
				}
863
864
				// Prevent reserved query_var issues
865
				if ( in_array( $pods_taxonomies[ $taxonomy_name ]['query_var'], $reserved_query_vars, true ) ) {
866
					$pods_taxonomies[ $taxonomy_name ]['query_var'] = 'taxonomy_' . $pods_taxonomies[ $taxonomy_name ]['query_var'];
867
				}
868
869
				// REST API
870
				$rest_enabled = (boolean) pods_v( 'rest_enable', $taxonomy, false );
871
872
				if ( $rest_enabled ) {
873
					$rest_base = sanitize_title( pods_v( 'rest_base', $taxonomy, $taxonomy_name ) );
874
875
					$pods_taxonomies[ $taxonomy_name ]['show_in_rest']          = true;
876
					$pods_taxonomies[ $taxonomy_name ]['rest_base']             = $rest_base;
877
					$pods_taxonomies[ $taxonomy_name ]['rest_controller_class'] = 'WP_REST_Terms_Controller';
878
				}
879
880
				// Integration for Single Value Taxonomy UI
881
				if ( function_exists( 'tax_single_value_meta_box' ) ) {
882
					$pods_taxonomies[ $taxonomy_name ]['single_value'] = (boolean) pods_v( 'single_value', $taxonomy, false );
883
					$pods_taxonomies[ $taxonomy_name ]['required']     = (boolean) pods_v( 'single_value_required', $taxonomy, false );
884
				}
885
886
				// Post Types
887
				$ct_post_types = array();
888
				$_post_types   = get_post_types();
889
				$_post_types   = array_merge_recursive( $_post_types, $pods_post_types );
890
				$ignore        = array( 'revision' );
891
892
				foreach ( $_post_types as $post_type => $options ) {
893
					if ( in_array( $post_type, $ignore, true ) ) {
894
						continue;
895
					}
896
897
					if ( false !== (boolean) pods_v( 'built_in_post_types_' . $post_type, $taxonomy, false ) ) {
898
						$ct_post_types[] = $post_type;
899
900
						if ( isset( $supported_taxonomies[ $post_type ] ) && ! in_array( $taxonomy_name, $supported_taxonomies[ $post_type ], true ) ) {
901
							$supported_taxonomies[ $post_type ][] = $taxonomy_name;
902
						}
903
					}
904
				}
905
906
				if ( isset( $supported_post_types[ $taxonomy_name ] ) ) {
907
					$supported_post_types[ $taxonomy_name ] = array_merge( $supported_post_types[ $taxonomy_name ], $ct_post_types );
908
				} else {
909
					$supported_post_types[ $taxonomy_name ] = $ct_post_types;
910
				}
911
			}//end foreach
912
913
			$pods_post_types = apply_filters( 'pods_wp_post_types', $pods_post_types );
914
			$pods_taxonomies = apply_filters( 'pods_wp_taxonomies', $pods_taxonomies );
915
916
			$supported_post_types = apply_filters( 'pods_wp_supported_post_types', $supported_post_types );
917
			$supported_taxonomies = apply_filters( 'pods_wp_supported_taxonomies', $supported_taxonomies );
918
919
			foreach ( $pods_taxonomies as $taxonomy => $options ) {
920
				$ct_post_types = null;
921
922
				if ( isset( $supported_post_types[ $taxonomy ] ) && ! empty( $supported_post_types[ $taxonomy ] ) ) {
923
					$ct_post_types = $supported_post_types[ $taxonomy ];
924
				}
925
926
				$pods_cpt_ct['taxonomies'][ $taxonomy ] = array(
927
					'post_types' => $ct_post_types,
928
					'options'    => $options,
929
				);
930
			}
931
932
			foreach ( $pods_post_types as $post_type => $options ) {
933
				if ( isset( $supported_taxonomies[ $post_type ] ) && ! empty( $supported_taxonomies[ $post_type ] ) ) {
934
					$options['taxonomies'] = $supported_taxonomies[ $post_type ];
935
				}
936
937
				$pods_cpt_ct['post_types'][ $post_type ] = $options;
938
			}
939
940
			$pods_cpt_ct['post_format_post_types'] = $post_format_post_types;
941
942
			pods_transient_set( 'pods_wp_cpt_ct', $pods_cpt_ct );
943
		}//end if
944
945
		foreach ( $pods_cpt_ct['taxonomies'] as $taxonomy => $options ) {
946
			if ( isset( self::$content_types_registered['taxonomies'] ) && in_array( $taxonomy, self::$content_types_registered['taxonomies'], true ) ) {
947
				continue;
948
			}
949
950
			$ct_post_types = $options['post_types'];
951
			$options       = $options['options'];
952
953
			$options = self::object_label_fix( $options, 'taxonomy' );
954
955
			/**
956
			 * Hide tagcloud compatibility
957
			 *
958
			 * @todo check https://core.trac.wordpress.org/ticket/36964
959
			 * @see  wp-admin/edit-tags.php L389
960
			 */
961
			if ( true !== (boolean) pods_v( 'show_tagcloud_in_edit', $options, (boolean) pods_v( 'show_tagcloud', $options, true ) ) ) {
962
				$options['labels']['popular_items'] = null;
963
			}
964
965
			// Max length for taxonomies are 32 characters
966
			$taxonomy = substr( $taxonomy, 0, 32 );
967
968
			// i18n compatibility for plugins that override it
969
			if ( is_array( $options['rewrite'] ) && isset( $options['rewrite']['slug'] ) && ! empty( $options['rewrite']['slug'] ) ) {
970
				$options['rewrite']['slug'] = _x( $options['rewrite']['slug'], 'URL taxonomy slug', 'pods' );
971
			}
972
973
			/**
974
			 * Allow filtering of taxonomy options per taxonomy.
975
			 *
976
			 * @param array  $options       Taxonomy options
977
			 * @param string $taxonomy      Taxonomy name
978
			 * @param array  $ct_post_types Associated Post Types
979
			 */
980
			$options = apply_filters( 'pods_register_taxonomy_' . $taxonomy, $options, $taxonomy, $ct_post_types );
981
982
			/**
983
			 * Allow filtering of taxonomy options.
984
			 *
985
			 * @param array  $options       Taxonomy options
986
			 * @param string $taxonomy      Taxonomy name
987
			 * @param array  $ct_post_types Associated post types
988
			 */
989
			$options = apply_filters( 'pods_register_taxonomy', $options, $taxonomy, $ct_post_types );
990
991
			if ( 1 === (int) pods_v( 'pods_debug_register', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
992
				pods_debug( array( 'register_taxonomy', compact( 'taxonomy', 'ct_post_types', 'options' ) ) );
993
			}
994
995
			register_taxonomy( $taxonomy, $ct_post_types, $options );
996
997
			if ( ! empty( $options['show_in_rest'] ) ) {
998
				new PodsRESTFields( $taxonomy );
999
			}
1000
1001
			if ( ! isset( self::$content_types_registered['taxonomies'] ) ) {
1002
				self::$content_types_registered['taxonomies'] = array();
1003
			}
1004
1005
			self::$content_types_registered['taxonomies'][] = $taxonomy;
1006
		}//end foreach
1007
1008
		foreach ( $pods_cpt_ct['post_types'] as $post_type => $options ) {
1009
			if ( isset( self::$content_types_registered['post_types'] ) && in_array( $post_type, self::$content_types_registered['post_types'], true ) ) {
1010
				continue;
1011
			}
1012
1013
			$options = self::object_label_fix( $options, 'post_type' );
1014
1015
			// Max length for post types are 20 characters
1016
			$post_type = substr( $post_type, 0, 20 );
1017
1018
			// i18n compatibility for plugins that override it
1019
			if ( is_array( $options['rewrite'] ) && isset( $options['rewrite']['slug'] ) && ! empty( $options['rewrite']['slug'] ) ) {
1020
				$options['rewrite']['slug'] = _x( $options['rewrite']['slug'], 'URL slug', 'pods' );
1021
			}
1022
1023
			/**
1024
			 * Allow filtering of post type options per post type.
1025
			 *
1026
			 * @param array  $options   Post type options
1027
			 * @param string $post_type Post type name
1028
			 */
1029
			$options = apply_filters( 'pods_register_post_type_' . $post_type, $options, $post_type );
1030
1031
			/**
1032
			 * Allow filtering of post type options.
1033
			 *
1034
			 * @param array  $options   Post type options
1035
			 * @param string $post_type Post type name
1036
			 */
1037
			$options = apply_filters( 'pods_register_post_type', $options, $post_type );
1038
1039
			if ( 1 === (int) pods_v( 'pods_debug_register', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
1040
				pods_debug( array( 'register_post_type', compact( 'post_type', 'options' ) ) );
1041
			}
1042
1043
			register_post_type( $post_type, $options );
1044
1045
			// Register post format taxonomy for this post type
1046
			if ( isset( $pods_cpt_ct['post_format_post_types'] ) && in_array( $post_type, $pods_cpt_ct['post_format_post_types'], true ) ) {
1047
				register_taxonomy_for_object_type( 'post_format', $post_type );
1048
			}
1049
1050
			if ( ! empty( $options['show_in_rest'] ) ) {
1051
				new PodsRESTFields( $post_type );
1052
			}
1053
1054
			if ( ! isset( self::$content_types_registered['post_types'] ) ) {
1055
				self::$content_types_registered['post_types'] = array();
1056
			}
1057
1058
			self::$content_types_registered['post_types'][] = $post_type;
1059
		}//end foreach
1060
1061
		// Handle existing post types / taxonomies settings (just REST for now)
1062
		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...
1063
1064
		$post_type_names = wp_list_pluck( $post_types, 'name', 'id' );
1065
		$taxonomy_names  = wp_list_pluck( $taxonomies, 'name', 'id' );
1066
1067
		foreach ( $existing_post_types as $post_type_name => $post_type_name_again ) {
1068
			if ( isset( self::$content_types_registered['post_types'] ) && in_array( $post_type_name, self::$content_types_registered['post_types'], true ) ) {
1069
				// Post type already registered / setup by Pods
1070
				continue;
1071
			}
1072
1073
			$pod_id = array_search( $post_type_name, $post_type_names, true );
1074
1075
			if ( ! $pod_id ) {
1076
				// Post type not a pod
1077
				continue;
1078
			}
1079
1080
			$pod = $post_types[ $pod_id ];
1081
1082
			// REST API
1083
			$rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1084
1085
			if ( $rest_enabled ) {
1086
				if ( empty( $wp_post_types[ $post_type_name ]->show_in_rest ) ) {
1087
					$rest_base = sanitize_title( pods_v( 'rest_base', $pod['options'], pods_v( 'rest_base', $wp_post_types[ $post_type_name ] ), true ) );
1088
1089
					$wp_post_types[ $post_type_name ]->show_in_rest          = true;
1090
					$wp_post_types[ $post_type_name ]->rest_base             = $rest_base;
1091
					$wp_post_types[ $post_type_name ]->rest_controller_class = 'WP_REST_Posts_Controller';
1092
				}
1093
1094
				new PodsRESTFields( $post_type_name );
1095
			}
1096
		}//end foreach
1097
1098
		foreach ( $existing_taxonomies as $taxonomy_name => $taxonomy_name_again ) {
1099
			if ( isset( self::$content_types_registered['taxonomies'] ) && in_array( $taxonomy_name, self::$content_types_registered['taxonomies'], true ) ) {
1100
				// Taxonomy already registered / setup by Pods
1101
				continue;
1102
			}
1103
1104
			$pod_id = array_search( $taxonomy_name, $taxonomy_names, true );
1105
1106
			if ( ! $pod_id ) {
1107
				// Taxonomy not a pod
1108
				continue;
1109
			}
1110
1111
			$pod = $taxonomies[ $pod_id ];
1112
1113
			// REST API
1114
			$rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1115
1116
			if ( $rest_enabled ) {
1117
				if ( empty( $wp_taxonomies[ $taxonomy_name ]->show_in_rest ) ) {
1118
					$rest_base = sanitize_title( pods_v( 'rest_base', $pod['options'], pods_v( 'rest_base', $wp_taxonomies[ $taxonomy_name ] ), true ) );
1119
1120
					$wp_taxonomies[ $taxonomy_name ]->show_in_rest          = true;
1121
					$wp_taxonomies[ $taxonomy_name ]->rest_base             = $rest_base;
1122
					$wp_taxonomies[ $taxonomy_name ]->rest_controller_class = 'WP_REST_Terms_Controller';
1123
				}
1124
1125
				new PodsRESTFields( $taxonomy_name );
1126
			}
1127
		}//end foreach
1128
1129
		if ( ! empty( PodsMeta::$user ) ) {
1130
			$pod = current( PodsMeta::$user );
1131
1132
			$rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1133
1134
			if ( $rest_enabled ) {
1135
				new PodsRESTFields( $pod['name'] );
1136
			}
1137
		}
1138
1139
		if ( ! empty( PodsMeta::$media ) ) {
1140
			$pod = current( PodsMeta::$media );
1141
1142
			$rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1143
1144
			if ( $rest_enabled ) {
1145
				new PodsRESTFields( $pod['name'] );
1146
			}
1147
		}
1148
1149
	}
1150
1151
	/**
1152
	 * Check if we need to flush WordPress rewrite rules
1153
	 * This gets run during 'init' action late in the game to give other plugins time to register their rewrite rules
1154
	 */
1155
	public function flush_rewrite_rules() {
1156
1157
		$flush = (int) pods_transient_get( 'pods_flush_rewrites' );
1158
1159
		if ( 1 === $flush ) {
1160
			/**
1161
			 * @var $wp_rewrite WP_Rewrite
1162
			 */
1163
			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...
1164
			$wp_rewrite->flush_rules();
1165
			$wp_rewrite->init();
1166
1167
			pods_transient_set( 'pods_flush_rewrites', 0 );
1168
		}
1169
	}
1170
1171
	/**
1172
	 * Update Post Type messages
1173
	 *
1174
	 * @param array $messages
1175
	 *
1176
	 * @return array
1177
	 * @since 2.0.2
1178
	 */
1179
	public function setup_updated_messages( $messages ) {
1180
1181
		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...
1182
1183
		$post_types          = PodsMeta::$post_types;
1184
		$existing_post_types = get_post_types();
1185
1186
		$pods_cpt_ct = pods_transient_get( 'pods_wp_cpt_ct' );
1187
1188
		if ( empty( $pods_cpt_ct ) || empty( $post_types ) ) {
1189
			return $messages;
1190
		}
1191
1192
		/**
1193
		 * Use get_preview_post_link function added in 4.4, which eventually applies preview_post_link filter
1194
		 * Before 4.4, this filter is defined in wp-admin/includes/meta-boxes.php, $post parameter added in 4.0
1195
		 * there wasn't post parameter back in 3.8
1196
		 * Let's add $post in the filter as it won't hurt anyway.
1197
		 *
1198
		 * @since 2.6.8.1
1199
		 */
1200
		$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 );
1201
1202
		foreach ( $post_types as $post_type ) {
1203
			if ( ! isset( $pods_cpt_ct['post_types'][ $post_type['name'] ] ) ) {
1204
				continue;
1205
			}
1206
1207
			$labels = self::object_label_fix( $pods_cpt_ct['post_types'][ $post_type['name'] ], 'post_type' );
1208
			$labels = $labels['labels'];
1209
1210
			$messages[ $post_type['name'] ] = array(
1211
				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'] ),
1212
				2  => __( 'Custom field updated.', 'pods' ),
1213
				3  => __( 'Custom field deleted.', 'pods' ),
1214
				4  => sprintf( __( '%s updated.', 'pods' ), $labels['singular_name'] ),
1215
				/* translators: %s: date and time of the revision */
1216
				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,
1217
				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'] ),
1218
				7  => sprintf( __( '%s saved.', 'pods' ), $labels['singular_name'] ),
1219
				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'] ),
1220
				9  => sprintf(
1221
					__( '%1$s scheduled for: <strong>%2$s</strong>. <a target="_blank" href="%3$s">Preview %4$s</a>', 'pods' ), $labels['singular_name'],
1222
					// translators: Publish box date format, see http://php.net/date
1223
					date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ), $labels['singular_name']
1224
				),
1225
				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'] ),
1226
			);
1227
1228
			if ( false === (boolean) $pods_cpt_ct['post_types'][ $post_type['name'] ]['public'] ) {
1229
				$messages[ $post_type['name'] ][1] = sprintf( __( '%s updated.', 'pods' ), $labels['singular_name'] );
1230
				$messages[ $post_type['name'] ][6] = sprintf( __( '%s published.', 'pods' ), $labels['singular_name'] );
1231
				$messages[ $post_type['name'] ][8] = sprintf( __( '%s submitted.', 'pods' ), $labels['singular_name'] );
1232
				$messages[ $post_type['name'] ][9] = sprintf(
1233
					__( '%s scheduled for: <strong>%1$s</strong>.', 'pods' ), $labels['singular_name'],
1234
					// translators: Publish box date format, see http://php.net/date
1235
					date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) )
1236
				);
1237
				$messages[ $post_type['name'] ][10] = sprintf( __( '%s draft updated.', 'pods' ), $labels['singular_name'] );
1238
			}
1239
		}//end foreach
1240
1241
		return $messages;
1242
	}
1243
1244
	/**
1245
	 * @param        $args
1246
	 * @param string $type
1247
	 *
1248
	 * @return array
0 ignored issues
show
Documentation introduced by
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...
1249
	 */
1250
	public static function object_label_fix( $args, $type = 'post_type' ) {
1251
1252
		if ( empty( $args ) || ! is_array( $args ) ) {
1253
			$args = array();
1254
		}
1255
1256
		if ( ! isset( $args['labels'] ) || ! is_array( $args['labels'] ) ) {
1257
			$args['labels'] = array();
1258
		}
1259
1260
		$label          = pods_v( 'name', $args['labels'], pods_v( 'label', $args, __( 'Items', 'pods' ), true ), true );
1261
		$singular_label = pods_v( 'singular_name', $args['labels'], pods_v( 'label_singular', $args, __( 'Item', 'pods' ), true ), true );
1262
1263
		$labels = $args['labels'];
1264
1265
		$labels['name']          = $label;
1266
		$labels['singular_name'] = $singular_label;
1267
1268
		if ( 'post_type' === $type ) {
1269
			$labels['menu_name']             = pods_v( 'menu_name', $labels, $label, true );
1270
			$labels['name_admin_bar']        = pods_v( 'name_admin_bar', $labels, $singular_label, true );
1271
			$labels['add_new']               = pods_v( 'add_new', $labels, __( 'Add New', 'pods' ), true );
1272
			$labels['add_new_item']          = pods_v( 'add_new_item', $labels, sprintf( __( 'Add New %s', 'pods' ), $singular_label ), true );
1273
			$labels['new_item']              = pods_v( 'new_item', $labels, sprintf( __( 'New %s', 'pods' ), $singular_label ), true );
1274
			$labels['edit']                  = pods_v( 'edit', $labels, __( 'Edit', 'pods' ), true );
1275
			$labels['edit_item']             = pods_v( 'edit_item', $labels, sprintf( __( 'Edit %s', 'pods' ), $singular_label ), true );
1276
			$labels['view']                  = pods_v( 'view', $labels, sprintf( __( 'View %s', 'pods' ), $singular_label ), true );
1277
			$labels['view_item']             = pods_v( 'view_item', $labels, sprintf( __( 'View %s', 'pods' ), $singular_label ), true );
1278
			$labels['view_items']            = pods_v( 'view_items', $labels, sprintf( __( 'View %s', 'pods' ), $label ), true );
1279
			$labels['all_items']             = pods_v( 'all_items', $labels, sprintf( __( 'All %s', 'pods' ), $label ), true );
1280
			$labels['search_items']          = pods_v( 'search_items', $labels, sprintf( __( 'Search %s', 'pods' ), $label ), true );
1281
			$labels['not_found']             = pods_v( 'not_found', $labels, sprintf( __( 'No %s Found', 'pods' ), $label ), true );
1282
			$labels['not_found_in_trash']    = pods_v( 'not_found_in_trash', $labels, sprintf( __( 'No %s Found in Trash', 'pods' ), $label ), true );
1283
			$labels['parent']                = pods_v( 'parent', $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['featured_image']        = pods_v( 'featured_image', $labels, __( 'Featured Image', 'pods' ), true );
1286
			$labels['set_featured_image']    = pods_v( 'set_featured_image', $labels, __( 'Set featured image', 'pods' ), true );
1287
			$labels['remove_featured_image'] = pods_v( 'remove_featured_image', $labels, __( 'Remove featured image', 'pods' ), true );
1288
			$labels['use_featured_image']    = pods_v( 'use_featured_image', $labels, __( 'Use as featured image', 'pods' ), true );
1289
			$labels['archives']              = pods_v( 'archives', $labels, sprintf( __( '%s Archives', 'pods' ), $singular_label ), true );
1290
			$labels['attributes']            = pods_v( 'attributes', $labels, sprintf( __( '%s Attributes', 'pods' ), $singular_label ), true );
1291
			$labels['insert_into_item']      = pods_v( 'insert_into_item', $labels, sprintf( __( 'Insert into %s', 'pods' ), $singular_label ), true );
1292
			$labels['uploaded_to_this_item'] = pods_v( 'uploaded_to_this_item', $labels, sprintf( __( 'Uploaded to this %s', 'pods' ), $singular_label ), true );
1293
			$labels['filter_items_list']     = pods_v( 'filter_items_list', $labels, sprintf( __( 'Filter %s lists', 'pods' ), $label ), true );
1294
			$labels['items_list_navigation'] = pods_v( 'items_list_navigation', $labels, sprintf( __( '%s navigation', 'pods' ), $label ), true );
1295
			$labels['items_list']            = pods_v( 'items_list', $labels, sprintf( __( '%s list', 'pods' ), $label ), true );
1296
		} elseif ( 'taxonomy' === $type ) {
1297
			$labels['menu_name']                  = pods_v( 'menu_name', $labels, $label, true );
1298
			$labels['search_items']               = pods_v( 'search_items', $labels, sprintf( __( 'Search %s', 'pods' ), $label ), true );
1299
			$labels['popular_items']              = pods_v( 'popular_items', $labels, sprintf( __( 'Popular %s', 'pods' ), $label ), true );
1300
			$labels['all_items']                  = pods_v( 'all_items', $labels, sprintf( __( 'All %s', 'pods' ), $label ), true );
1301
			$labels['parent_item']                = pods_v( 'parent_item', $labels, sprintf( __( 'Parent %s', 'pods' ), $singular_label ), true );
1302
			$labels['parent_item_colon']          = pods_v( 'parent_item_colon', $labels, sprintf( __( 'Parent %s :', 'pods' ), $singular_label ), true );
1303
			$labels['edit_item']                  = pods_v( 'edit_item', $labels, sprintf( __( 'Edit %s', 'pods' ), $singular_label ), true );
1304
			$labels['view_item']                  = pods_v( 'view_item', $labels, sprintf( __( 'View %s', 'pods' ), $singular_label ), true );
1305
			$labels['update_item']                = pods_v( 'update_item', $labels, sprintf( __( 'Update %s', 'pods' ), $singular_label ), true );
1306
			$labels['add_new_item']               = pods_v( 'add_new_item', $labels, sprintf( __( 'Add New %s', 'pods' ), $singular_label ), true );
1307
			$labels['new_item_name']              = pods_v( 'new_item_name', $labels, sprintf( __( 'New %s Name', 'pods' ), $singular_label ), true );
1308
			$labels['separate_items_with_commas'] = pods_v( 'separate_items_with_commas', $labels, sprintf( __( 'Separate %s with commas', 'pods' ), $label ), true );
1309
			$labels['add_or_remove_items']        = pods_v( 'add_or_remove_items', $labels, sprintf( __( 'Add or remove %s', 'pods' ), $label ), true );
1310
			$labels['choose_from_most_used']      = pods_v( 'choose_from_most_used', $labels, sprintf( __( 'Choose from the most used %s', 'pods' ), $label ), true );
1311
			$labels['not_found']                  = pods_v( 'not_found', $labels, sprintf( __( 'No %s found.', 'pods' ), $label ), true );
1312
			$labels['no_terms']                   = pods_v( 'no_terms', $labels, sprintf( __( 'No %s', 'pods' ), $label ), true );
1313
			$labels['items_list_navigation']      = pods_v( 'items_list_navigation', $labels, sprintf( __( '%s navigation', 'pods' ), $label ), true );
1314
			$labels['items_list']                 = pods_v( 'items_list', $labels, sprintf( __( '%s list', 'pods' ), $label ), true );
1315
		}//end if
1316
1317
		$args['labels'] = $labels;
1318
1319
		return $args;
1320
	}
1321
1322
	/**
1323
	 * Activate and Install
1324
	 */
1325
	public function activate_install() {
1326
1327
		register_activation_hook( PODS_DIR . 'init.php', array( $this, 'activate' ) );
1328
		register_deactivation_hook( PODS_DIR . 'init.php', array( $this, 'deactivate' ) );
1329
1330
		add_action( 'wpmu_new_blog', array( $this, 'new_blog' ), 10, 6 );
1331
1332
		if ( empty( self::$version ) || version_compare( self::$version, PODS_VERSION, '<' ) || version_compare( self::$version, PODS_DB_VERSION, '<=' ) || self::$upgrade_needed ) {
1333
			$this->setup();
1334
		} elseif ( self::$version !== PODS_VERSION ) {
1335
			delete_option( 'pods_framework_version' );
1336
			add_option( 'pods_framework_version', PODS_VERSION, '', 'yes' );
1337
1338
			self::$version = PODS_VERSION;
1339
1340
			pods_api()->cache_flush_pods();
1341
		}
1342
1343
	}
1344
1345
	/**
1346
	 *
1347
	 */
1348
	public function activate() {
1349
1350
		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...
1351
1352
		if ( is_multisite() && 1 === (int) pods_v( 'networkwide' ) ) {
1353
			$_blog_ids = $wpdb->get_col( "SELECT `blog_id` FROM `{$wpdb->blogs}`" );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1354
1355
			foreach ( $_blog_ids as $_blog_id ) {
1356
				$this->setup( $_blog_id );
1357
			}
1358
		} else {
1359
			$this->setup();
1360
		}
1361
	}
1362
1363
	/**
1364
	 *
1365
	 */
1366
	public function deactivate() {
1367
1368
		pods_api()->cache_flush_pods();
1369
1370
	}
1371
1372
	/**
1373
	 * @param null $current
1374
	 * @param null $last
1375
	 *
1376
	 * @return bool
1377
	 */
1378
	public function needs_upgrade( $current = null, $last = null ) {
1379
1380
		if ( null === $current ) {
1381
			$current = self::$version;
1382
		}
1383
1384
		if ( null === $last ) {
1385
			$last = self::$version_last;
1386
		}
1387
1388
		$upgrade_needed = false;
1389
1390
		if ( ! empty( $current ) ) {
1391
			foreach ( self::$upgrades as $old_version => $new_version ) {
1392
				/*
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...
1393
				if ( '2.1.0' === $new_version && ( is_developer() ) )
1394
					continue;*/
1395
1396
				if ( version_compare( $last, $old_version, '>=' ) && version_compare( $last, $new_version, '<' ) && version_compare( $current, $new_version, '>=' ) && 1 !== self::$upgraded ) {
1397
					$upgrade_needed = true;
1398
1399
					break;
1400
				}
1401
			}
1402
		}
1403
1404
		return $upgrade_needed;
1405
	}
1406
1407
	/**
1408
	 * @param $_blog_id
1409
	 * @param $user_id
1410
	 * @param $domain
1411
	 * @param $path
1412
	 * @param $site_id
1413
	 * @param $meta
1414
	 */
1415
	public function new_blog( $_blog_id, $user_id, $domain, $path, $site_id, $meta ) {
1416
1417
		if ( is_multisite() && is_plugin_active_for_network( basename( PODS_DIR ) . '/init.php' ) ) {
1418
			$this->setup( $_blog_id );
1419
		}
1420
	}
1421
1422
	/**
1423
	 * @param null $_blog_id
1424
	 */
1425
	public function setup( $_blog_id = null ) {
1426
1427
		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...
1428
1429
		// Switch DB table prefixes
1430
		if ( null !== $_blog_id && $_blog_id !== $wpdb->blogid ) {
1431
			switch_to_blog( pods_absint( $_blog_id ) );
0 ignored issues
show
introduced by
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...
1432
		} else {
1433
			$_blog_id = null;
1434
		}
1435
1436
		// Setup DB tables
1437
		$pods_version      = get_option( 'pods_framework_version' );
1438
		$pods_version_last = get_option( 'pods_framework_version_last' );
1439
1440
		if ( empty( $pods_version ) ) {
1441
			// Install Pods
1442
			pods_upgrade()->install( $_blog_id );
1443
1444
			$old_version = get_option( 'pods_version' );
1445
1446
			if ( ! empty( $old_version ) ) {
1447
				if ( false === strpos( $old_version, '.' ) ) {
1448
					$old_version = pods_version_to_point( $old_version );
1449
				}
1450
1451
				delete_option( 'pods_framework_version_last' );
1452
				add_option( 'pods_framework_version_last', $pods_version, '', 'yes' );
1453
1454
				self::$version_last = $old_version;
1455
			}
1456
		} elseif ( $this->needs_upgrade( $pods_version, $pods_version_last ) ) {
1457
			// Upgrade Wizard needed
1458
			// Do not do anything
1459
			return;
1460
		} elseif ( version_compare( $pods_version, PODS_VERSION, '<=' ) ) {
1461
			// Update Pods and run any required DB updates
1462
			if ( false !== apply_filters( 'pods_update_run', null, PODS_VERSION, $pods_version, $_blog_id ) && ! isset( $_GET['pods_bypass_update'] ) ) {
1463
				do_action( 'pods_update', PODS_VERSION, $pods_version, $_blog_id );
1464
1465
				// Update 2.0 alpha / beta sites
1466
				if ( version_compare( '2.0.0-a-1', $pods_version, '<=' ) && version_compare( $pods_version, '2.0.0-b-15', '<=' ) ) {
1467
					include PODS_DIR . 'sql/update-2.0-beta.php';
1468
				}
1469
1470
				if ( version_compare( $pods_version, PODS_DB_VERSION, '<=' ) ) {
1471
					include PODS_DIR . 'sql/update.php';
1472
				}
1473
1474
				do_action( 'pods_update_post', PODS_VERSION, $pods_version, $_blog_id );
1475
			}
1476
1477
			delete_option( 'pods_framework_version_last' );
1478
			add_option( 'pods_framework_version_last', $pods_version, '', 'yes' );
1479
1480
			self::$version_last = $pods_version;
1481
		}//end if
1482
1483
		delete_option( 'pods_framework_version' );
1484
		add_option( 'pods_framework_version', PODS_VERSION, '', 'yes' );
1485
1486
		delete_option( 'pods_framework_db_version' );
1487
		add_option( 'pods_framework_db_version', PODS_DB_VERSION, '', 'yes' );
1488
1489
		self::$version    = PODS_VERSION;
1490
		self::$db_version = PODS_DB_VERSION;
1491
1492
		pods_api()->cache_flush_pods();
1493
1494
		// Restore DB table prefix (if switched)
1495
		if ( null !== $_blog_id ) {
1496
			restore_current_blog();
1497
		}
1498
1499
	}
1500
1501
	/**
1502
	 * @param null $_blog_id
1503
	 */
1504
	public function reset( $_blog_id = null ) {
1505
1506
		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...
1507
1508
		// Switch DB table prefixes
1509
		if ( null !== $_blog_id && $_blog_id !== $wpdb->blogid ) {
1510
			switch_to_blog( pods_absint( $_blog_id ) );
0 ignored issues
show
introduced by
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...
1511
		} else {
1512
			$_blog_id = null;
1513
		}
1514
1515
		$api = pods_api();
1516
1517
		$pods = $api->load_pods(
1518
			array(
1519
				'names_ids'  => true,
1520
				'table_info' => false,
1521
			)
1522
		);
1523
1524
		foreach ( $pods as $pod_id => $pod_label ) {
0 ignored issues
show
Bug introduced by
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...
1525
			$api->delete_pod( array( 'id' => $pod_id ) );
1526
		}
1527
1528
		$templates = $api->load_templates();
1529
1530
		foreach ( $templates as $template ) {
1531
			$api->delete_template( array( 'id' => $template['id'] ) );
1532
		}
1533
1534
		$pages = $api->load_pages();
1535
1536
		foreach ( $pages as $page ) {
1537
			$api->delete_page( array( 'id' => $page['id'] ) );
1538
		}
1539
1540
		$helpers = $api->load_helpers();
1541
1542
		foreach ( $helpers as $helper ) {
1543
			$api->delete_helper( array( 'id' => $helper['id'] ) );
1544
		}
1545
1546
		$tables = $wpdb->get_results( "SHOW TABLES LIKE '{$wpdb->prefix}pods%'", ARRAY_N );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1547
1548
		if ( ! empty( $tables ) ) {
1549
			foreach ( $tables as $table ) {
1550
				$table = $table[0];
1551
1552
				pods_query( "DROP TABLE `{$table}`", false );
1553
			}
1554
		}
1555
1556
		// Remove any orphans
1557
		$wpdb->query(
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1558
			"
1559
                DELETE `p`, `pm`
1560
                FROM `{$wpdb->posts}` AS `p`
1561
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1562
                    ON `pm`.`post_id` = `p`.`ID`
1563
                WHERE
1564
                    `p`.`post_type` LIKE '_pods_%'
1565
            "
1566
		);
1567
1568
		delete_option( 'pods_framework_version' );
1569
		delete_option( 'pods_framework_db_version' );
1570
		delete_option( 'pods_framework_upgrade_2_0' );
1571
		delete_option( 'pods_framework_upgraded_1_x' );
1572
1573
		// @todo Make sure all entries are being cleaned and do something about the pods_framework_upgrade_{version} dynamic entries created by PodsUpgrade
1574
		delete_option( 'pods_framework_upgrade_2_0_0' );
1575
		delete_option( 'pods_framework_upgrade_2_0_sister_ids' );
1576
		delete_option( 'pods_framework_version_last' );
1577
1578
		delete_option( 'pods_component_settings' );
1579
1580
		$api->cache_flush_pods();
1581
1582
		pods_transient_clear( 'pods_flush_rewrites' );
1583
1584
		self::$version = '';
1585
1586
		// Restore DB table prefix (if switched)
1587
		if ( null !== $_blog_id ) {
1588
			restore_current_blog();
1589
		}
1590
	}
1591
1592
	public function run() {
1593
1594
		static $ran;
1595
1596
		if ( ! empty( $ran ) ) {
1597
			return;
1598
		}
1599
1600
		$ran = true;
1601
1602
		$this->load_i18n();
1603
1604
		if ( ! did_action( 'plugins_loaded' ) ) {
1605
			add_action( 'plugins_loaded', array( $this, 'load_components' ), 11 );
1606
		} else {
1607
			$this->load_components();
1608
		}
1609
1610
		if ( ! did_action( 'setup_theme' ) ) {
1611
			add_action( 'setup_theme', array( $this, 'load_meta' ), 14 );
1612
		} else {
1613
			$this->load_meta();
1614
		}
1615
1616
		if ( ! did_action( 'init' ) ) {
1617
			add_action( 'init', array( $this, 'core' ), 11 );
1618
			add_action( 'init', array( $this, 'setup_content_types' ), 11 );
1619
1620
			if ( is_admin() ) {
1621
				add_action( 'init', array( $this, 'admin_init' ), 12 );
1622
			}
1623
		} else {
1624
			$this->core();
1625
			$this->setup_content_types();
1626
1627
			if ( is_admin() ) {
1628
				$this->admin_init();
1629
			}
1630
		}
1631
1632
		add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1633
		add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1634
		add_action( 'login_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1635
1636
		add_filter( 'post_updated_messages', array( $this, 'setup_updated_messages' ), 10, 1 );
1637
		add_action( 'delete_attachment', array( $this, 'delete_attachment' ) );
1638
1639
		// Register widgets
1640
		add_action( 'widgets_init', array( $this, 'register_widgets' ) );
1641
1642
		// Show admin bar links
1643
		add_action( 'admin_bar_menu', array( $this, 'admin_bar_links' ), 81 );
1644
1645
		// Add WP-CLI commands
1646
		if ( defined( 'WP_CLI' ) && WP_CLI ) {
1647
			require_once PODS_DIR . 'classes/cli/Pods_CLI_Command.php';
1648
			require_once PODS_DIR . 'classes/cli/PodsAPI_CLI_Command.php';
1649
		}
1650
1651
	}
1652
1653
	/**
1654
	 * Delete Attachments from relationships
1655
	 *
1656
	 * @param int $_ID
1657
	 */
1658
	public function delete_attachment( $_ID ) {
1659
1660
		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...
1661
1662
		$_ID = (int) $_ID;
1663
1664
		do_action( 'pods_delete_attachment', $_ID );
1665
1666
		$file_types = "'" . implode( "', '", PodsForm::file_field_types() ) . "'";
1667
1668
		if ( ! pods_tableless() ) {
1669
			$sql = "
1670
                DELETE `rel`
1671
                FROM `@wp_podsrel` AS `rel`
1672
                LEFT JOIN `{$wpdb->posts}` AS `p`
1673
                    ON
1674
                        `p`.`post_type` = '_pods_field'
1675
                        AND ( `p`.`ID` = `rel`.`field_id` OR `p`.`ID` = `rel`.`related_field_id` )
1676
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1677
                    ON
1678
                        `pm`.`post_id` = `p`.`ID`
1679
                        AND `pm`.`meta_key` = 'type'
1680
                        AND `pm`.`meta_value` IN ( {$file_types} )
1681
                WHERE
1682
                    `p`.`ID` IS NOT NULL
1683
                    AND `pm`.`meta_id` IS NOT NULL
1684
                    AND `rel`.`item_id` = {$_ID}";
1685
1686
			pods_query( $sql, false );
1687
		}
1688
1689
		// Post Meta
1690
		if ( ! empty( PodsMeta::$post_types ) ) {
1691
			$sql = "
1692
                DELETE `rel`
1693
                FROM `@wp_postmeta` AS `rel`
1694
                LEFT JOIN `{$wpdb->posts}` AS `p`
1695
                    ON
1696
                        `p`.`post_type` = '_pods_field'
1697
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1698
                    ON
1699
                        `pm`.`post_id` = `p`.`ID`
1700
                        AND `pm`.`meta_key` = 'type'
1701
                        AND `pm`.`meta_value` IN ( {$file_types} )
1702
                WHERE
1703
                    `p`.`ID` IS NOT NULL
1704
                    AND `pm`.`meta_id` IS NOT NULL
1705
                    AND `rel`.`meta_key` = `p`.`post_name`
1706
                    AND `rel`.`meta_value` = '{$_ID}'";
1707
1708
			pods_query( $sql, false );
1709
		}
1710
1711
		// User Meta
1712
		if ( ! empty( PodsMeta::$user ) ) {
1713
			$sql = "
1714
                DELETE `rel`
1715
                FROM `@wp_usermeta` AS `rel`
1716
                LEFT JOIN `{$wpdb->posts}` AS `p`
1717
                    ON
1718
                        `p`.`post_type` = '_pods_field'
1719
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1720
                    ON
1721
                        `pm`.`post_id` = `p`.`ID`
1722
                        AND `pm`.`meta_key` = 'type'
1723
                        AND `pm`.`meta_value` IN ( {$file_types} )
1724
                WHERE
1725
                    `p`.`ID` IS NOT NULL
1726
                    AND `pm`.`meta_id` IS NOT NULL
1727
                    AND `rel`.`meta_key` = `p`.`post_name`
1728
                    AND `rel`.`meta_value` = '{$_ID}'";
1729
1730
			pods_query( $sql, false );
1731
		}
1732
1733
		// Comment Meta
1734
		if ( ! empty( PodsMeta::$comment ) ) {
1735
			$sql = "
1736
                DELETE `rel`
1737
                FROM `@wp_commentmeta` AS `rel`
1738
                LEFT JOIN `{$wpdb->posts}` AS `p`
1739
                    ON
1740
                        `p`.`post_type` = '_pods_field'
1741
                LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1742
                    ON
1743
                        `pm`.`post_id` = `p`.`ID`
1744
                        AND `pm`.`meta_key` = 'type'
1745
                        AND `pm`.`meta_value` IN ( {$file_types} )
1746
                WHERE
1747
                    `p`.`ID` IS NOT NULL
1748
                    AND `pm`.`meta_id` IS NOT NULL
1749
                    AND `rel`.`meta_key` = `p`.`post_name`
1750
                    AND `rel`.`meta_value` = '{$_ID}'";
1751
1752
			pods_query( $sql, false );
1753
		}
1754
	}
1755
1756
	/**
1757
	 * Register widgets for Pods
1758
	 */
1759
	public function register_widgets() {
1760
1761
		$widgets = array(
1762
			'PodsWidgetSingle',
1763
			'PodsWidgetList',
1764
			'PodsWidgetField',
1765
			'PodsWidgetForm',
1766
			'PodsWidgetView',
1767
		);
1768
1769
		foreach ( $widgets as $widget ) {
1770
			if ( ! file_exists( PODS_DIR . 'classes/widgets/' . $widget . '.php' ) ) {
1771
				continue;
1772
			}
1773
1774
			require_once PODS_DIR . 'classes/widgets/' . $widget . '.php';
1775
1776
			register_widget( $widget );
1777
		}
1778
	}
1779
1780
	/**
1781
	 * Add Admin Bar links
1782
	 */
1783
	public function admin_bar_links() {
1784
1785
		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...
1786
1787
		if ( ! is_user_logged_in() || ! is_admin_bar_showing() ) {
1788
			return;
1789
		}
1790
1791
		$all_pods = pods_api()->load_pods(
1792
			array(
1793
				'type'       => 'pod',
1794
				'fields'     => false,
1795
				'table_info' => false,
1796
			)
1797
		);
1798
1799
		// Add New item links for all pods
1800
		foreach ( $all_pods as $pod ) {
0 ignored issues
show
Bug introduced by
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...
1801
			if ( 0 === (int) $pod['options']['show_in_menu'] ) {
1802
				continue;
1803
			}
1804
1805
			if ( ! pods_is_admin( array( 'pods', 'pods_content', 'pods_add_' . $pod['name'] ) ) ) {
1806
				continue;
1807
			}
1808
1809
			$singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
1810
1811
			$wp_admin_bar->add_node(
1812
				array(
1813
					'id'     => 'new-pod-' . $pod['name'],
1814
					'title'  => $singular_label,
1815
					'parent' => 'new-content',
1816
					'href'   => admin_url( 'admin.php?page=pods-manage-' . $pod['name'] . '&action=add' ),
1817
				)
1818
			);
1819
		}
1820
1821
		// Add edit link if we're on a pods page
1822
		if ( is_object( $pods ) && ! is_wp_error( $pods ) && ! empty( $pods->id ) && isset( $pods->pod_data ) && ! empty( $pods->pod_data ) && 'pod' === $pods->pod_data['type'] ) {
1823
			$pod = $pods->pod_data;
1824
1825
			if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod['name'] ) ) ) {
1826
				$singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
1827
1828
				$wp_admin_bar->add_node(
1829
					array(
1830
						'title' => sprintf( __( 'Edit %s', 'pods' ), $singular_label ),
1831
						'id'    => 'edit-pod',
1832
						'href'  => admin_url( 'admin.php?page=pods-manage-' . $pod['name'] . '&action=edit&id=' . $pods->id() ),
1833
					)
1834
				);
1835
			}
1836
		}
1837
1838
	}
1839
}
1840