Completed
Pull Request — 2.x (#4108)
by Scott Kingsley
05:31
created

PodsField_Pick::simple_value()   F

Complexity

Conditions 24
Paths 481

Size

Total Lines 84
Code Lines 49

Duplication

Lines 5
Ratio 5.95 %

Importance

Changes 0
Metric Value
cc 24
eloc 49
nc 481
nop 6
dl 5
loc 84
rs 3.2552
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @package Pods\Fields
5
 */
6
class PodsField_Pick extends PodsField {
7
8
	/**
9
	 * {@inheritdoc}
10
	 */
11
	public static $group = 'Relationships / Media';
12
13
	/**
14
	 * {@inheritdoc}
15
	 */
16
	public static $type = 'pick';
17
18
	/**
19
	 * {@inheritdoc}
20
	 */
21
	public static $label = 'Relationship';
22
23
	/**
24
	 * Available Related Objects.
25
	 *
26
	 * @var array
27
	 * @since 2.3
28
	 */
29
	public static $related_objects = array();
30
31
	/**
32
	 * Custom Related Objects
33
	 *
34
	 * @var array
35
	 * @since 2.3
36
	 */
37
	public static $custom_related_objects = array();
38
39
	/**
40
	 * Data used during validate / save to avoid extra queries.
41
	 *
42
	 * @var array
43
	 * @since 2.3
44
	 */
45
	public static $related_data = array();
46
47
	/**
48
	 * Data used during input method (mainly for autocomplete).
49
	 *
50
	 * @var array
51
	 * @since 2.3
52
	 */
53
	public static $field_data = array();
54
55
	/**
56
	 * API caching for fields that need it during validate/save.
57
	 *
58
	 * @var \PodsAPI
59
	 * @since 2.3
60
	 */
61
	protected static $api = false;
62
63
	/**
64
	 * Saved array of simple relationship names.
65
	 *
66
	 * @var array
67
	 * @since 2.5
68
	 */
69
	private static $names_simple = null;
70
71
	/**
72
	 * Saved array of relationship names
73
	 *
74
	 * @var array
75
	 * @since 2.5
76
	 */
77
	private static $names_related = null;
78
79
	/**
80
	 * Saved array of bidirectional relationship names
81
	 *
82
	 * @var array
83
	 * @since 2.5
84
	 */
85
	private static $names_bidirectional = null;
86
87
	/**
88
	 * {@inheritdoc}
89
	 */
90
	public function __construct() {
91
92
		self::$label = __( 'Relationship', 'pods' );
93
	}
94
95
	/**
96
	 * Add admin_init actions.
97
	 *
98
	 * @since 2.3
99
	 */
100
	public function admin_init() {
101
102
		// AJAX for Relationship lookups.
103
		add_action( 'wp_ajax_pods_relationship', array( $this, 'admin_ajax_relationship' ) );
104
		add_action( 'wp_ajax_nopriv_pods_relationship', array( $this, 'admin_ajax_relationship' ) );
105
106
		// Handle modal input.
107
		add_action( 'edit_form_top', array( $this, 'admin_modal_input' ) );
108
		add_action( 'show_user_profile', array( $this, 'admin_modal_input' ) );
109
		add_action( 'edit_user_profile', array( $this, 'admin_modal_input' ) );
110
		add_action( 'edit_category_form', array( $this, 'admin_modal_input' ) );
111
		add_action( 'edit_link_category_form', array( $this, 'admin_modal_input' ) );
112
		add_action( 'edit_tag_form', array( $this, 'admin_modal_input' ) );
113
		add_action( 'add_tag_form', array( $this, 'admin_modal_input' ) );
114
		add_action( 'pods_meta_box_pre', array( $this, 'admin_modal_input' ) );
115
116
		// Handle modal saving.
117
		add_filter( 'redirect_post_location', array( $this, 'admin_modal_bail_post_redirect' ), 10, 2 );
118
		add_action( 'load-edit-tags.php', array( $this, 'admin_modal_bail_term_action' ) );
119
		add_action( 'load-categories.php', array( $this, 'admin_modal_bail_term_action' ) );
120
		add_action( 'load-edit-link-categories.php', array( $this, 'admin_modal_bail_term_action' ) );
121
		add_action( 'personal_options_update', array( $this, 'admin_modal_bail_user_action' ) );
122
		add_action( 'edit_user_profile_update', array( $this, 'admin_modal_bail_user_action' ) );
123
		add_action( 'pods_api_process_form', array( $this, 'admin_modal_bail_pod' ), 10, 3 );
124
125
	}
126
127
	/**
128
	 * {@inheritdoc}
129
	 */
130
	public function options() {
131
132
		$options = array(
133
			self::$type . '_format_type'    => array(
134
				'label'      => __( 'Selection Type', 'pods' ),
135
				'help'       => __( 'help', 'pods' ),
136
				'default'    => 'single',
137
				'type'       => 'pick',
138
				'data'       => array(
139
					'single' => __( 'Single Select', 'pods' ),
140
					'multi'  => __( 'Multiple Select', 'pods' ),
141
				),
142
				'dependency' => true,
143
			),
144
			self::$type . '_format_single'  => array(
145
				'label'      => __( 'Format', 'pods' ),
146
				'help'       => __( 'help', 'pods' ),
147
				'depends-on' => array( self::$type . '_format_type' => 'single' ),
148
				'default'    => 'dropdown',
149
				'type'       => 'pick',
150
				'data'       => apply_filters( 'pods_form_ui_field_pick_format_single_options', array(
151
						'dropdown'     => __( 'Drop Down', 'pods' ),
152
						'radio'        => __( 'Radio Buttons', 'pods' ),
153
						'autocomplete' => __( 'Autocomplete', 'pods' ),
154
						'list'         => __( 'List view', 'pods' ),
155
					)
156
				),
157
				'dependency' => true,
158
			),
159
			self::$type . '_format_multi'   => array(
160
				'label'      => __( 'Format', 'pods' ),
161
				'help'       => __( 'help', 'pods' ),
162
				'depends-on' => array( self::$type . '_format_type' => 'multi' ),
163
				'default'    => 'checkbox',
164
				'type'       => 'pick',
165
				'data'       => apply_filters( 'pods_form_ui_field_pick_format_multi_options', array(
166
						'checkbox'     => __( 'Checkboxes', 'pods' ),
167
						'multiselect'  => __( 'Multi Select', 'pods' ),
168
						'autocomplete' => __( 'Autocomplete', 'pods' ),
169
						'list'         => __( 'List view', 'pods' ),
170
					)
171
				),
172
				'dependency' => true,
173
			),
174
			self::$type . '_allow_add_new' => array(
175
				'label'       => __( 'Allow Add New', 'pods' ),
176
				'help'        => __( 'Allow new related records to be created in a modal window', 'pods' ),
177
				'wildcard-on' => array(
178
					self::$type . '_object' => array( '^post-type-(?!(custom-css|customize-changeset)).*$', '^taxonomy-.*$', '^user$', '^pod-.*$' )
179
				),
180
				'type'        => 'boolean',
181
				'default'     => 1
182
			),
183
			self::$type . '_taggable'       => array(
184
				'label'       => __( 'Taggable', 'pods' ),
185
				'help'        => __( 'Allow new values to be inserted when using an Autocomplete field', 'pods' ),
186
				'excludes-on' => array(
187
					self::$type . '_format_single' => array( 'dropdown', 'radio', 'list' ),
188
					self::$type . '_format_multi'  => array( 'checkbox', 'multiselect', 'list' ),
189
					self::$type . '_object'        => array_merge( array( 'site', 'network' ), self::simple_objects() ),
190
				),
191
				'type'        => 'boolean',
192
				'default'     => 0,
193
			),
194
			self::$type . '_show_icon'      => array(
195
				'label'       => __( 'Show Icons', 'pods' ),
196
				'excludes-on' => array(
197
					self::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ),
198
					self::$type . '_format_multi'  => array( 'checkbox', 'multiselect', 'autocomplete' ),
199
					self::$type . '_object'        => array_merge( array( 'site', 'network' ), self::simple_objects() ),
200
				),
201
				'type'        => 'boolean',
202
				'default'     => 1,
203
			),
204
			self::$type . '_show_edit_link' => array(
205
				'label'       => __( 'Show Edit Links', 'pods' ),
206
				'excludes-on' => array(
207
					self::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ),
208
					self::$type . '_format_multi'  => array( 'checkbox', 'multiselect', 'autocomplete' ),
209
					self::$type . '_object'        => array_merge( array( 'site', 'network' ), self::simple_objects() ),
210
				),
211
				'type'        => 'boolean',
212
				'default'     => 1,
213
			),
214
			self::$type . '_show_view_link' => array(
215
				'label'       => __( 'Show View Links', 'pods' ),
216
				'excludes-on' => array(
217
					self::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ),
218
					self::$type . '_format_multi'  => array( 'checkbox', 'multiselect', 'autocomplete' ),
219
					self::$type . '_object'        => array_merge( array( 'site', 'network' ), self::simple_objects() ),
220
				),
221
				'type'        => 'boolean',
222
				'default'     => 1,
223
			),
224
			self::$type . '_select_text'    => array(
225
				'label'      => __( 'Default Select Text', 'pods' ),
226
				'help'       => __( 'This is the text use for the default "no selection" dropdown item, if empty, it will default to "-- Select One --"', 'pods' ),
227
				'depends-on' => array(
228
					self::$type . '_format_type'   => 'single',
229
					self::$type . '_format_single' => 'dropdown',
230
				),
231
				'default'    => '',
232
				'type'       => 'text',
233
			),
234
			self::$type . '_limit'          => array(
235
				'label'      => __( 'Selection Limit', 'pods' ),
236
				'help'       => __( 'help', 'pods' ),
237
				'depends-on' => array( self::$type . '_format_type' => 'multi' ),
238
				'default'    => 0,
239
				'type'       => 'number',
240
			),
241
			self::$type . '_table_id'       => array(
242
				'label'      => __( 'Table ID Column', 'pods' ),
243
				'help'       => __( 'You must provide the ID column name for the table, this will be used to keep track of the relationship', 'pods' ),
244
				'depends-on' => array( self::$type . '_object' => 'table' ),
245
				'required'   => 1,
246
				'default'    => '',
247
				'type'       => 'text',
248
			),
249
			self::$type . '_table_index'    => array(
250
				'label'      => __( 'Table Index Column', 'pods' ),
251
				'help'       => __( 'You must provide the index column name for the table, this may optionally also be the ID column name', 'pods' ),
252
				'depends-on' => array( self::$type . '_object' => 'table' ),
253
				'required'   => 1,
254
				'default'    => '',
255
				'type'       => 'text',
256
			),
257
			self::$type . '_display'        => array(
258
				'label'       => __( 'Display Field in Selection List', 'pods' ),
259
				'help'        => __( 'Provide the name of a field on the related object to reference, example: {@post_title}', 'pods' ),
260
				'excludes-on' => array(
261
					self::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ),
262
				),
263
				'default'     => '',
264
				'type'        => 'text',
265
			),
266
			self::$type . '_user_role'      => array(
267
				'label'            => __( 'Limit list to Role(s)', 'pods' ),
268
				'help'             => __( 'help', 'pods' ),
269
				'depends-on'       => array( self::$type . '_object' => 'user' ),
270
				'default'          => '',
271
				'type'             => 'pick',
272
				'pick_object'      => 'role',
273
				'pick_format_type' => 'multi',
274
			),
275
			/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
276
            self::$type . '_user_site' => array(
277
                'label' => __( 'Limit list to Site(s)', 'pods' ),
278
                'help' => __( 'help', 'pods' ),
279
                'depends-on' => array( self::$type . '_object' => 'user' ),
280
                'default' => '',
281
                'type' => 'pick',
282
                'pick_object' => 'site',
283
                'pick_format_type' => 'multi',
284
            ),
285
			*/
286
			self::$type . '_where'          => array(
287
				'label'       => __( 'Customized <em>WHERE</em>', 'pods' ),
288
				'help'        => __( 'help', 'pods' ),
289
				'excludes-on' => array(
290
					self::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ),
291
				),
292
				'default'     => '',
293
				'type'        => 'text',
294
			),
295
			self::$type . '_orderby'        => array(
296
				'label'       => __( 'Customized <em>ORDER BY</em>', 'pods' ),
297
				'help'        => __( 'help', 'pods' ),
298
				'excludes-on' => array(
299
					self::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ),
300
				),
301
				'default'     => '',
302
				'type'        => 'text',
303
			),
304
			self::$type . '_groupby'        => array(
305
				'label'       => __( 'Customized <em>GROUP BY</em>', 'pods' ),
306
				'help'        => __( 'help', 'pods' ),
307
				'excludes-on' => array(
308
					self::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ),
309
				),
310
				'default'     => '',
311
				'type'        => 'text',
312
			),
313
			/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
314
			self::$type . '_size' => array(
315
				'label' => __( 'Field Size', 'pods' ),
316
				'default' => 'medium',
317
				'type' => 'pick',
318
				'data' => array(
319
					'small' => __( 'Small', 'pods' ),
320
					'medium' => __( 'Medium', 'pods' ),
321
					'large' => __( 'Large', 'pods' )
322
				)
323
			),
324
			*/
325
		);
326
327
		$post_type_pick_objects = array();
328
329
		foreach ( get_post_types( '', 'names' ) as $post_type ) {
330
			$post_type_pick_objects[] = 'post-type_' . $post_type;
331
		}
332
333
		$options[ self::$type . '_post_status' ] = array(
334
			'name'             => 'post_status',
335
			'label'            => __( 'Post Status', 'pods' ),
336
			'help'             => __( 'help', 'pods' ),
337
			'type'             => 'pick',
338
			'pick_object'      => 'post-status',
339
			'pick_format_type' => 'multi',
340
			'default'          => 'publish',
341
			'depends-on'       => array(
342
				self::$type . '_object' => $post_type_pick_objects,
343
			),
344
		);
345
346
		/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
347
		if ( ! is_multisite() ) {
348
			unset( $options[ self::$type . '_user_site' ] );
349
		}
350
		*/
351
352
		return $options;
353
354
	}
355
356
	/**
357
	 * Register a related object
358
	 *
359
	 * @param string $name    Object name
360
	 * @param string $label   Object label
361
	 * @param array  $options Object options
362
	 *
363
	 * @return array|boolean Object array or false if unsuccessful
364
	 * @since 2.3
365
	 */
366
	public function register_related_object( $name, $label, $options = null ) {
367
368
		if ( empty( $name ) || empty( $label ) ) {
369
			return false;
370
		}
371
372
		$related_object = array(
373
			'label'         => $label,
374
			'group'         => 'Custom Relationships',
375
			'simple'        => true,
376
			'bidirectional' => false,
377
			'data'          => array(),
378
			'data_callback' => null,
379
		);
380
381
		$related_object = array_merge( $related_object, $options );
382
383
		self::$custom_related_objects[ $name ] = $related_object;
384
385
		return true;
386
387
	}
388
389
	/**
390
	 * Setup related objects
391
	 *
392
	 * @param boolean $force Whether to force refresh of related objects
393
	 *
394
	 * @return bool True when data has been loaded
395
	 * @since 2.3
396
	 */
397
	public function setup_related_objects( $force = false ) {
398
399
		$new_data_loaded = false;
400
401
		if ( ! $force && empty( self::$related_objects ) ) {
402
			// Only load transient if we aren't forcing a refresh.
403
			self::$related_objects = pods_transient_get( 'pods_related_objects' );
404
405
			if ( false !== self::$related_objects ) {
406
				$new_data_loaded = true;
407
			}
408
		} elseif ( $force ) {
409
			// If we are rebuilding, make sure we start with a clean slate.
410
			self::$related_objects = array();
411
		}
412
413
		if ( empty( self::$related_objects ) ) {
414
			// Do a complete build of related_objects.
415
			$new_data_loaded = true;
416
417
			// Custom simple relationship lists.
418
			self::$related_objects['custom-simple'] = array(
419
				'label'  => __( 'Simple (custom defined list)', 'pods' ),
420
				'group'  => __( 'Custom', 'pods' ),
421
				'simple' => true,
422
			);
423
424
			// Pods options.
425
			$pod_options = array();
426
427
			// Include PodsMeta if not already included.
428
			pods_meta();
429
430
			// Advanced Content Types for relationships.
431
			$_pods = PodsMeta::$advanced_content_types;
432
433 View Code Duplication
			foreach ( $_pods as $pod ) {
434
				$pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')';
435
			}
436
437
			// Settings pods for relationships.
438
			$_pods = PodsMeta::$settings;
439
440 View Code Duplication
			foreach ( $_pods as $pod ) {
441
				$pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')';
442
			}
443
444
			asort( $pod_options );
445
446
			foreach ( $pod_options as $pod => $label ) {
447
				self::$related_objects[ 'pod-' . $pod ] = array(
448
					'label'         => $label,
449
					'group'         => __( 'Pods', 'pods' ),
450
					'bidirectional' => true,
451
				);
452
			}
453
454
			// Post Types for relationships.
455
			$post_types = get_post_types();
456
			asort( $post_types );
457
458
			$ignore = array( 'attachment', 'revision', 'nav_menu_item' );
459
460 View Code Duplication
			foreach ( $post_types as $post_type => $label ) {
461
				if ( in_array( $post_type, $ignore, true ) || empty( $post_type ) ) {
462
					unset( $post_types[ $post_type ] );
463
464
					continue;
465
				} elseif ( 0 === strpos( $post_type, '_pods_' ) && apply_filters( 'pods_pick_ignore_internal', true ) ) {
466
					unset( $post_types[ $post_type ] );
467
468
					continue;
469
				}
470
471
				$post_type = get_post_type_object( $post_type );
472
473
				self::$related_objects[ 'post_type-' . $post_type->name ] = array(
474
					'label'         => $post_type->label . ' (' . $post_type->name . ')',
475
					'group'         => __( 'Post Types', 'pods' ),
476
					'bidirectional' => true,
477
				);
478
			}
479
480
			// Taxonomies for relationships.
481
			$taxonomies = get_taxonomies();
482
			asort( $taxonomies );
483
484
			$ignore = array( 'nav_menu', 'post_format' );
485
486 View Code Duplication
			foreach ( $taxonomies as $taxonomy => $label ) {
487
				/**
488
				 * Prevent ability to extend core Pods content types.
489
				 *
490
				 * @param bool $ignore_internal Default is true, when set to false Pods internal content types can not be extended.
491
				 *
492
				 * @since 2.3.19
493
				 */
494
				$ignore_internal = apply_filters( 'pods_pick_ignore_internal', true );
495
496
				if ( in_array( $taxonomy, $ignore, true ) || empty( $taxonomy ) ) {
497
					unset( $taxonomies[ $taxonomy ] );
498
499
					continue;
500
				} elseif ( 0 === strpos( $taxonomy, '_pods_' ) && $ignore_internal ) {
501
					unset( $taxonomies[ $taxonomy ] );
502
503
					continue;
504
				}
505
506
				$taxonomy = get_taxonomy( $taxonomy );
507
508
				self::$related_objects[ 'taxonomy-' . $taxonomy->name ] = array(
509
					'label'         => $taxonomy->label . ' (' . $taxonomy->name . ')',
510
					'group'         => __( 'Taxonomies', 'pods' ),
511
					'bidirectional' => true,
512
				);
513
			}
514
515
			// Other WP Objects for relationships.
516
			self::$related_objects['user'] = array(
517
				'label'         => __( 'Users', 'pods' ),
518
				'group'         => __( 'Other WP Objects', 'pods' ),
519
				'bidirectional' => true,
520
			);
521
522
			self::$related_objects['role'] = array(
523
				'label'         => __( 'User Roles', 'pods' ),
524
				'group'         => __( 'Other WP Objects', 'pods' ),
525
				'simple'        => true,
526
				'data_callback' => array( $this, 'data_roles' ),
527
			);
528
529
			self::$related_objects['capability'] = array(
530
				'label'         => __( 'User Capabilities', 'pods' ),
531
				'group'         => __( 'Other WP Objects', 'pods' ),
532
				'simple'        => true,
533
				'data_callback' => array( $this, 'data_capabilities' ),
534
			);
535
536
			self::$related_objects['media'] = array(
537
				'label'         => __( 'Media', 'pods' ),
538
				'group'         => __( 'Other WP Objects', 'pods' ),
539
				'bidirectional' => true,
540
			);
541
542
			self::$related_objects['comment'] = array(
543
				'label'         => __( 'Comments', 'pods' ),
544
				'group'         => __( 'Other WP Objects', 'pods' ),
545
				'bidirectional' => true,
546
			);
547
548
			self::$related_objects['image-size'] = array(
549
				'label'         => __( 'Image Sizes', 'pods' ),
550
				'group'         => __( 'Other WP Objects', 'pods' ),
551
				'simple'        => true,
552
				'data_callback' => array( $this, 'data_image_sizes' ),
553
			);
554
555
			self::$related_objects['nav_menu'] = array(
556
				'label' => __( 'Navigation Menus', 'pods' ),
557
				'group' => __( 'Other WP Objects', 'pods' ),
558
			);
559
560
			self::$related_objects['post_format'] = array(
561
				'label' => __( 'Post Formats', 'pods' ),
562
				'group' => __( 'Other WP Objects', 'pods' ),
563
			);
564
565
			self::$related_objects['post-status'] = array(
566
				'label'         => __( 'Post Status', 'pods' ),
567
				'group'         => __( 'Other WP Objects', 'pods' ),
568
				'simple'        => true,
569
				'data_callback' => array( $this, 'data_post_stati' ),
570
			);
571
572
			do_action( 'pods_form_ui_field_pick_related_objects_other' );
573
574
			self::$related_objects['country'] = array(
575
				'label'         => __( 'Countries', 'pods' ),
576
				'group'         => __( 'Predefined Lists', 'pods' ),
577
				'simple'        => true,
578
				'data_callback' => array( $this, 'data_countries' ),
579
			);
580
581
			self::$related_objects['us_state'] = array(
582
				'label'         => __( 'US States', 'pods' ),
583
				'group'         => __( 'Predefined Lists', 'pods' ),
584
				'simple'        => true,
585
				'data_callback' => array( $this, 'data_us_states' ),
586
			);
587
588
			self::$related_objects['days_of_week'] = array(
589
				'label'         => __( 'Calendar - Days of Week', 'pods' ),
590
				'group'         => __( 'Predefined Lists', 'pods' ),
591
				'simple'        => true,
592
				'data_callback' => array( $this, 'data_days_of_week' ),
593
			);
594
595
			self::$related_objects['months_of_year'] = array(
596
				'label'         => __( 'Calendar - Months of Year', 'pods' ),
597
				'group'         => __( 'Predefined Lists', 'pods' ),
598
				'simple'        => true,
599
				'data_callback' => array( $this, 'data_months_of_year' ),
600
			);
601
602
			do_action( 'pods_form_ui_field_pick_related_objects_predefined' );
603
604
			if ( did_action( 'init' ) ) {
605
				pods_transient_set( 'pods_related_objects', self::$related_objects );
606
			}
607
		}
608
609
		/**
610
		 * Allow custom related objects to be defined
611
		 */
612
		do_action( 'pods_form_ui_field_pick_related_objects_custom' );
613
614
		foreach ( self::$custom_related_objects as $object => $related_object ) {
615
			if ( ! isset( self::$related_objects[ $object ] ) ) {
616
				$new_data_loaded = true;
617
618
				self::$related_objects[ $object ] = $related_object;
619
			}
620
		}
621
622
		return $new_data_loaded;
623
624
	}
625
626
	/**
627
	 * Return available related objects
628
	 *
629
	 * @param boolean $force Whether to force refresh of related objects
630
	 *
631
	 * @return array Field selection array
632
	 * @since 2.3
633
	 */
634
	public function related_objects( $force = false ) {
635
636
		if ( $this->setup_related_objects( $force ) || null === self::$names_related ) {
637
			$related_objects = array();
638
639
			foreach ( self::$related_objects as $related_object_name => $related_object ) {
640
				if ( ! isset( $related_objects[ $related_object['group'] ] ) ) {
641
					$related_objects[ $related_object['group'] ] = array();
642
				}
643
644
				$related_objects[ $related_object['group'] ][ $related_object_name ] = $related_object['label'];
645
			}
646
647
			self::$names_related = (array) apply_filters( 'pods_form_ui_field_pick_related_objects', $related_objects );
648
		}
649
650
		return self::$names_related;
651
652
	}
653
654
	/**
655
	 * Return available simple object names
656
	 *
657
	 * @return array Simple object names
658
	 * @since 2.3
659
	 */
660 View Code Duplication
	public function simple_objects() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
661
662
		if ( $this->setup_related_objects() || null === self::$names_simple ) {
663
			$simple_objects = array();
664
665
			foreach ( self::$related_objects as $object => $related_object ) {
666
				if ( ! isset( $related_object['simple'] ) || ! $related_object['simple'] ) {
667
					continue;
668
				}
669
670
				$simple_objects[] = $object;
671
			}
672
673
			self::$names_simple = (array) apply_filters( 'pods_form_ui_field_pick_simple_objects', $simple_objects );
674
		}
675
676
		return self::$names_simple;
677
678
	}
679
680
	/**
681
	 * Return available bidirectional object names
682
	 *
683
	 * @return array Bidirectional object names
684
	 * @since 2.3.4
685
	 */
686 View Code Duplication
	public function bidirectional_objects() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
687
688
		if ( $this->setup_related_objects() || null === self::$names_bidirectional ) {
689
			$bidirectional_objects = array();
690
691
			foreach ( self::$related_objects as $object => $related_object ) {
692
				if ( ! isset( $related_object['bidirectional'] ) || ! $related_object['bidirectional'] ) {
693
					continue;
694
				}
695
696
				$bidirectional_objects[] = $object;
697
			}
698
699
			self::$names_bidirectional = (array) apply_filters( 'pods_form_ui_field_pick_bidirectional_objects', $bidirectional_objects );
700
		}
701
702
		return self::$names_bidirectional;
703
704
	}
705
706
	/**
707
	 * {@inheritdoc}
708
	 */
709
	public function schema( $options = null ) {
710
711
		$schema = false;
712
713
		$simple_tableless_objects = $this->simple_objects();
714
715
		if ( in_array( pods_v( self::$type . '_object', $options ), $simple_tableless_objects, true ) ) {
716
			$schema = 'LONGTEXT';
717
		}
718
719
		return $schema;
720
721
	}
722
723
	/**
724
	 * {@inheritdoc}
725
	 */
726
	public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
727
728
		$fields = null;
729
730
		if ( is_object( $pod ) && isset( $pod->fields ) ) {
731
			/**
732
			 * @var $pod Pods
733
			 */
734
			$fields = $pod->fields;
735
736
			if ( ! empty( $pod->pod_data['object_fields'] ) ) {
737
				$fields = array_merge( $fields, $pod->pod_data['object_fields'] );
738
			}
739 View Code Duplication
		} elseif ( is_array( $pod ) && isset( $pod['fields'] ) ) {
740
			$fields = $pod['fields'];
741
742
			if ( ! empty( $pod['object_fields'] ) ) {
743
				$fields = array_merge( $fields, $pod['object_fields'] );
744
			}
745
		}
746
747
		return pods_serial_comma( $value, array( 'field' => $name, 'fields' => $fields ) );
748
749
	}
750
751
	/**
752
	 * {@inheritdoc}
753
	 */
754
	public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
755
756
		$options = (array) $options;
757
758
		$type = pods_v( 'type', $options, static::$type );
759
760
		$args = compact( array_keys( get_defined_vars() ) );
761
		$args = (object) $args;
762
763
		wp_enqueue_style( 'pods-dfv-list' );
764
		wp_enqueue_script( 'pods-dfv' );
765
766
		wp_enqueue_style( 'pods-select2' );
767
		wp_enqueue_script( 'pods-select2' );
768
769
		$this->render_input_script( $args );
770
771
		return;
772
773
		// @todo Support custom integrations.
774
		do_action( 'pods_form_ui_field_pick_input_' . pods_v( self::$type . '_format_type', $options, 'single' ) . '_' . pods_v( self::$type . '_format_multi', $options, 'checkbox' ), $name, $value, $options, $pod, $id );
0 ignored issues
show
Unused Code introduced by
// @todo Support custom ..., $options, $pod, $id); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
775
		do_action( 'pods_form_ui_field_pick_input', pods_v( self::$type . '_format_type', $options, 'single' ), $name, $value, $options, $pod, $id );
776
777
		// @todo Support custom integrations.
778
		do_action( 'pods_form_ui_field_pick_input', pods_v( self::$type . '_format_type', $options, 'single' ), $name, $value, $options, $pod, $id );
779
780
	}
781
782
	/**
783
	 * {@inheritdoc}
784
	 */
785
	public function build_dfv_field_options( $options, $args ) {
786
787
		$options['grouped'] = 1;
788
789
		if ( empty( $options[ $args->type . '_object' ] ) ) {
790
			$options[ $args->type . '_object' ] = '';
791
		}
792
793
		if ( empty( $options[ $args->type . '_val' ] ) ) {
794
			$options[ $args->type . '_val' ] = '';
795
		}
796
797
		$options['table_info'] = array();
798
799
		$custom = pods_v( $args->type . '_custom', $options, false );
800
801
		$custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $args->name, $args->value, $options, $args->pod, $args->id );
802
803
		$ajax = false;
804
805
		if ( ( 'custom-simple' !== pods_v( $args->type . '_object', $options ) || empty( $custom ) ) && '' !== pods_v( $args->type . '_object', $options, '', true ) ) {
806
			$ajax = true;
807
		}
808
809
		if ( ! empty( self::$field_data ) && self::$field_data['id'] === $options['id'] ) {
810
			$ajax = (boolean) self::$field_data['autocomplete'];
811
		}
812
813
		$ajax = apply_filters( 'pods_form_ui_field_pick_ajax', $ajax, $args->name, $args->value, $options, $args->pod, $args->id );
814
815
		if ( 0 === (int) pods_v( $args->type . '_ajax', $options, 1 ) ) {
816
			$ajax = false;
817
		}
818
819
		$options[ $args->type . '_ajax' ] = (int) $ajax;
820
821
		$format_type = pods_v( $args->type . '_format_type', $options, 'single', true );
822
823
		$limit = 1;
824
825
		if ( 'single' === $format_type ) {
826
			$format_single = pods_v( $args->type . '_format_single', $options, 'dropdown', true );
827
828 View Code Duplication
			if ( 'dropdown' === $format_single ) {
829
				$options['view_name'] = 'select';
830
			} elseif ( 'radio' === $format_single ) {
831
				$options['view_name'] = 'radio';
832
			} elseif ( 'autocomplete' === $format_single ) {
833
				$options['view_name'] = 'select2';
834
			} elseif ( 'list' === $format_single ) {
835
				$options['view_name'] = 'list';
836
			} else {
837
				$options['view_name'] = $format_single;
838
			}
839
		} elseif ( 'multi' === $format_type ) {
840
			$format_multi = pods_v( $args->type . '_format_multi', $options, 'checkbox', true );
841
842
			if ( ! empty( $args->value ) && ! is_array( $args->value ) ) {
843
				$args->value = explode( ',', $args->value );
844
			}
845
846 View Code Duplication
			if ( 'checkbox' === $format_multi ) {
847
				$options['view_name'] = 'checkbox';
848
			} elseif ( 'multiselect' === $format_multi ) {
849
				$options['view_name'] = 'select';
850
			} elseif ( 'autocomplete' === $format_multi ) {
851
				$options['view_name'] = 'select2';
852
			} elseif ( 'list' === $format_multi ) {
853
				$options['view_name'] = 'list';
854
			} else {
855
				$options['view_name'] = $format_multi;
856
			}
857
858
			$limit = 0;
859
860
			if ( ! empty( $options[ $args->type . '_limit' ] ) ) {
861
				$limit = absint( $options[ $args->type . '_limit' ] );
862
			}
863
		} else {
864
			$options['view_name'] = $format_type;
865
		}
866
867
		$options[ $args->type . '_limit' ] = $limit;
868
869
		return $options;
870
871
	}
872
873
	/**
874
	 * {@inheritdoc}
875
	 */
876
	public function build_dfv_field_config( $args ) {
877
878
		$config = parent::build_dfv_field_config( $args );
879
880
		if ( ! isset( $config['optgroup'] ) ) {
881
			$config['optgroup'] = false;
882
		}
883
884
		$file_name  = '';
885
		$query_args = array();
886
887
		// Set the file name and args based on the content type of the relationship
888
		switch ( $args->options['pick_object'] ) {
889 View Code Duplication
			case 'post_type':
890
				if ( ! empty( $args->options['pick_val'] ) ) {
891
					$post_type_obj = get_post_type_object( $args->options['pick_val'] );
892
893
					if ( $post_type_obj && current_user_can( $post_type_obj->cap->create_posts ) ) {
894
						$file_name  = 'post-new.php';
895
						$query_args = array(
896
							'post_type' => $args->options['pick_val'],
897
						);
898
					}
899
				}
900
901
				break;
902
903 View Code Duplication
			case 'taxonomy':
904
				if ( ! empty( $args->options['pick_val'] ) ) {
905
					$taxonomy_obj = get_taxonomy( $args->options['pick_val'] );
906
907
					if ( $taxonomy_obj && current_user_can( $taxonomy_obj->cap->edit_terms ) ) {
908
						$file_name  = 'edit-tags.php';
909
						$query_args = array(
910
							'taxonomy' => $args->options['pick_val'],
911
						);
912
					}
913
				}
914
915
				break;
916
917
			case 'user':
918
				if ( current_user_can( 'create_users' ) ) {
919
					$file_name  = 'user-new.php';
920
				}
921
922
				break;
923
924
			case 'pod':
925
				if ( ! empty( $args->options['pick_val'] ) ) {
926
					if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $args->options['pick_val'] ) ) ) {
927
						$file_name  = 'admin.php';
928
						$query_args = array(
929
							'page'   => 'pods-manage-' . $args->options['pick_val'],
930
							'action' => 'add',
931
						);
932
933
					}
934
				}
935
936
				break;
937
		}
938
939
		$iframe_src = '';
940
941
		if ( ! empty( $file_name ) ) {
942
			// @todo: Replace string literal with defined constant
943
			$query_args['pods_modal'] = 1;
944
945
			// Add args we always need
946
			$iframe_src = add_query_arg( $query_args, admin_url( $file_name ) );
947
		}
948
949
		$config['iframe_src']   = $iframe_src;
950
		$config['iframe_title'] = sprintf( __( '%s: Add New', 'pods' ), $args->options['label'] );
951
952
		return $config;
953
954
	}
955
956
	/**
957
	 * {@inheritdoc}
958
	 */
959
	public function build_dfv_field_item_data( $args ) {
960
961
		$args->options['supports_thumbnails'] = null;
962
963
		$item_data = array();
964
965
		if ( ! empty( $args->options['data'] ) ) {
966
			$item_data = $this->build_dfv_field_item_data_recurse( $args->options['data'], $args );
967
		}
968
969
		return $item_data;
970
971
	}
972
973
	/**
974
	 * Loop through relationship data and expand item data with additional information for DFV.
975
	 *
976
	 * @param array     $data    Item data to expand.
977
	 * @param object    $args    {
978
	 *                           Field information arguments.
979
	 *
980
	 * @type string     $name    Field name
981
	 * @type string     $type    Field type
982
	 * @type array      $options Field options
983
	 * @type mixed      $value   Current value
984
	 * @type array      $pod     Pod information
985
	 * @type int|string $id      Current item ID
986
	 * }
987
	 *
988
	 * @return array
989
	 */
990
	public function build_dfv_field_item_data_recurse( $data, $args ) {
991
992
		$item_data = array();
993
994
		foreach ( $data as $item_id => $item_title ) {
995
			if ( is_array( $item_title ) ) {
996
				$args->options['optgroup'] = true;
997
998
				$item_data[] = array(
999
					'label'      => $item_id,
1000
					'collection' => $this->build_dfv_field_item_data_recurse( $item_title, $args ),
1001
				);
1002
			} else {
1003
				$item_data[] = $this->build_dfv_field_item_data_recurse_item( $item_id, $item_title, $args );
1004
			}
1005
		}
1006
1007
		return $item_data;
1008
1009
	}
1010
1011
	/**
1012
	 * Loop through relationship data and expand item data with additional information for DFV.
1013
	 *
1014
	 * @param int|string $item_id
1015
	 * @param string     $item_title
1016
	 * @param object     $args    {
1017
	 *                            Field information arguments.
1018
	 *
1019
	 * @type string      $name    Field name
1020
	 * @type string      $type    Field type
1021
	 * @type array       $options Field options
1022
	 * @type mixed       $value   Current value
1023
	 * @type array       $pod     Pod information
1024
	 * @type int|string  $id      Current item ID
1025
	 * }
1026
	 *
1027
	 * @return array
1028
	 */
1029
	public function build_dfv_field_item_data_recurse_item( $item_id, $item_title, $args ) {
1030
1031
		$icon      = '';
1032
		$edit_link = '';
1033
		$link      = '';
1034
1035
		if ( ! isset( $args->options['supports_thumbnails'] ) ) {
1036
			$args->options['supports_thumbnails'] = null;
1037
		}
1038
1039
		switch ( $args->options['pick_object'] ) {
1040
			case 'post_type':
1041
				$item_id = (int) $item_id;
1042
1043
				if ( null === $args->options['supports_thumbnails'] && ! empty( $args->options['pick_val'] ) ) {
1044
					$args->options['supports_thumbnails'] = post_type_supports( $args->options['pick_val'], 'thumbnail' );
1045
				}
1046
1047
				if ( true === $args->options['supports_thumbnails'] ) {
1048
					$post_thumbnail_id = get_post_thumbnail_id( $item_id );
1049
1050
					if ( $post_thumbnail_id ) {
1051
						$thumb = wp_get_attachment_image_src( $post_thumbnail_id, 'thumbnail', true );
1052
1053
						if ( ! empty( $thumb[0] ) ) {
1054
							$icon = $thumb[0];
1055
						}
1056
					}
1057
				}
1058
1059
				$edit_link = get_edit_post_link( $item_id, 'raw' );
1060
1061
				$link = get_permalink( $item_id );
1062
1063
				break;
1064
1065
			case 'taxonomy':
1066
				$item_id = (int) $item_id;
1067
1068
				if ( ! empty( $args->options['pick_val'] ) ) {
1069
					$edit_link = get_edit_term_link( $item_id, $args->options['pick_val'] );
1070
1071
					$link = get_term_link( $item_id, $args->options['pick_val'] );
1072
				}
1073
1074
				break;
1075
1076 View Code Duplication
			case 'user':
1077
				$item_id = (int) $item_id;
1078
1079
				$args->options['supports_thumbnails'] = true;
1080
1081
				$icon = get_avatar_url( $item_id, array( 'size' => 150 ) );
1082
1083
				$edit_link = get_edit_user_link( $item_id );
1084
1085
				$link = get_author_posts_url( $item_id );
1086
1087
				break;
1088
1089 View Code Duplication
			case 'comment':
1090
				$item_id = (int) $item_id;
1091
1092
				$args->options['supports_thumbnails'] = true;
1093
1094
				$icon = get_avatar_url( get_comment( $item_id ), array( 'size' => 150 ) );
1095
1096
				$edit_link = get_edit_comment_link( $item_id );
1097
1098
				$link = get_comment_link( $item_id );
1099
1100
				break;
1101
1102
			case 'pod':
1103
				$item_id = (int) $item_id;
1104
1105
				if ( ! empty( $args->options['pick_val'] ) ) {
1106
					if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $args->options['pick_val'] ) ) ) {
1107
						$file_name  = 'admin.php';
1108
						$query_args = array(
1109
							'page'   => 'pods-manage-' . $args->options['pick_val'],
1110
							'action' => 'edit',
1111
							'id'     => $item_id,
1112
						);
1113
1114
						$edit_link = add_query_arg( $query_args, admin_url( $file_name ) );
1115
					}
1116
1117
					// @todo Add $link support
1118
					$link = '';
1119
				}
1120
1121
				break;
1122
		}
1123
1124
		$item = array(
1125
			'id'        => $item_id,
1126
			'icon'      => $icon,
1127
			'name'      => $item_title,
1128
			'edit_link' => $edit_link,
1129
			'link'      => $link,
1130
			'selected'  => ( isset( $args->value[ $item_id ] ) ),
1131
		);
1132
1133
		return $item;
1134
1135
	}
1136
1137
	/**
1138
	 * {@inheritdoc}
1139
	 */
1140
	public function validate( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
1141
1142
		if ( empty( self::$api ) ) {
1143
			self::$api = pods_api();
1144
		}
1145
1146
		$simple_tableless_objects = $this->simple_objects();
1147
1148
		$related_pick_limit = 0;
1149
		$related_field      = $related_pod = $current_related_ids = false;
1150
1151
		// Bidirectional relationship requirement checks
1152
		$related_object = pods_v( self::$type . '_object', $options, '' ); // pod, post_type, taxonomy, etc..
1153
		$related_val    = pods_v( self::$type . '_val', $options, $related_object, null, true ); // pod name, post type name, taxonomy name, etc..
1154
		if ( empty( $related_val ) ) {
1155
			$related_val = $related_object;
1156
		}
1157
1158
		$related_sister_id = (int) pods_v( 'sister_id', $options, 0 );
1159
1160
		$options['id'] = (int) $options['id'];
1161
1162
		if ( ! isset( self::$related_data[ $options['id'] ] ) || empty( self::$related_data[ $options['id'] ] ) ) {
1163
			self::$related_data[ $options['id'] ] = array();
1164
		}
1165
1166
		if ( ! empty( $related_sister_id ) && ! in_array( $related_object, $simple_tableless_objects, true ) ) {
1167
			$related_pod = self::$api->load_pod( array( 'name' => $related_val, 'table_info' => false ), false );
1168
1169
			if ( false !== $related_pod && ( 'pod' === $related_object || $related_object === $related_pod['type'] ) ) {
1170
				$related_field = false;
1171
1172
				// Ensure sister_id exists on related Pod.
1173 View Code Duplication
				foreach ( $related_pod['fields'] as $related_pod_field ) {
1174
					if ( 'pick' === $related_pod_field['type'] && $related_sister_id === $related_pod_field['id'] ) {
1175
						$related_field = $related_pod_field;
1176
1177
						break;
1178
					}
1179
				}
1180
1181
				if ( ! empty( $related_field ) ) {
1182
					$current_ids = self::$api->lookup_related_items( $fields[ $name ]['id'], $pod['id'], $id, $fields[ $name ], $pod );
1183
1184
					self::$related_data[ $options['id'] ]['current_ids'] = $current_ids;
1185
1186
					$value_ids = $value;
1187
1188
					// Convert values from a comma-separated string into an array.
1189
					if ( ! is_array( $value_ids ) ) {
1190
						$value_ids = explode( ',', $value_ids );
1191
					}
1192
1193
					$value_ids = array_unique( array_filter( $value_ids ) );
1194
1195
					// Get ids to remove.
1196
					$remove_ids = array_diff( $current_ids, $value_ids );
1197
1198
					$related_required   = (boolean) pods_v( 'required', $related_field['options'], 0 );
1199
					$related_pick_limit = (int) pods_v( self::$type . '_limit', $related_field['options'], 0 );
1200
1201
					if ( 'single' === pods_v( self::$type . '_format_type', $related_field['options'] ) ) {
1202
						$related_pick_limit = 1;
1203
					}
1204
1205
					// Validate Required fields.
1206
					if ( $related_required && ! empty( $remove_ids ) ) {
1207
						foreach ( $remove_ids as $related_id ) {
1208
							$bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod );
1209
1210
							self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] = $bidirectional_ids;
1211
1212
							if ( empty( $bidirectional_ids ) || ( in_array( (int) $id, $bidirectional_ids, true ) && 1 === count( $bidirectional_ids ) ) ) {
1213
								return sprintf( __( 'The %1$s field is required and cannot be removed by the %2$s field', 'pods' ), $related_field['label'], $options['label'] );
1214
							}
1215
						}
1216
					}
1217
				} else {
1218
					$related_pod = false;
1219
				}
1220
			} else {
1221
				$related_pod = false;
1222
			}
1223
		}
1224
1225
		if ( empty( self::$related_data[ $options['id'] ] ) ) {
1226
			unset( self::$related_data[ $options['id'] ] );
1227
		} else {
1228
			self::$related_data[ $options['id'] ]['related_pod']        = $related_pod;
1229
			self::$related_data[ $options['id'] ]['related_field']      = $related_field;
1230
			self::$related_data[ $options['id'] ]['related_pick_limit'] = $related_pick_limit;
1231
1232
			$pick_limit = (int) pods_v( self::$type . '_limit', $options['options'], 0 );
1233
1234
			if ( 'single' === pods_v( self::$type . '_format_type', $options['options'] ) ) {
1235
				$pick_limit = 1;
1236
			}
1237
1238
			$related_field['id'] = (int) $related_field['id'];
1239
1240
			if ( ! isset( self::$related_data[ $related_field['id'] ] ) || empty( self::$related_data[ $related_field['id'] ] ) ) {
1241
				self::$related_data[ $related_field['id'] ] = array(
1242
					'related_pod'        => $pod,
1243
					'related_field'      => $options,
1244
					'related_pick_limit' => $pick_limit,
1245
				);
1246
			}
1247
		}
1248
1249
		return true;
1250
1251
	}
1252
1253
	/**
1254
	 * {@inheritdoc}
1255
	 */
1256
	public function save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
1257
1258
		if ( empty( self::$api ) ) {
1259
			self::$api = pods_api();
1260
		}
1261
1262
		$options['id'] = (int) $options['id'];
1263
1264
		if ( ! isset( self::$related_data[ $options['id'] ] ) ) {
1265
			return;
1266
		}
1267
1268
		$related_pod        = self::$related_data[ $options['id'] ]['related_pod'];
1269
		$related_field      = self::$related_data[ $options['id'] ]['related_field'];
1270
		$related_pick_limit = self::$related_data[ $options['id'] ]['related_pick_limit'];
1271
1272
		// Bidirectional relationship updates.
1273
		if ( ! empty( $related_field ) ) {
1274
			// Don't use no conflict mode unless this isn't the current pod type.
1275
			$no_conflict = true;
1276
1277
			if ( $related_pod['type'] !== $pod['type'] ) {
1278
				$no_conflict = pods_no_conflict_check( $related_pod['type'] );
1279
			}
1280
1281
			if ( ! $no_conflict ) {
1282
				pods_no_conflict_on( $related_pod['type'] );
1283
			}
1284
1285
			$value = array_filter( $value );
1286
1287
			foreach ( $value as $related_id ) {
1288
				if ( isset( self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] ) && ! empty( self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] ) ) {
1289
					$bidirectional_ids = self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ];
1290
				} else {
1291
					$bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod );
1292
				}
1293
1294
				$bidirectional_ids = array_filter( $bidirectional_ids );
1295
1296
				if ( empty( $bidirectional_ids ) ) {
1297
					$bidirectional_ids = array();
1298
				}
1299
1300
				$remove_ids = array();
1301
1302
				if ( 0 < $related_pick_limit && ! empty( $bidirectional_ids ) && ! in_array( $id, $bidirectional_ids, true ) ) {
1303
					while ( $related_pick_limit <= count( $bidirectional_ids ) ) {
1304
						$remove_ids[] = (int) array_pop( $bidirectional_ids );
1305
					}
1306
				}
1307
1308
				// Remove this item from related items no longer related to.
1309
				$remove_ids = array_unique( array_filter( $remove_ids ) );
1310
1311
				if ( ! in_array( $id, $bidirectional_ids, true ) ) {
1312
					// Add to related items.
1313
					$bidirectional_ids[] = $id;
1314
				} elseif ( empty( $remove_ids ) ) {
1315
					// Nothing to change.
1316
					continue;
1317
				}
1318
1319
				self::$api->save_relationships( $related_id, $bidirectional_ids, $related_pod, $related_field );
1320
1321
				if ( ! empty( $remove_ids ) ) {
1322
					self::$api->delete_relationships( $remove_ids, $related_id, $pod, $options );
1323
				}
1324
			}
1325
1326
			if ( ! $no_conflict ) {
1327
				pods_no_conflict_off( $related_pod['type'] );
1328
			}
1329
		}
1330
1331
	}
1332
1333
	/**
1334
	 * Delete the value from the DB
1335
	 *
1336
	 * @param int    $id
1337
	 * @param string $name
1338
	 * @param array  $options
1339
	 * @param array  $pod
1340
	 *
1341
	 * @since 2.3
1342
	 */
1343
	public function delete( $id = null, $name = null, $options = null, $pod = null ) {
1344
1345
		if ( empty( self::$api ) ) {
1346
			self::$api = pods_api();
1347
		}
1348
1349
		$simple_tableless_objects = $this->simple_objects();
1350
1351
		// Bidirectional relationship requirement checks.
1352
		$related_object    = pods_v( self::$type . '_object', $options, '' ); // pod, post_type, taxonomy, etc..
1353
		$related_val       = pods_v( self::$type . '_val', $options, $related_object, true ); // pod name, post type name, taxonomy name, etc..
1354
		$related_sister_id = (int) pods_v( 'sister_id', $options, 0 );
1355
1356
		if ( ! empty( $related_sister_id ) && ! in_array( $related_object, $simple_tableless_objects, true ) ) {
1357
			$related_pod = self::$api->load_pod( array( 'name' => $related_val, 'table_info' => false ), false );
1358
1359
			if ( false !== $related_pod && ( 'pod' === $related_object || $related_object === $related_pod['type'] ) ) {
1360
				$related_field = false;
1361
1362
				// Ensure sister_id exists on related Pod.
1363 View Code Duplication
				foreach ( $related_pod['fields'] as $related_pod_field ) {
1364
					if ( 'pick' === $related_pod_field['type'] && (int) $related_sister_id === (int) $related_pod_field['id'] ) {
1365
						$related_field = $related_pod_field;
1366
1367
						break;
1368
					}
1369
				}
1370
1371
				if ( ! empty( $related_field ) ) {
1372
					$values = self::$api->lookup_related_items( $options['id'], $pod['id'], $id, $options, $pod );
1373
1374
					if ( ! empty( $values ) ) {
1375
						$no_conflict = pods_no_conflict_check( $related_pod['type'] );
1376
1377
						if ( ! $no_conflict ) {
1378
							pods_no_conflict_on( $related_pod['type'] );
1379
						}
1380
1381
						self::$api->delete_relationships( $values, $id, $related_pod, $related_field );
1382
1383
						if ( ! $no_conflict ) {
1384
							pods_no_conflict_off( $related_pod['type'] );
1385
						}
1386
					}
1387
				}
1388
			}
1389
		}
1390
1391
	}
1392
1393
	/**
1394
	 * {@inheritdoc}
1395
	 */
1396
	public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) {
1397
1398
		$value = $this->simple_value( $name, $value, $options, $pod, $id );
1399
1400
		return $this->display( $value, $name, $options, $pod, $id );
1401
1402
	}
1403
1404
	/**
1405
	 * Get the data from the field
1406
	 *
1407
	 * @param string       $name    The name of the field
1408
	 * @param string|array $value   The value of the field
1409
	 * @param array        $options Field options
1410
	 * @param array        $pod     Pod data
1411
	 * @param int          $id      Item ID
1412
	 * @param boolean      $in_form
1413
	 *
1414
	 * @return array Array of possible field data
1415
	 *
1416
	 * @since 2.0
1417
	 */
1418
	public function data( $name, $value = null, $options = null, $pod = null, $id = null, $in_form = true ) {
1419
1420 View Code Duplication
		if ( isset( $options['options'] ) ) {
1421
			$options = array_merge( $options, $options['options'] );
1422
1423
			unset( $options['options'] );
1424
		}
1425
1426
		$data = pods_v( 'data', $options, null, true );
1427
1428
		$object_params = array(
1429
			'name'    => $name, // The name of the field.
1430
			'value'   => $value, // The value of the field.
1431
			'options' => $options, // Field options.
1432
			'pod'     => $pod, // Pod data.
1433
			'id'      => $id, // Item ID.
1434
			'context' => 'data', // Data context.
1435
		);
1436
1437
		if ( null !== $data ) {
1438
			$data = (array) $data;
1439
		} else {
1440
			$data = $this->get_object_data( $object_params );
1441
		}
1442
1443
		if ( 'single' === pods_v( self::$type . '_format_type', $options, 'single' ) && 'dropdown' === pods_v( self::$type . '_format_single', $options, 'dropdown' ) ) {
1444
			$data = array( '' => pods_v( self::$type . '_select_text', $options, __( '-- Select One --', 'pods' ), true ) ) + $data;
1445
		}
1446
1447
		$data = apply_filters( 'pods_field_pick_data', $data, $name, $value, $options, $pod, $id );
1448
1449
		return $data;
1450
1451
	}
1452
1453
	/**
1454
	 * Convert a simple value to the correct value
1455
	 *
1456
	 * @param string       $name    The name of the field
1457
	 * @param string|array $value   The value of the field
1458
	 * @param array        $options Field options
1459
	 * @param array        $pod     Pod data
1460
	 * @param int          $id      Item ID
1461
	 * @param boolean      $raw     Whether to return the raw list of keys (true) or convert to key=>value (false)
1462
	 *
1463
	 * @return mixed Corrected value
1464
	 */
1465
	public function simple_value( $name, $value = null, $options = null, $pod = null, $id = null, $raw = false ) {
1466
1467
		if ( in_array( pods_v( self::$type . '_object', $options ), self::simple_objects(), true ) ) {
1468 View Code Duplication
			if ( isset( $options['options'] ) ) {
1469
				$options = array_merge( $options, $options['options'] );
1470
1471
				unset( $options['options'] );
1472
			}
1473
1474
			if ( ! is_array( $value ) && 0 < strlen( $value ) ) {
1475
				$simple = @json_decode( $value, true );
1476
1477
				if ( is_array( $simple ) ) {
1478
					$value = $simple;
1479
				}
1480
			}
1481
1482
			$data = pods_v( 'data', $options, null, true );
1483
1484
			$object_params = array(
1485
				'name'    => $name, // The name of the field.
1486
				'value'   => $value, // The value of the field.
1487
				'options' => $options, // Field options.
1488
				'pod'     => $pod, // Pod data.
1489
				'id'      => $id, // Item ID.
1490
				'context' => 'simple_value', // Data context.
1491
			);
1492
1493
			if ( null === $data ) {
1494
				$data = $this->get_object_data( $object_params );
1495
			}
1496
1497
			$data = (array) $data;
1498
1499
			$key = 0;
1500
1501
			if ( is_array( $value ) ) {
1502
				if ( ! empty( $data ) ) {
1503
					$val = array();
1504
1505
					foreach ( $value as $k => $v ) {
1506
						if ( isset( $data[ $v ] ) ) {
1507
							if ( false === $raw ) {
1508
								$k = $v;
1509
								$v = $data[ $v ];
1510
							}
1511
1512
							$val[ $k ] = $v;
1513
						}
1514
					}
1515
1516
					$value = $val;
1517
				}
1518
			} elseif ( isset( $data[ $value ] ) && false === $raw ) {
1519
				$key   = $value;
1520
				$value = $data[ $value ];
1521
			}
1522
1523
			$single_multi = pods_v( self::$type . '_format_type', $options, 'single' );
1524
1525
			if ( 'multi' === $single_multi ) {
1526
				$limit = (int) pods_v( self::$type . '_limit', $options, 0 );
1527
			} else {
1528
				$limit = 1;
1529
			}
1530
1531
			if ( is_array( $value ) && 0 < $limit ) {
1532
				if ( 1 === $limit ) {
1533
					$value = current( $value );
1534
				} else {
1535
					$value = array_slice( $value, 0, $limit, true );
1536
				}
1537
			} elseif ( ! is_array( $value ) && null !== $value && 0 < strlen( $value ) ) {
1538
				if ( 1 !== $limit || ( true === $raw && 'multi' === $single_multi ) ) {
1539
					$value = array(
1540
						$key => $value,
1541
					);
1542
				}
1543
			}
1544
		}
1545
1546
		return $value;
1547
1548
	}
1549
1550
	/**
1551
	 * Get the label from a pick value
1552
	 *
1553
	 * @param string       $name    The name of the field
1554
	 * @param string|array $value   The value of the field
1555
	 * @param array        $options Field options
1556
	 * @param array        $pod     Pod data
1557
	 * @param int          $id      Item ID
1558
	 *
1559
	 * @return string
1560
	 *
1561
	 * @since 2.2
1562
	 */
1563
	public function value_to_label( $name, $value = null, $options = null, $pod = null, $id = null ) {
1564
1565 View Code Duplication
		if ( isset( $options['options'] ) ) {
1566
			$options = array_merge( $options, $options['options'] );
1567
1568
			unset( $options['options'] );
1569
		}
1570
1571
		$data = pods_v( 'data', $options, null, true );
1572
1573
		$object_params = array(
1574
			'name'    => $name, // The name of the field.
1575
			'value'   => $value, // The value of the field.
1576
			'options' => $options, // Field options.
1577
			'pod'     => $pod, // Pod data.
1578
			'id'      => $id, // Item ID.
1579
			'context' => 'value_to_label', // Data context.
1580
		);
1581
1582
		if ( null !== $data ) {
1583
			$data = (array) $data;
1584
		} else {
1585
			$data = $this->get_object_data( $object_params );
1586
		}
1587
1588
		$labels = array();
1589
1590
		$check_value = $value;
1591
1592
		foreach ( $check_value as &$check_v ) {
0 ignored issues
show
Bug introduced by
The expression $check_value of type string|array|null 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...
1593
			$check_v = (string) $check_v;
1594
		}
1595
1596
		foreach ( $data as $v => $l ) {
0 ignored issues
show
Bug introduced by
The expression $data of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

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

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

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

Loading history...
1597
			if ( ! in_array( (string) $l, $labels, true ) && ( (string) $value === (string) $v || ( is_array( $value ) && in_array( (string) $v, $value, true ) ) ) ) {
1598
				$labels[] = (string) $l;
1599
			}
1600
		}
1601
1602
		$labels = apply_filters( 'pods_field_pick_value_to_label', $labels, $name, $value, $options, $pod, $id );
1603
1604
		$labels = pods_serial_comma( $labels );
1605
1606
		return $labels;
1607
1608
	}
1609
1610
	/**
1611
	 * Get available items from a relationship field
1612
	 *
1613
	 * @param array|string $field         Field array or field name
1614
	 * @param array        $options       [optional] Field options array overrides
1615
	 * @param array        $object_params [optional] Additional get_object_data options
1616
	 *
1617
	 * @return array An array of available items from a relationship field
1618
	 */
1619
	public function get_field_data( $field, $options = array(), $object_params = array() ) {
1620
1621
		// Handle field array overrides.
1622
		if ( is_array( $field ) ) {
1623
			$options = array_merge( $field, $options );
1624
		}
1625
1626
		// Get field name from array.
1627
		$field = pods_v( 'name', $options, $field, true );
1628
1629
		// Field name or options not set.
1630
		if ( empty( $field ) || empty( $options ) ) {
1631
			return array();
1632
		}
1633
1634
		// Options normalization.
1635
		$options = array_merge( $options, pods_v( 'options', $options, array(), true ) );
1636
1637
		// Setup object params.
1638
		$object_params = array_merge( array(
1639
			'name'    => $field, // The name of the field.
1640
			'options' => $options, // Field options.
1641
		), $object_params );
1642
1643
		// Get data override.
1644
		$data = pods_v( 'data', $options, null, true );
1645
1646
		if ( null !== $data ) {
1647
			// Return data override.
1648
			$data = (array) $data;
1649
		} else {
1650
			// Get object data.
1651
			$data = $this->get_object_data( $object_params );
1652
		}
1653
1654
		return $data;
1655
1656
	}
1657
1658
	/**
1659
	 * Get data from relationship objects
1660
	 *
1661
	 * @param array $object_params Object data parameters
1662
	 *
1663
	 * @return array|bool Object data
1664
	 */
1665
	public function get_object_data( $object_params = null ) {
1666
1667
		/**
1668
		 * @var $wpdb wpdb
1669
		 */
1670
		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...
1671
1672
		$object_params = array_merge( array(
1673
			// The name of the field.
1674
			'name'        => '',
1675
			// The value of the field.
1676
			'value'       => '',
1677
			// Field options.
1678
			'options'     => array(),
1679
			// Pod data.
1680
			'pod'         => '',
1681
			// Item ID.
1682
			'id'          => '',
1683
			// Data context.
1684
			'context'     => '',
1685
			// Data parameters.
1686
			'data_params' => array(
1687
				'query' => '', // Query being searched.
1688
			),
1689
			// Page number of results to get.
1690
			'page'        => 1,
1691
			// How many data items to limit to (autocomplete defaults to 30, set to -1 or 1+ to override).
1692
			'limit'       => 0,
1693
		), $object_params );
1694
1695
		$name        = $object_params['name'];
1696
		$value       = $object_params['value'];
1697
		$options     = $object_params['options'] = (array) $object_params['options'];
1698
		$pod         = $object_params['pod'];
1699
		$id          = $object_params['id'];
1700
		$context     = $object_params['context'];
1701
		$data_params = $object_params['data_params'] = (array) $object_params['data_params'];
1702
		$page        = min( 1, (int) $object_params['page'] );
1703
		$limit       = (int) $object_params['limit'];
1704
1705 View Code Duplication
		if ( isset( $options['options'] ) ) {
1706
			$options = array_merge( $options, $options['options'] );
1707
1708
			unset( $options['options'] );
1709
		}
1710
1711
		$data  = apply_filters( 'pods_field_pick_object_data', null, $name, $value, $options, $pod, $id, $object_params );
1712
		$items = array();
1713
1714
		if ( ! isset( $options[ self::$type . '_object' ] ) ) {
1715
			$data = pods_v( 'data', $options, array(), true );
1716
		}
1717
1718
		$simple = false;
1719
1720
		if ( null === $data ) {
1721
			$data = array();
1722
1723
			if ( 'custom-simple' === $options[ self::$type . '_object' ] ) {
1724
				$custom = pods_v( self::$type . '_custom', $options, '' );
1725
1726
				$custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $name, $value, $options, $pod, $id, $object_params );
1727
1728
				if ( ! empty( $custom ) ) {
1729
					if ( ! is_array( $custom ) ) {
1730
						$data = array();
1731
1732
						$custom = explode( "\n", trim( $custom ) );
1733
1734
						foreach ( $custom as $custom_value ) {
1735
							$custom_label = explode( '|', $custom_value );
1736
1737
							if ( empty( $custom_label ) ) {
1738
								continue;
1739
							}
1740
1741
							if ( 1 === count( $custom_label ) ) {
1742
								$custom_label = $custom_value;
1743
							} else {
1744
								$custom_value = $custom_label[0];
1745
								$custom_label = $custom_label[1];
1746
							}
1747
1748
							$custom_value = trim( (string) $custom_value );
1749
							$custom_label = trim( (string) $custom_label );
1750
1751
							$data[ $custom_value ] = $custom_label;
1752
						}
1753
					} else {
1754
						$data = $custom;
1755
					}
1756
1757
					$simple = true;
1758
				}
1759
			} elseif ( isset( self::$related_objects[ $options[ self::$type . '_object' ] ] ) && isset( self::$related_objects[ $options[ self::$type . '_object' ] ]['data'] ) && ! empty( self::$related_objects[ $options[ self::$type . '_object' ] ]['data'] ) ) {
1760
				$data = self::$related_objects[ $options[ self::$type . '_object' ] ]['data'];
1761
1762
				$simple = true;
1763
			} elseif ( isset( self::$related_objects[ $options[ self::$type . '_object' ] ] ) && isset( self::$related_objects[ $options[ self::$type . '_object' ] ]['data_callback'] ) && is_callable( self::$related_objects[ $options[ self::$type . '_object' ] ]['data_callback'] ) ) {
1764
				$data = call_user_func_array( self::$related_objects[ $options[ self::$type . '_object' ] ]['data_callback'], array(
1765
						$name,
1766
						$value,
1767
						$options,
1768
						$pod,
1769
						$id,
1770
					)
1771
				);
1772
1773 View Code Duplication
				if ( 'data' === $context ) {
1774
					self::$field_data = array(
1775
						'field'        => $name,
1776
						'id'           => $options['id'],
1777
						'autocomplete' => false,
1778
					);
1779
				}
1780
1781
				$simple = true;
1782
1783
				// Cache data from callback.
1784
				if ( ! empty( $data ) ) {
1785
					self::$related_objects[ $options[ self::$type . '_object' ] ]['data'] = $data;
1786
				}
1787
			} elseif ( 'simple_value' !== $context ) {
1788
				$pick_val = pods_v( self::$type . '_val', $options );
1789
1790
				if ( 'table' === pods_v( self::$type . '_object', $options ) ) {
1791
					$pick_val = pods_v( self::$type . '_table', $options, $pick_val, true );
1792
				}
1793
1794 View Code Duplication
				if ( '__current__' === $pick_val ) {
1795
					if ( is_object( $pod ) ) {
1796
						$pick_val = $pod->pod;
1797
					} elseif ( is_array( $pod ) ) {
1798
						$pick_val = $pod['name'];
1799
					} elseif ( 0 < strlen( $pod ) ) {
1800
						$pick_val = $pod;
1801
					}
1802
				}
1803
1804
				$options['table_info'] = pods_api()->get_table_info( pods_v( self::$type . '_object', $options ), $pick_val, null, null, $options );
1805
1806
				$search_data = pods_data();
1807
				$search_data->table( $options['table_info'] );
1808
1809
				if ( isset( $options['table_info']['pod'] ) && ! empty( $options['table_info']['pod'] ) && isset( $options['table_info']['pod']['name'] ) ) {
1810
					$search_data->pod    = $options['table_info']['pod']['name'];
1811
					$search_data->fields = $options['table_info']['pod']['fields'];
1812
				}
1813
1814
				$params = array(
1815
					'select'     => "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`",
1816
					'table'      => $search_data->table,
1817
					'where'      => pods_v( self::$type . '_where', $options, (array) $options['table_info']['where_default'], true ),
1818
					'orderby'    => pods_v( self::$type . '_orderby', $options, null, true ),
1819
					'groupby'    => pods_v( self::$type . '_groupby', $options, null, true ),
1820
					// 'having' => pods_v( self::$type . '_having', $options, null, 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...
1821
					'pagination' => false,
1822
					'search'     => false
1823
				);
1824
1825
				if ( in_array( $options[ self::$type . '_object' ], array( 'site', 'network' ), true ) ) {
1826
					$params['select'] .= ', `t`.`path`';
1827
				}
1828
1829
				if ( ! empty( $params['where'] ) && (array) $options['table_info']['where_default'] !== $params['where'] ) {
1830
					$params['where'] = pods_evaluate_tags( $params['where'], true );
1831
				}
1832
1833
				if ( empty( $params['where'] ) || ( ! is_array( $params['where'] ) && strlen( trim( $params['where'] ) ) < 1 ) ) {
1834
					$params['where'] = array();
1835
				} elseif ( ! is_array( $params['where'] ) ) {
1836
					$params['where'] = (array) $params['where'];
1837
				}
1838
1839
				if ( 'value_to_label' === $context ) {
1840
					$params['where'][] = "`t`.`{$search_data->field_id}` = " . number_format( $value, 0, '', '' );
1841
				}
1842
1843
				/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
1844
				if ( ! empty( $params['orderby'] ) ) {
1845
					$params['orderby'] = pods_evaluate_tags( $params['orderby'], true );
1846
				}
1847
1848
				if ( ! empty( $params['groupby'] ) ) {
1849
					$params['groupby'] = pods_evaluate_tags( $params['groupby'], true );
1850
				}
1851
				*/
1852
1853
				$display = trim( pods_v( self::$type . '_display', $options ), ' {@}' );
1854
1855
				if ( 0 < strlen( $display ) ) {
1856
					if ( isset( $options['table_info']['pod'] ) && ! empty( $options['table_info']['pod'] ) ) {
1857
						if ( isset( $options['table_info']['pod']['object_fields'] ) && isset( $options['table_info']['pod']['object_fields'][ $display ] ) ) {
1858
							$search_data->field_index = $display;
1859
1860
							$params['select'] = "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`";
1861
						} elseif ( isset( $options['table_info']['pod']['fields'][ $display ] ) ) {
1862
							$search_data->field_index = $display;
1863
1864
							if ( 'table' === $options['table_info']['pod']['storage'] && ! in_array( $options['table_info']['pod']['type'], array(
1865
									'pod',
1866
									'table',
1867
								), true )
1868
							) {
1869
								$params['select'] = "`t`.`{$search_data->field_id}`, `d`.`{$search_data->field_index}`";
1870
							} elseif ( 'meta' === $options['table_info']['pod']['storage'] ) {
1871
								$params['select'] = "`t`.`{$search_data->field_id}`, `{$search_data->field_index}`.`meta_value` AS {$search_data->field_index}";
1872
							} else {
1873
								$params['select'] = "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`";
1874
							}
1875
						}
1876
					} elseif ( isset( $options['table_info']['object_fields'] ) && isset( $options['table_info']['object_fields'][ $display ] ) ) {
1877
						$search_data->field_index = $display;
1878
1879
						$params['select'] = "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`";
1880
					}
1881
				}
1882
1883
				$autocomplete = false;
1884
1885
				if ( 'single' === pods_v( self::$type . '_format_type', $options, 'single' ) && 'autocomplete' === pods_v( self::$type . '_format_single', $options, 'dropdown' ) ) {
1886
					$autocomplete = true;
1887
				} elseif ( 'multi' === pods_v( self::$type . '_format_type', $options, 'single' ) && 'autocomplete' === pods_v( self::$type . '_format_multi', $options, 'checkbox' ) ) {
1888
					$autocomplete = true;
1889
				}
1890
1891
				$hierarchy = false;
1892
1893
				if ( 'data' === $context && ! $autocomplete ) {
1894
					if ( 'single' === pods_v( self::$type . '_format_type', $options, 'single' ) && in_array( pods_v( self::$type . '_format_single', $options, 'dropdown' ), array(
1895
							'dropdown',
1896
							'radio',
1897
						), true )
1898
					) {
1899
						$hierarchy = true;
1900
					} elseif ( 'multi' === pods_v( self::$type . '_format_type', $options, 'single' ) && in_array( pods_v( self::$type . '_format_multi', $options, 'checkbox' ), array(
1901
							'multiselect',
1902
							'checkbox',
1903
						), true )
1904
					) {
1905
						$hierarchy = true;
1906
					}
1907
				}
1908
1909
				if ( $hierarchy && $options['table_info']['object_hierarchical'] && ! empty( $options['table_info']['field_parent'] ) ) {
1910
					$params['select'] .= ', ' . $options['table_info']['field_parent_select'];
1911
				}
1912
1913
				if ( $autocomplete ) {
1914
					if ( 0 === $limit ) {
1915
						$limit = 30;
1916
					}
1917
1918
					$params['limit'] = apply_filters( 'pods_form_ui_field_pick_autocomplete_limit', $limit, $name, $value, $options, $pod, $id, $object_params );
1919
1920
					if ( is_array( $value ) && $params['limit'] < count( $value ) ) {
1921
						$params['limit'] = count( $value );
1922
					}
1923
1924
					$params['page'] = $page;
1925
1926
					if ( 'admin_ajax_relationship' === $context ) {
1927
						$lookup_where = array(
1928
							$search_data->field_index => "`t`.`{$search_data->field_index}` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'",
1929
						);
1930
1931
						// @todo Hook into WPML for each table
1932
						if ( $wpdb->users === $search_data->table ) {
1933
							$lookup_where['display_name'] = "`t`.`display_name` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1934
							$lookup_where['user_login']   = "`t`.`user_login` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1935
							$lookup_where['user_email']   = "`t`.`user_email` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1936
						} elseif ( $wpdb->posts === $search_data->table ) {
1937
							$lookup_where['post_title']   = "`t`.`post_title` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1938
							$lookup_where['post_name']    = "`t`.`post_name` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1939
							$lookup_where['post_content'] = "`t`.`post_content` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1940
							$lookup_where['post_excerpt'] = "`t`.`post_excerpt` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1941
						} elseif ( $wpdb->terms === $search_data->table ) {
1942
							$lookup_where['name'] = "`t`.`name` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1943
							$lookup_where['slug'] = "`t`.`slug` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1944
						} elseif ( $wpdb->comments === $search_data->table ) {
1945
							$lookup_where['comment_content']      = "`t`.`comment_content` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1946
							$lookup_where['comment_author']       = "`t`.`comment_author` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1947
							$lookup_where['comment_author_email'] = "`t`.`comment_author_email` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1948
						}
1949
1950
						$lookup_where = apply_filters( 'pods_form_ui_field_pick_autocomplete_lookup', $lookup_where, $data_params['query'], $name, $value, $options, $pod, $id, $object_params, $search_data );
1951
1952
						if ( ! empty( $lookup_where ) ) {
1953
							$params['where'][] = implode( ' OR ', $lookup_where );
1954
						}
1955
1956
						$orderby   = array();
1957
						$orderby[] = "(`t`.`{$search_data->field_index}` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%' ) DESC";
1958
1959
						$pick_orderby = pods_v( self::$type . '_orderby', $options, null, true );
1960
1961
						if ( 0 < strlen( $pick_orderby ) ) {
1962
							$orderby[] = $pick_orderby;
1963
						}
1964
1965
						$orderby[] = "`t`.`{$search_data->field_index}`";
1966
						$orderby[] = "`t`.`{$search_data->field_id}`";
1967
1968
						$params['orderby'] = $orderby;
1969
					}
1970
				} elseif ( 0 < $limit ) {
1971
					$params['limit'] = $limit;
1972
					$params['page']  = $page;
1973
				}
1974
1975
				$extra = '';
1976
1977
				if ( $wpdb->posts === $search_data->table ) {
1978
					$extra = ', `t`.`post_type`';
1979
				} elseif ( $wpdb->terms === $search_data->table ) {
1980
					$extra = ', `tt`.`taxonomy`';
1981
				} elseif ( $wpdb->comments === $search_data->table ) {
1982
					$extra = ', `t`.`comment_type`';
1983
				}
1984
1985
				$params['select'] .= $extra;
1986
1987
				if ( 'user' === pods_v( self::$type . '_object', $options ) ) {
1988
					$roles = pods_v( self::$type . '_user_role', $options );
1989
1990
					if ( ! empty( $roles ) ) {
1991
						$where = array();
1992
1993
						foreach ( (array) $roles as $role ) {
1994
							if ( empty( $role ) || ( pods_clean_name( $role ) !== $role && sanitize_title( $role ) !== $role ) ) {
1995
								continue;
1996
							}
1997
1998
							$where[] = $wpdb->base_prefix . ( ( is_multisite() && ! is_main_site() ) ? get_current_blog_id() . '_' : '' ) . 'capabilities.meta_value LIKE "%\"' . pods_sanitize_like( $role ) . '\"%"';
1999
						}
2000
2001
						if ( ! empty( $where ) ) {
2002
							$params['where'][] = implode( ' OR ', $where );
2003
						}
2004
					}
2005
				}
2006
2007
				$results = $search_data->select( $params );
2008
2009
				if ( $autocomplete && $params['limit'] < $search_data->total_found() ) {
2010
					if ( ! empty( $value ) ) {
2011
						$ids = $value;
2012
2013
						if ( is_array( $ids ) && isset( $ids[0] ) && is_array( $ids[0] ) ) {
2014
							$ids = wp_list_pluck( $ids, $search_data->field_id );
2015
						}
2016
2017
						if ( is_array( $ids ) ) {
2018
							$ids = implode( ', ', $ids );
2019
						}
2020
2021
						if ( is_array( $params['where'] ) ) {
2022
							$params['where'] = implode( ' AND ', $params['where'] );
2023
						}
2024
						if ( ! empty( $params['where'] ) ) {
2025
							$params['where'] .= ' AND ';
2026
						}
2027
2028
						$params['where'] .= "`t`.`{$search_data->field_id}` IN ( {$ids} )";
2029
2030
						$results = $search_data->select( $params );
2031
					}
2032
				} else {
2033
					$autocomplete = false;
2034
				}
2035
2036 View Code Duplication
				if ( 'data' === $context ) {
2037
					self::$field_data = array(
2038
						'field'        => $name,
2039
						'id'           => $options['id'],
2040
						'autocomplete' => $autocomplete,
2041
					);
2042
				}
2043
2044
				if ( $hierarchy && ! $autocomplete && ! empty( $results ) && $options['table_info']['object_hierarchical'] && ! empty( $options['table_info']['field_parent'] ) ) {
2045
					$select_args = array(
2046
						'id'     => $options['table_info']['field_id'],
2047
						'index'  => $options['table_info']['field_index'],
2048
						'parent' => $options['table_info']['field_parent'],
2049
					);
2050
2051
					$results = pods_hierarchical_select( $results, $select_args );
2052
				}
2053
2054
				$ids = array();
2055
2056
				if ( ! empty( $results ) ) {
2057
					$display_filter = pods_v( 'display_filter', pods_v( 'options', pods_v( $search_data->field_index, $search_data->pod_data['object_fields'] ) ) );
2058
2059
					foreach ( $results as $result ) {
2060
						$result = get_object_vars( $result );
2061
2062
						if ( ! isset( $result[ $search_data->field_id ] ) || ! isset( $result[ $search_data->field_index ] ) ) {
2063
							continue;
2064
						}
2065
2066
						$result[ $search_data->field_index ] = trim( $result[ $search_data->field_index ] );
2067
2068
						$object = $object_type = '';
2069
2070
						if ( $wpdb->posts === $search_data->table && isset( $result['post_type'] ) ) {
2071
							$object      = $result['post_type'];
2072
							$object_type = 'post_type';
2073
						} elseif ( $wpdb->terms === $search_data->table && isset( $result['taxonomy'] ) ) {
2074
							$object      = $result['taxonomy'];
2075
							$object_type = 'taxonomy';
2076
						}
2077
2078
						if ( 0 < strlen( $display_filter ) ) {
2079
							$display_filter_args = pods_v( 'display_filter_args', pods_v( 'options', pods_v( $search_data->field_index, $search_data->pod_data['object_fields'] ) ) );
2080
2081
							$filter_args = array(
2082
								$display_filter,
2083
								$result[ $search_data->field_index ],
2084
							);
2085
2086
							if ( ! empty( $display_filter_args ) ) {
2087
								foreach ( (array) $display_filter_args as $display_filter_arg ) {
2088
									if ( isset( $result[ $display_filter_arg ] ) ) {
2089
										$filter_args[] = $result[ $display_filter_arg ];
2090
									}
2091
								}
2092
							}
2093
2094
							$result[ $search_data->field_index ] = call_user_func_array( 'apply_filters', $filter_args );
2095
						}
2096
2097
						if ( in_array( $options[ self::$type . '_object' ], array( 'site', 'network' ), true ) ) {
2098
							$result[ $search_data->field_index ] = $result[ $search_data->field_index ] . $result['path'];
2099
						} elseif ( strlen( $result[ $search_data->field_index ] ) < 1 ) {
2100
							$result[ $search_data->field_index ] = '(No Title)';
2101
						}
2102
2103
						if ( 'admin_ajax_relationship' === $context ) {
2104
							$items[] = array(
2105
								'id'    => $result[ $search_data->field_id ],
2106
								'text'  => $result[ $search_data->field_index ],
2107
								'image' => '',
2108
							);
2109
						} else {
2110
							$data[ $result[ $search_data->field_id ] ] = $result[ $search_data->field_index ];
2111
						}
2112
2113
						$ids[] = $result[ $search_data->field_id ];
2114
					}
2115
				}
2116
			}
2117
2118
			if ( $simple && 'admin_ajax_relationship' === $context ) {
2119
				$found_data = array();
2120
2121
				foreach ( $data as $k => $v ) {
2122
					if ( false !== stripos( $v, $data_params['query'] ) || false !== stripos( $k, $data_params['query'] ) ) {
2123
						$found_data[ $k ] = $v;
2124
					}
2125
				}
2126
2127
				$data = $found_data;
2128
			}
2129
		}
2130
2131
		if ( 'admin_ajax_relationship' === $context ) {
2132
			if ( empty( $items ) && ! empty( $data ) ) {
2133
				foreach ( $data as $k => $v ) {
2134
					$items[] = array(
2135
						'id'    => $k,
2136
						'text'  => $v,
2137
						'image' => '',
2138
					);
2139
				}
2140
			}
2141
2142
			$data = $items;
2143
		}
2144
2145
		return $data;
2146
2147
	}
2148
2149
	/**
2150
	 * Handle autocomplete AJAX.
2151
	 *
2152
	 * @since 2.3
2153
	 */
2154
	public function admin_ajax_relationship() {
2155
2156
		pods_session_start();
2157
2158
		// Sanitize input.
2159
		$params = pods_unslash( (array) $_POST );
2160
2161 View Code Duplication
		foreach ( $params as $key => $value ) {
2162
			if ( 'action' === $key ) {
2163
				continue;
2164
			}
2165
2166
			unset( $params[ $key ] );
2167
2168
			$params[ str_replace( '_podsfix_', '', $key ) ] = $value;
2169
		}
2170
2171
		$params = (object) $params;
2172
2173
		$uid = @session_id();
2174
2175
		if ( is_user_logged_in() ) {
2176
			$uid = 'user_' . get_current_user_id();
2177
		}
2178
2179
		$nonce_check = 'pods_relationship_' . (int) $params->pod . '_' . $uid . '_' . $params->uri . '_' . (int) $params->field;
2180
2181 View Code Duplication
		if ( ! isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, $nonce_check ) ) {
2182
			pods_error( __( 'Unauthorized request', 'pods' ), PodsInit::$admin );
0 ignored issues
show
Bug introduced by
The property admin cannot be accessed from this context as it is declared private in class PodsInit.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
2183
		}
2184
2185
		if ( empty( self::$api ) ) {
2186
			self::$api = pods_api();
2187
		}
2188
2189
		$pod   = self::$api->load_pod( array( 'id' => (int) $params->pod ) );
2190
		$field = self::$api->load_field( array( 'id' => (int) $params->field, 'table_info' => true ) );
2191
		$id    = (int) $params->id;
2192
2193
		$limit = 15;
2194
2195
		if ( isset( $params->limit ) ) {
2196
			$limit = (int) $params->limit;
2197
		}
2198
2199
		$page = 1;
2200
2201
		if ( isset( $params->page ) ) {
2202
			$page = (int) $params->page;
2203
		}
2204
2205
		if ( ! isset( $params->query ) || strlen( trim( $params->query ) ) < 1 ) {
2206
			pods_error( __( 'Invalid field request', 'pods' ), PodsInit::$admin );
0 ignored issues
show
Bug introduced by
The property admin cannot be accessed from this context as it is declared private in class PodsInit.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
2207
		} elseif ( empty( $pod ) || empty( $field ) || (int) $pod['id'] !== (int) $field['pod_id'] || ! isset( $pod['fields'][ $field['name'] ] ) ) {
2208
			pods_error( __( 'Invalid field request', 'pods' ), PodsInit::$admin );
0 ignored issues
show
Bug introduced by
The property admin cannot be accessed from this context as it is declared private in class PodsInit.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
2209
		} elseif ( 'pick' !== $field['type'] || empty( $field['table_info'] ) ) {
2210
			pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin );
0 ignored issues
show
Bug introduced by
The property admin cannot be accessed from this context as it is declared private in class PodsInit.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
2211
		} elseif ( 'single' === pods_v( self::$type . '_format_type', $field ) && 'autocomplete' === pods_v( self::$type . '_format_single', $field ) ) {
2212
			pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin );
0 ignored issues
show
Bug introduced by
The property admin cannot be accessed from this context as it is declared private in class PodsInit.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
2213
		} elseif ( 'multi' === pods_v( self::$type . '_format_type', $field ) && 'autocomplete' === pods_v( self::$type . '_format_multi', $field ) ) {
2214
			pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin );
0 ignored issues
show
Bug introduced by
The property admin cannot be accessed from this context as it is declared private in class PodsInit.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
2215
		}
2216
2217
		$object_params = array(
2218
			'name'        => $field['name'], // The name of the field.
2219
			'value'       => null, // The value of the field.
2220
			'options'     => array_merge( $field, $field['options'] ), // Field options.
2221
			'pod'         => $pod, // Pod data.
2222
			'id'          => $id, // Item ID.
2223
			'context'     => 'admin_ajax_relationship', // Data context.
2224
			'data_params' => $params,
2225
			'page'        => $page,
2226
			'limit'       => $limit
2227
		);
2228
2229
		$pick_data = apply_filters( 'pods_field_pick_data_ajax', null, $field['name'], null, $field, $pod, $id );
2230
2231
		if ( null !== $pick_data ) {
2232
			$items = $pick_data;
2233
		} else {
2234
			$items = $this->get_object_data( $object_params );
2235
		}
2236
2237
		if ( ! empty( $items ) && isset( $items[0] ) && ! is_array( $items[0] ) ) {
2238
			$new_items = array();
2239
2240
			foreach ( $items as $id => $text ) {
2241
				$new_items[] = array(
2242
					'id'    => $id,
2243
					'text'  => $text,
2244
					'image' => '',
2245
				);
2246
			}
2247
2248
			$items = $new_items;
2249
		}
2250
2251
		$items = apply_filters( 'pods_field_pick_data_ajax_items', $items, $field['name'], null, $field, $pod, $id );
2252
2253
		$items = array(
2254
			'results' => $items,
2255
		);
2256
2257
		wp_send_json( $items );
2258
2259
		die(); // KBAI!
0 ignored issues
show
Coding Style Compatibility introduced by
The method admin_ajax_relationship() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
2260
2261
	}
2262
2263
	/**
2264
	 * Data callback for Post Stati
2265
	 *
2266
	 * @param string       $name    The name of the field
2267
	 * @param string|array $value   The value of the field
2268
	 * @param array        $options Field options
2269
	 * @param array        $pod     Pod data
2270
	 * @param int          $id      Item ID
2271
	 *
2272
	 * @return array
2273
	 *
2274
	 * @since 2.3
2275
	 */
2276
	public function data_post_stati( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2277
2278
		$data = array();
2279
2280
		$post_stati = get_post_stati( array(), 'objects' );
2281
2282
		foreach ( $post_stati as $post_status ) {
2283
			$data[ $post_status->name ] = $post_status->label;
2284
		}
2285
2286
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2287
2288
	}
2289
2290
	/**
2291
	 * Data callback for User Roles
2292
	 *
2293
	 * @param string       $name    The name of the field
2294
	 * @param string|array $value   The value of the field
2295
	 * @param array        $options Field options
2296
	 * @param array        $pod     Pod data
2297
	 * @param int          $id      Item ID
2298
	 *
2299
	 * @return array
2300
	 *
2301
	 * @since 2.3
2302
	 */
2303
	public function data_roles( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2304
2305
		$data = array();
2306
2307
		global $wp_roles;
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...
2308
2309
		foreach ( $wp_roles->role_objects as $key => $role ) {
2310
			$data[ $key ] = $wp_roles->role_names[ $key ];
2311
		}
2312
2313
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2314
2315
	}
2316
2317
	/**
2318
	 * Data callback for User Capabilities
2319
	 *
2320
	 * @param string       $name    The name of the field
2321
	 * @param string|array $value   The value of the field
2322
	 * @param array        $options Field options
2323
	 * @param array        $pod     Pod data
2324
	 * @param int          $id      Item ID
2325
	 *
2326
	 * @return array
2327
	 *
2328
	 * @since 2.3
2329
	 */
2330
	public function data_capabilities( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2331
2332
		$data = array();
2333
2334
		global $wp_roles;
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...
2335
2336
		$default_caps = array(
2337
			'activate_plugins',
2338
			'add_users',
2339
			'create_users',
2340
			'delete_others_pages',
2341
			'delete_others_posts',
2342
			'delete_pages',
2343
			'delete_plugins',
2344
			'delete_posts',
2345
			'delete_private_pages',
2346
			'delete_private_posts',
2347
			'delete_published_pages',
2348
			'delete_published_posts',
2349
			'delete_users',
2350
			'edit_dashboard',
2351
			'edit_files',
2352
			'edit_others_pages',
2353
			'edit_others_posts',
2354
			'edit_pages',
2355
			'edit_plugins',
2356
			'edit_posts',
2357
			'edit_private_pages',
2358
			'edit_private_posts',
2359
			'edit_published_pages',
2360
			'edit_published_posts',
2361
			'edit_theme_options',
2362
			'edit_themes',
2363
			'edit_users',
2364
			'import',
2365
			'install_plugins',
2366
			'install_themes',
2367
			'list_users',
2368
			'manage_categories',
2369
			'manage_links',
2370
			'manage_options',
2371
			'moderate_comments',
2372
			'promote_users',
2373
			'publish_pages',
2374
			'publish_posts',
2375
			'read',
2376
			'read_private_pages',
2377
			'read_private_posts',
2378
			'remove_users',
2379
			'switch_themes',
2380
			'unfiltered_html',
2381
			'unfiltered_upload',
2382
			'update_core',
2383
			'update_plugins',
2384
			'update_themes',
2385
			'upload_files',
2386
		);
2387
2388
		$role_caps = array();
2389
2390 View Code Duplication
		foreach ( $wp_roles->role_objects as $key => $role ) {
2391
			if ( is_array( $role->capabilities ) ) {
2392
				foreach ( $role->capabilities as $cap => $grant ) {
2393
					$role_caps[ $cap ] = $cap;
2394
				}
2395
			}
2396
		}
2397
2398
		$role_caps = array_unique( $role_caps );
2399
2400
		$capabilities = array_merge( $default_caps, $role_caps );
2401
2402
		// To support Members filters
2403
		$capabilities = apply_filters( 'members_get_capabilities', $capabilities );
2404
2405
		$capabilities = apply_filters( 'pods_roles_get_capabilities', $capabilities );
2406
2407
		sort( $capabilities );
2408
2409
		$capabilities = array_unique( $capabilities );
2410
2411
		global $wp_roles;
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...
2412
2413
		foreach ( $capabilities as $capability ) {
2414
			$data[ $capability ] = $capability;
2415
		}
2416
2417
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2418
2419
	}
2420
2421
	/**
2422
	 * Data callback for Image Sizes
2423
	 *
2424
	 * @param string       $name    The name of the field
2425
	 * @param string|array $value   The value of the field
2426
	 * @param array        $options Field options
2427
	 * @param array        $pod     Pod data
2428
	 * @param int          $id      Item ID
2429
	 *
2430
	 * @return array
2431
	 *
2432
	 * @since 2.3
2433
	 */
2434 View Code Duplication
	public function data_image_sizes( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2435
2436
		$data = array();
2437
2438
		$image_sizes = get_intermediate_image_sizes();
2439
2440
		foreach ( $image_sizes as $image_size ) {
2441
			$data[ $image_size ] = ucwords( str_replace( '-', ' ', $image_size ) );
2442
		}
2443
2444
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2445
2446
	}
2447
2448
	/**
2449
	 * Data callback for Countries
2450
	 *
2451
	 * @param string       $name    The name of the field
2452
	 * @param string|array $value   The value of the field
2453
	 * @param array        $options Field options
2454
	 * @param array        $pod     Pod data
2455
	 * @param int          $id      Item ID
2456
	 *
2457
	 * @return array
2458
	 *
2459
	 * @since 2.3
2460
	 */
2461
	public function data_countries( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2462
2463
		$data = array(
2464
			'AF' => __( 'Afghanistan' ),
2465
			'AL' => __( 'Albania' ),
2466
			'DZ' => __( 'Algeria' ),
2467
			'AS' => __( 'American Samoa' ),
2468
			'AD' => __( 'Andorra' ),
2469
			'AO' => __( 'Angola' ),
2470
			'AI' => __( 'Anguilla' ),
2471
			'AQ' => __( 'Antarctica' ),
2472
			'AG' => __( 'Antigua and Barbuda' ),
2473
			'AR' => __( 'Argentina' ),
2474
			'AM' => __( 'Armenia' ),
2475
			'AW' => __( 'Aruba' ),
2476
			'AU' => __( 'Australia' ),
2477
			'AT' => __( 'Austria' ),
2478
			'AZ' => __( 'Azerbaijan' ),
2479
			'BS' => __( 'Bahamas' ),
2480
			'BH' => __( 'Bahrain' ),
2481
			'BD' => __( 'Bangladesh' ),
2482
			'BB' => __( 'Barbados' ),
2483
			'BY' => __( 'Belarus' ),
2484
			'BE' => __( 'Belgium' ),
2485
			'BZ' => __( 'Belize' ),
2486
			'BJ' => __( 'Benin' ),
2487
			'BM' => __( 'Bermuda' ),
2488
			'BT' => __( 'Bhutan' ),
2489
			'BO' => __( 'Bolivia' ),
2490
			'BA' => __( 'Bosnia and Herzegovina' ),
2491
			'BW' => __( 'Botswana' ),
2492
			'BV' => __( 'Bouvet Island' ),
2493
			'BR' => __( 'Brazil' ),
2494
			'BQ' => __( 'British Antarctic Territory' ),
2495
			'IO' => __( 'British Indian Ocean Territory' ),
2496
			'VG' => __( 'British Virgin Islands' ),
2497
			'BN' => __( 'Brunei' ),
2498
			'BG' => __( 'Bulgaria' ),
2499
			'BF' => __( 'Burkina Faso' ),
2500
			'BI' => __( 'Burundi' ),
2501
			'KH' => __( 'Cambodia' ),
2502
			'CM' => __( 'Cameroon' ),
2503
			'CA' => __( 'Canada' ),
2504
			'CT' => __( 'Canton and Enderbury Islands' ),
2505
			'CV' => __( 'Cape Verde' ),
2506
			'KY' => __( 'Cayman Islands' ),
2507
			'CF' => __( 'Central African Republic' ),
2508
			'TD' => __( 'Chad' ),
2509
			'CL' => __( 'Chile' ),
2510
			'CN' => __( 'China' ),
2511
			'CX' => __( 'Christmas Island' ),
2512
			'CC' => __( 'Cocos [Keeling] Islands' ),
2513
			'CO' => __( 'Colombia' ),
2514
			'KM' => __( 'Comoros' ),
2515
			'CG' => __( 'Congo - Brazzaville' ),
2516
			'CD' => __( 'Congo - Kinshasa' ),
2517
			'CK' => __( 'Cook Islands' ),
2518
			'CR' => __( 'Costa Rica' ),
2519
			'HR' => __( 'Croatia' ),
2520
			'CU' => __( 'Cuba' ),
2521
			'CY' => __( 'Cyprus' ),
2522
			'CZ' => __( 'Czech Republic' ),
2523
			'CI' => __( 'Côte d’Ivoire' ),
2524
			'DK' => __( 'Denmark' ),
2525
			'DJ' => __( 'Djibouti' ),
2526
			'DM' => __( 'Dominica' ),
2527
			'DO' => __( 'Dominican Republic' ),
2528
			'NQ' => __( 'Dronning Maud Land' ),
2529
			'DD' => __( 'East Germany' ),
2530
			'EC' => __( 'Ecuador' ),
2531
			'EG' => __( 'Egypt' ),
2532
			'SV' => __( 'El Salvador' ),
2533
			'GQ' => __( 'Equatorial Guinea' ),
2534
			'ER' => __( 'Eritrea' ),
2535
			'EE' => __( 'Estonia' ),
2536
			'ET' => __( 'Ethiopia' ),
2537
			'FK' => __( 'Falkland Islands' ),
2538
			'FO' => __( 'Faroe Islands' ),
2539
			'FJ' => __( 'Fiji' ),
2540
			'FI' => __( 'Finland' ),
2541
			'FR' => __( 'France' ),
2542
			'GF' => __( 'French Guiana' ),
2543
			'PF' => __( 'French Polynesia' ),
2544
			'TF' => __( 'French Southern Territories' ),
2545
			'FQ' => __( 'French Southern and Antarctic Territories' ),
2546
			'GA' => __( 'Gabon' ),
2547
			'GM' => __( 'Gambia' ),
2548
			'GE' => __( 'Georgia' ),
2549
			'DE' => __( 'Germany' ),
2550
			'GH' => __( 'Ghana' ),
2551
			'GI' => __( 'Gibraltar' ),
2552
			'GR' => __( 'Greece' ),
2553
			'GL' => __( 'Greenland' ),
2554
			'GD' => __( 'Grenada' ),
2555
			'GP' => __( 'Guadeloupe' ),
2556
			'GU' => __( 'Guam' ),
2557
			'GT' => __( 'Guatemala' ),
2558
			'GG' => __( 'Guernsey' ),
2559
			'GN' => __( 'Guinea' ),
2560
			'GW' => __( 'Guinea-Bissau' ),
2561
			'GY' => __( 'Guyana' ),
2562
			'HT' => __( 'Haiti' ),
2563
			'HM' => __( 'Heard Island and McDonald Islands' ),
2564
			'HN' => __( 'Honduras' ),
2565
			'HK' => __( 'Hong Kong SAR China' ),
2566
			'HU' => __( 'Hungary' ),
2567
			'IS' => __( 'Iceland' ),
2568
			'IN' => __( 'India' ),
2569
			'ID' => __( 'Indonesia' ),
2570
			'IR' => __( 'Iran' ),
2571
			'IQ' => __( 'Iraq' ),
2572
			'IE' => __( 'Ireland' ),
2573
			'IM' => __( 'Isle of Man' ),
2574
			'IL' => __( 'Israel' ),
2575
			'IT' => __( 'Italy' ),
2576
			'JM' => __( 'Jamaica' ),
2577
			'JP' => __( 'Japan' ),
2578
			'JE' => __( 'Jersey' ),
2579
			'JT' => __( 'Johnston Island' ),
2580
			'JO' => __( 'Jordan' ),
2581
			'KZ' => __( 'Kazakhstan' ),
2582
			'KE' => __( 'Kenya' ),
2583
			'KI' => __( 'Kiribati' ),
2584
			'KW' => __( 'Kuwait' ),
2585
			'KG' => __( 'Kyrgyzstan' ),
2586
			'LA' => __( 'Laos' ),
2587
			'LV' => __( 'Latvia' ),
2588
			'LB' => __( 'Lebanon' ),
2589
			'LS' => __( 'Lesotho' ),
2590
			'LR' => __( 'Liberia' ),
2591
			'LY' => __( 'Libya' ),
2592
			'LI' => __( 'Liechtenstein' ),
2593
			'LT' => __( 'Lithuania' ),
2594
			'LU' => __( 'Luxembourg' ),
2595
			'MO' => __( 'Macau SAR China' ),
2596
			'MK' => __( 'Macedonia' ),
2597
			'MG' => __( 'Madagascar' ),
2598
			'MW' => __( 'Malawi' ),
2599
			'MY' => __( 'Malaysia' ),
2600
			'MV' => __( 'Maldives' ),
2601
			'ML' => __( 'Mali' ),
2602
			'MT' => __( 'Malta' ),
2603
			'MH' => __( 'Marshall Islands' ),
2604
			'MQ' => __( 'Martinique' ),
2605
			'MR' => __( 'Mauritania' ),
2606
			'MU' => __( 'Mauritius' ),
2607
			'YT' => __( 'Mayotte' ),
2608
			'FX' => __( 'Metropolitan France' ),
2609
			'MX' => __( 'Mexico' ),
2610
			'FM' => __( 'Micronesia' ),
2611
			'MI' => __( 'Midway Islands' ),
2612
			'MD' => __( 'Moldova' ),
2613
			'MC' => __( 'Monaco' ),
2614
			'MN' => __( 'Mongolia' ),
2615
			'ME' => __( 'Montenegro' ),
2616
			'MS' => __( 'Montserrat' ),
2617
			'MA' => __( 'Morocco' ),
2618
			'MZ' => __( 'Mozambique' ),
2619
			'MM' => __( 'Myanmar [Burma]' ),
2620
			'NA' => __( 'Namibia' ),
2621
			'NR' => __( 'Nauru' ),
2622
			'NP' => __( 'Nepal' ),
2623
			'NL' => __( 'Netherlands' ),
2624
			'AN' => __( 'Netherlands Antilles' ),
2625
			'NT' => __( 'Neutral Zone' ),
2626
			'NC' => __( 'New Caledonia' ),
2627
			'NZ' => __( 'New Zealand' ),
2628
			'NI' => __( 'Nicaragua' ),
2629
			'NE' => __( 'Niger' ),
2630
			'NG' => __( 'Nigeria' ),
2631
			'NU' => __( 'Niue' ),
2632
			'NF' => __( 'Norfolk Island' ),
2633
			'KP' => __( 'North Korea' ),
2634
			'VD' => __( 'North Vietnam' ),
2635
			'MP' => __( 'Northern Mariana Islands' ),
2636
			'NO' => __( 'Norway' ),
2637
			'OM' => __( 'Oman' ),
2638
			'PC' => __( 'Pacific Islands Trust Territory' ),
2639
			'PK' => __( 'Pakistan' ),
2640
			'PW' => __( 'Palau' ),
2641
			'PS' => __( 'Palestinian Territories' ),
2642
			'PA' => __( 'Panama' ),
2643
			'PZ' => __( 'Panama Canal Zone' ),
2644
			'PG' => __( 'Papua New Guinea' ),
2645
			'PY' => __( 'Paraguay' ),
2646
			'YD' => __( "People's Democratic Republic of Yemen" ),
2647
			'PE' => __( 'Peru' ),
2648
			'PH' => __( 'Philippines' ),
2649
			'PN' => __( 'Pitcairn Islands' ),
2650
			'PL' => __( 'Poland' ),
2651
			'PT' => __( 'Portugal' ),
2652
			'PR' => __( 'Puerto Rico' ),
2653
			'QA' => __( 'Qatar' ),
2654
			'RO' => __( 'Romania' ),
2655
			'RU' => __( 'Russia' ),
2656
			'RW' => __( 'Rwanda' ),
2657
			'RE' => __( 'Réunion' ),
2658
			'BL' => __( 'Saint Barthélemy' ),
2659
			'SH' => __( 'Saint Helena' ),
2660
			'KN' => __( 'Saint Kitts and Nevis' ),
2661
			'LC' => __( 'Saint Lucia' ),
2662
			'MF' => __( 'Saint Martin' ),
2663
			'PM' => __( 'Saint Pierre and Miquelon' ),
2664
			'VC' => __( 'Saint Vincent and the Grenadines' ),
2665
			'WS' => __( 'Samoa' ),
2666
			'SM' => __( 'San Marino' ),
2667
			'SA' => __( 'Saudi Arabia' ),
2668
			'SN' => __( 'Senegal' ),
2669
			'RS' => __( 'Serbia' ),
2670
			'CS' => __( 'Serbia and Montenegro' ),
2671
			'SC' => __( 'Seychelles' ),
2672
			'SL' => __( 'Sierra Leone' ),
2673
			'SG' => __( 'Singapore' ),
2674
			'SK' => __( 'Slovakia' ),
2675
			'SI' => __( 'Slovenia' ),
2676
			'SB' => __( 'Solomon Islands' ),
2677
			'SO' => __( 'Somalia' ),
2678
			'ZA' => __( 'South Africa' ),
2679
			'GS' => __( 'South Georgia and the South Sandwich Islands' ),
2680
			'KR' => __( 'South Korea' ),
2681
			'ES' => __( 'Spain' ),
2682
			'LK' => __( 'Sri Lanka' ),
2683
			'SD' => __( 'Sudan' ),
2684
			'SR' => __( 'Suriname' ),
2685
			'SJ' => __( 'Svalbard and Jan Mayen' ),
2686
			'SZ' => __( 'Swaziland' ),
2687
			'SE' => __( 'Sweden' ),
2688
			'CH' => __( 'Switzerland' ),
2689
			'SY' => __( 'Syria' ),
2690
			'ST' => __( 'São Tomé and Príncipe' ),
2691
			'TW' => __( 'Taiwan' ),
2692
			'TJ' => __( 'Tajikistan' ),
2693
			'TZ' => __( 'Tanzania' ),
2694
			'TH' => __( 'Thailand' ),
2695
			'TL' => __( 'Timor-Leste' ),
2696
			'TG' => __( 'Togo' ),
2697
			'TK' => __( 'Tokelau' ),
2698
			'TO' => __( 'Tonga' ),
2699
			'TT' => __( 'Trinidad and Tobago' ),
2700
			'TN' => __( 'Tunisia' ),
2701
			'TR' => __( 'Turkey' ),
2702
			'TM' => __( 'Turkmenistan' ),
2703
			'TC' => __( 'Turks and Caicos Islands' ),
2704
			'TV' => __( 'Tuvalu' ),
2705
			'UM' => __( 'U.S. Minor Outlying Islands' ),
2706
			'PU' => __( 'U.S. Miscellaneous Pacific Islands' ),
2707
			'VI' => __( 'U.S. Virgin Islands' ),
2708
			'UG' => __( 'Uganda' ),
2709
			'UA' => __( 'Ukraine' ),
2710
			'SU' => __( 'Union of Soviet Socialist Republics' ),
2711
			'AE' => __( 'United Arab Emirates' ),
2712
			'GB' => __( 'United Kingdom' ),
2713
			'US' => __( 'United States' ),
2714
			'ZZ' => __( 'Unknown or Invalid Region' ),
2715
			'UY' => __( 'Uruguay' ),
2716
			'UZ' => __( 'Uzbekistan' ),
2717
			'VU' => __( 'Vanuatu' ),
2718
			'VA' => __( 'Vatican City' ),
2719
			'VE' => __( 'Venezuela' ),
2720
			'VN' => __( 'Vietnam' ),
2721
			'WK' => __( 'Wake Island' ),
2722
			'WF' => __( 'Wallis and Futuna' ),
2723
			'EH' => __( 'Western Sahara' ),
2724
			'YE' => __( 'Yemen' ),
2725
			'ZM' => __( 'Zambia' ),
2726
			'ZW' => __( 'Zimbabwe' ),
2727
			'AX' => __( 'Åland Islands' ),
2728
		);
2729
2730
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2731
2732
	}
2733
2734
	/**
2735
	 * Data callback for US States
2736
	 *
2737
	 * @param string       $name    The name of the field
2738
	 * @param string|array $value   The value of the field
2739
	 * @param array        $options Field options
2740
	 * @param array        $pod     Pod data
2741
	 * @param int          $id      Item ID
2742
	 *
2743
	 * @return array
2744
	 *
2745
	 * @since 2.3
2746
	 */
2747
	public function data_us_states( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2748
2749
		$data = array(
2750
			'AL' => __( 'Alabama' ),
2751
			'AK' => __( 'Alaska' ),
2752
			'AZ' => __( 'Arizona' ),
2753
			'AR' => __( 'Arkansas' ),
2754
			'CA' => __( 'California' ),
2755
			'CO' => __( 'Colorado' ),
2756
			'CT' => __( 'Connecticut' ),
2757
			'DE' => __( 'Delaware' ),
2758
			'DC' => __( 'District Of Columbia' ),
2759
			'FL' => __( 'Florida' ),
2760
			'GA' => __( 'Georgia' ),
2761
			'HI' => __( 'Hawaii' ),
2762
			'ID' => __( 'Idaho' ),
2763
			'IL' => __( 'Illinois' ),
2764
			'IN' => __( 'Indiana' ),
2765
			'IA' => __( 'Iowa' ),
2766
			'KS' => __( 'Kansas' ),
2767
			'KY' => __( 'Kentucky' ),
2768
			'LA' => __( 'Louisiana' ),
2769
			'ME' => __( 'Maine' ),
2770
			'MD' => __( 'Maryland' ),
2771
			'MA' => __( 'Massachusetts' ),
2772
			'MI' => __( 'Michigan' ),
2773
			'MN' => __( 'Minnesota' ),
2774
			'MS' => __( 'Mississippi' ),
2775
			'MO' => __( 'Missouri' ),
2776
			'MT' => __( 'Montana' ),
2777
			'NE' => __( 'Nebraska' ),
2778
			'NV' => __( 'Nevada' ),
2779
			'NH' => __( 'New Hampshire' ),
2780
			'NJ' => __( 'New Jersey' ),
2781
			'NM' => __( 'New Mexico' ),
2782
			'NY' => __( 'New York' ),
2783
			'NC' => __( 'North Carolina' ),
2784
			'ND' => __( 'North Dakota' ),
2785
			'OH' => __( 'Ohio' ),
2786
			'OK' => __( 'Oklahoma' ),
2787
			'OR' => __( 'Oregon' ),
2788
			'PA' => __( 'Pennsylvania' ),
2789
			'RI' => __( 'Rhode Island' ),
2790
			'SC' => __( 'South Carolina' ),
2791
			'SD' => __( 'South Dakota' ),
2792
			'TN' => __( 'Tennessee' ),
2793
			'TX' => __( 'Texas' ),
2794
			'UT' => __( 'Utah' ),
2795
			'VT' => __( 'Vermont' ),
2796
			'VA' => __( 'Virginia' ),
2797
			'WA' => __( 'Washington' ),
2798
			'WV' => __( 'West Virginia' ),
2799
			'WI' => __( 'Wisconsin' ),
2800
			'WY' => __( 'Wyoming' ),
2801
		);
2802
2803
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2804
2805
	}
2806
2807
	/**
2808
	 * Data callback for US States
2809
	 *
2810
	 * @param string       $name    The name of the field
2811
	 * @param string|array $value   The value of the field
2812
	 * @param array        $options Field options
2813
	 * @param array        $pod     Pod data
2814
	 * @param int          $id      Item ID
2815
	 *
2816
	 * @return array
2817
	 *
2818
	 * @since 2.3
2819
	 */
2820
	public function data_days_of_week( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $pod is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2821
2822
		/**
2823
		 * @var WP_Locale
2824
		 */
2825
		global $wp_locale;
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...
2826
2827
		return $wp_locale->weekday;
2828
2829
	}
2830
2831
	/**
2832
	 * Data callback for US States
2833
	 *
2834
	 * @param string       $name    The name of the field
2835
	 * @param string|array $value   The value of the field
2836
	 * @param array        $options Field options
2837
	 * @param array        $pod     Pod data
2838
	 * @param int          $id      Item ID
2839
	 *
2840
	 * @return array
2841
	 *
2842
	 * @since 2.3
2843
	 */
2844
	public function data_months_of_year( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $pod is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2845
2846
		/**
2847
		 * @var WP_Locale
2848
		 */
2849
		global $wp_locale;
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...
2850
2851
		return $wp_locale->month;
2852
2853
	}
2854
2855
	/**
2856
	 * Add our modal input to the form so we can track whether we're in our modal during saving or not.
2857
	 */
2858
	public function admin_modal_input() {
2859
2860
		if ( ! pods_is_modal_window() ) {
2861
			return;
2862
		}
2863
2864
		echo '<input name="pods_modal" type="hidden" value="1" />';
2865
2866
	}
2867
2868
	/**
2869
	 * Bail to send new saved data back to our modal handler.
2870
	 *
2871
	 * @param int    $item_id
2872
	 * @param string $item_title
2873
	 * @param object $field_args
2874
	 */
2875
	public function admin_modal_bail( $item_id, $item_title, $field_args ) {
2876
2877
		$model_data = $this->build_dfv_field_item_data_recurse_item( $item_id, $item_title, $field_args );
2878
		?>
2879
			<script type="text/javascript">
2880
				const modalRecord = <?php echo json_encode( $model_data, JSON_HEX_TAG ); ?>;
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_HEX_TAG.

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

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

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

Loading history...
2881
2882
				window.parent.jQuery( window.parent ).trigger( 'dfv:modal:update', modalRecord );
2883
			</script>
2884
		<?php
2885
2886
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method admin_modal_bail() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
2887
2888
	}
2889
2890
	/**
2891
	 * Bail on Post save redirect for Admin modal.
2892
	 *
2893
	 * @param string $location The destination URL.
2894
	 * @param int    $post_id  The post ID.
2895
	 *
2896
	 * @return string
2897
	 */
2898
	public function admin_modal_bail_post_redirect( $location, $post_id ) {
2899
2900
		if ( ! pods_is_modal_window() ) {
2901
			return $location;
2902
		}
2903
2904
		$post_title = get_the_title( $post_id );
2905
2906
		$field_args = (object) array(
2907
			'options' => array(
2908
				'pick_object' => 'post_type',
2909
				'pick_val'    => get_post_type( $post_id ),
2910
			),
2911
			'value'   => array(
2912
				$post_id => $post_title,
2913
			),
2914
		);
2915
2916
		$this->admin_modal_bail( $post_id, $post_title, $field_args );
2917
2918
		return $location;
2919
2920
	}
2921
2922
	/**
2923
	 * Hook into term updating process to bail on redirect.
2924
	 */
2925
	public function admin_modal_bail_term_action() {
2926
2927
		if ( ! pods_is_modal_window() ) {
2928
			return;
2929
		}
2930
2931
		add_action( 'created_term', array( $this, 'admin_modal_bail_term' ), 10, 3 );
2932
		add_action( 'edited_term', array( $this, 'admin_modal_bail_term' ), 10, 3 );
2933
2934
	}
2935
2936
	/**
2937
	 * Bail on Term save redirect for Admin modal.
2938
	 *
2939
	 * @param int    $term_id  Term ID.
2940
	 * @param int    $tt_id    Term taxonomy ID.
2941
	 * @param string $taxonomy Taxonomy slug.
2942
	 */
2943
	public function admin_modal_bail_term( $term_id, $tt_id, $taxonomy ) {
0 ignored issues
show
Unused Code introduced by
The parameter $tt_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $taxonomy is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
2944
2945
		if ( ! pods_is_modal_window() ) {
2946
			return;
2947
		}
2948
2949
		$term = get_term( $term_id );
2950
2951
		if ( ! $term || is_wp_error( $term ) ) {
2952
			return;
2953
		}
2954
2955
		$field_args = (object) array(
2956
			'options' => array(
2957
				'pick_object' => 'taxonomy',
2958
				'pick_val'    => $term->taxonomy,
2959
			),
2960
			'value'   => array(
2961
				$term->term_id => $term->name,
2962
			),
2963
		);
2964
2965
		$this->admin_modal_bail( $term->term_id, $term->name, $field_args );
2966
2967
	}
2968
2969
	/**
2970
	 * Hook into user updating process to bail on redirect.
2971
	 */
2972
	public function admin_modal_bail_user_action() {
2973
2974
		if ( ! pods_is_modal_window() ) {
2975
			return;
2976
		}
2977
2978
		add_filter( 'wp_redirect', array( $this, 'admin_modal_bail_user_redirect' ) );
2979
2980
	}
2981
2982
	/**
2983
	 * Bail on User save redirect for Admin modal.
2984
	 *
2985
	 * @param string $location The destination URL.
2986
	 *
2987
	 * @return string
2988
	 */
2989
	public function admin_modal_bail_user_redirect( $location ) {
2990
2991
		if ( ! pods_is_modal_window() ) {
2992
			return $location;
2993
		}
2994
2995
		global $user_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...
2996
2997
		$user = get_userdata( $user_id );
2998
2999
		if ( ! $user || is_wp_error( $user ) ) {
3000
			return $location;
3001
		}
3002
3003
		$field_args = (object) array(
3004
			'options' => array(
3005
				'pick_object' => 'user',
3006
				'pick_val'    => '',
3007
			),
3008
			'value'   => array(
3009
				$user->ID => $user->display_name,
3010
			),
3011
		);
3012
3013
		$this->admin_modal_bail( $user->ID, $user->display_name, $field_args );
3014
3015
		return $location;
3016
3017
	}
3018
3019
	/**
3020
	 * Bail on Pod item save for Admin modal.
3021
	 *
3022
	 * @param int       $id     Item ID.
3023
	 * @param array     $params save_pod_item parameters.
3024
	 * @param null|Pods $obj    Pod object (if set).
3025
	 */
3026
	public function admin_modal_bail_pod( $id, $params, $obj ) {
3027
3028
		if ( ! pods_is_modal_window() ) {
3029
			return;
3030
		}
3031
3032
		if ( ! $obj ) {
3033
			$obj = pods( $params['pod'] );
3034
		}
3035
3036
		if ( ! $obj || $obj->fetch( $id ) ) {
3037
			return;
3038
		}
3039
3040
		$item_id    = $obj->id();
3041
		$item_title = $obj->index();
3042
3043
		$field_args = (object) array(
3044
			'options' => array(
3045
				'pick_object' => $obj->pod_data['type'],
3046
				'pick_val'    => $obj->pod,
3047
			),
3048
			'value'   => array(
3049
				$obj->id() => $item_title,
3050
			),
3051
		);
3052
3053
		$this->admin_modal_bail( $item_id, $item_title, $field_args );
3054
3055
	}
3056
3057
}
3058