Completed
Push — 2.x ( 971a6c...befcfa )
by Scott Kingsley
08:24 queued 03:02
created

PodsField_Pick::build_dfv_field_options()   F

Complexity

Conditions 21
Paths 512

Size

Total Lines 77
Code Lines 48

Duplication

Lines 22
Ratio 28.57 %

Importance

Changes 0
Metric Value
cc 21
eloc 48
nc 512
nop 2
dl 22
loc 77
rs 3.2549
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
	}
107
108
	/**
109
	 * {@inheritdoc}
110
	 */
111
	public function options() {
112
113
		$options = array(
114
			self::$type . '_format_type'    => array(
115
				'label'      => __( 'Selection Type', 'pods' ),
116
				'help'       => __( 'help', 'pods' ),
117
				'default'    => 'single',
118
				'type'       => 'pick',
119
				'data'       => array(
120
					'single' => __( 'Single Select', 'pods' ),
121
					'multi'  => __( 'Multiple Select', 'pods' ),
122
				),
123
				'dependency' => true,
124
			),
125
			self::$type . '_format_single'  => array(
126
				'label'      => __( 'Format', 'pods' ),
127
				'help'       => __( 'help', 'pods' ),
128
				'depends-on' => array( self::$type . '_format_type' => 'single' ),
129
				'default'    => 'dropdown',
130
				'type'       => 'pick',
131
				'data'       => apply_filters( 'pods_form_ui_field_pick_format_single_options', array(
132
						'dropdown'     => __( 'Drop Down', 'pods' ),
133
						'radio'        => __( 'Radio Buttons', 'pods' ),
134
						'autocomplete' => __( 'Autocomplete', 'pods' ),
135
						'list'         => __( 'List view', 'pods' ),
136
					)
137
				),
138
				'dependency' => true,
139
			),
140
			self::$type . '_format_multi'   => array(
141
				'label'      => __( 'Format', 'pods' ),
142
				'help'       => __( 'help', 'pods' ),
143
				'depends-on' => array( self::$type . '_format_type' => 'multi' ),
144
				'default'    => 'checkbox',
145
				'type'       => 'pick',
146
				'data'       => apply_filters( 'pods_form_ui_field_pick_format_multi_options', array(
147
						'checkbox'     => __( 'Checkboxes', 'pods' ),
148
						'multiselect'  => __( 'Multi Select', 'pods' ),
149
						'autocomplete' => __( 'Autocomplete', 'pods' ),
150
						'list'         => __( 'List view', 'pods' ),
151
					)
152
				),
153
				'dependency' => true,
154
			),
155
			self::$type . '_taggable'       => array(
156
				'label'       => __( 'Taggable', 'pods' ),
157
				'help'        => __( 'Allow new values to be inserted when using an Autocomplete field', 'pods' ),
158
				'excludes-on' => array(
159
					self::$type . '_format_single' => array( 'dropdown', 'radio' ),
160
					self::$type . '_format_multi'  => array( 'checkbox', 'multiselect' ),
161
					self::$type . '_object'        => array_merge( array( 'site', 'network' ), self::simple_objects() ),
162
				),
163
				'type'        => 'boolean',
164
				'default'     => 0,
165
			),
166
			self::$type . '_show_icon'      => array(
167
				'label'       => __( 'Show Icons', 'pods' ),
168
				'excludes-on' => array(
169
					self::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ),
170
					self::$type . '_format_multi'  => array( 'checkbox', 'multiselect', 'autocomplete' ),
171
					self::$type . '_object'        => array_merge( array( 'site', 'network' ), self::simple_objects() ),
172
				),
173
				'type'        => 'boolean',
174
				'default'     => 1,
175
			),
176
			self::$type . '_show_edit_link' => array(
177
				'label'       => __( 'Show Edit Links', 'pods' ),
178
				'excludes-on' => array(
179
					self::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ),
180
					self::$type . '_format_multi'  => array( 'checkbox', 'multiselect', 'autocomplete' ),
181
					self::$type . '_object'        => array_merge( array( 'site', 'network' ), self::simple_objects() ),
182
				),
183
				'type'        => 'boolean',
184
				'default'     => 1,
185
			),
186
			self::$type . '_show_view_link' => array(
187
				'label'       => __( 'Show View Links', 'pods' ),
188
				'excludes-on' => array(
189
					self::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ),
190
					self::$type . '_format_multi'  => array( 'checkbox', 'multiselect', 'autocomplete' ),
191
					self::$type . '_object'        => array_merge( array( 'site', 'network' ), self::simple_objects() ),
192
				),
193
				'type'        => 'boolean',
194
				'default'     => 1,
195
			),
196
			self::$type . '_select_text'    => array(
197
				'label'      => __( 'Default Select Text', 'pods' ),
198
				'help'       => __( 'This is the text use for the default "no selection" dropdown item, if empty, it will default to "-- Select One --"', 'pods' ),
199
				'depends-on' => array(
200
					self::$type . '_format_type'   => 'single',
201
					self::$type . '_format_single' => 'dropdown',
202
				),
203
				'default'    => '',
204
				'type'       => 'text',
205
			),
206
			self::$type . '_limit'          => array(
207
				'label'      => __( 'Selection Limit', 'pods' ),
208
				'help'       => __( 'help', 'pods' ),
209
				'depends-on' => array( self::$type . '_format_type' => 'multi' ),
210
				'default'    => 0,
211
				'type'       => 'number',
212
			),
213
			self::$type . '_table_id'       => array(
214
				'label'      => __( 'Table ID Column', 'pods' ),
215
				'help'       => __( 'You must provide the ID column name for the table, this will be used to keep track of the relationship', 'pods' ),
216
				'depends-on' => array( self::$type . '_object' => 'table' ),
217
				'required'   => 1,
218
				'default'    => '',
219
				'type'       => 'text',
220
			),
221
			self::$type . '_table_index'    => array(
222
				'label'      => __( 'Table Index Column', 'pods' ),
223
				'help'       => __( 'You must provide the index column name for the table, this may optionally also be the ID column name', 'pods' ),
224
				'depends-on' => array( self::$type . '_object' => 'table' ),
225
				'required'   => 1,
226
				'default'    => '',
227
				'type'       => 'text',
228
			),
229
			self::$type . '_display'        => array(
230
				'label'       => __( 'Display Field in Selection List', 'pods' ),
231
				'help'        => __( 'Provide the name of a field on the related object to reference, example: {@post_title}', 'pods' ),
232
				'excludes-on' => array(
233
					self::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ),
234
				),
235
				'default'     => '',
236
				'type'        => 'text',
237
			),
238
			self::$type . '_user_role'      => array(
239
				'label'            => __( 'Limit list to Role(s)', 'pods' ),
240
				'help'             => __( 'help', 'pods' ),
241
				'depends-on'       => array( self::$type . '_object' => 'user' ),
242
				'default'          => '',
243
				'type'             => 'pick',
244
				'pick_object'      => 'role',
245
				'pick_format_type' => 'multi',
246
			),
247
			/*
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...
248
            self::$type . '_user_site' => array(
249
                'label' => __( 'Limit list to Site(s)', 'pods' ),
250
                'help' => __( 'help', 'pods' ),
251
                'depends-on' => array( self::$type . '_object' => 'user' ),
252
                'default' => '',
253
                'type' => 'pick',
254
                'pick_object' => 'site',
255
                'pick_format_type' => 'multi',
256
            ),
257
			*/
258
			self::$type . '_where'          => array(
259
				'label'       => __( 'Customized <em>WHERE</em>', 'pods' ),
260
				'help'        => __( 'help', 'pods' ),
261
				'excludes-on' => array(
262
					self::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ),
263
				),
264
				'default'     => '',
265
				'type'        => 'text',
266
			),
267
			self::$type . '_orderby'        => array(
268
				'label'       => __( 'Customized <em>ORDER BY</em>', 'pods' ),
269
				'help'        => __( 'help', 'pods' ),
270
				'excludes-on' => array(
271
					self::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ),
272
				),
273
				'default'     => '',
274
				'type'        => 'text',
275
			),
276
			self::$type . '_groupby'        => array(
277
				'label'       => __( 'Customized <em>GROUP BY</em>', 'pods' ),
278
				'help'        => __( 'help', 'pods' ),
279
				'excludes-on' => array(
280
					self::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ),
281
				),
282
				'default'     => '',
283
				'type'        => 'text',
284
			),
285
			/*
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...
286
			self::$type . '_size' => array(
287
				'label' => __( 'Field Size', 'pods' ),
288
				'default' => 'medium',
289
				'type' => 'pick',
290
				'data' => array(
291
					'small' => __( 'Small', 'pods' ),
292
					'medium' => __( 'Medium', 'pods' ),
293
					'large' => __( 'Large', 'pods' )
294
				)
295
			),
296
			*/
297
		);
298
299
		$post_type_pick_objects = array();
300
301
		foreach ( get_post_types( '', 'names' ) as $post_type ) {
302
			$post_type_pick_objects[] = 'post-type_' . $post_type;
303
		}
304
305
		$options[ self::$type . '_post_status' ] = array(
306
			'name'             => 'post_status',
307
			'label'            => __( 'Post Status', 'pods' ),
308
			'help'             => __( 'help', 'pods' ),
309
			'type'             => 'pick',
310
			'pick_object'      => 'post-status',
311
			'pick_format_type' => 'multi',
312
			'default'          => 'publish',
313
			'depends-on'       => array(
314
				self::$type . '_object' => $post_type_pick_objects,
315
			),
316
		);
317
318
		/*
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...
319
		if ( ! is_multisite() ) {
320
			unset( $options[ self::$type . '_user_site' ] );
321
		}
322
		*/
323
324
		return $options;
325
326
	}
327
328
	/**
329
	 * Register a related object
330
	 *
331
	 * @param string $name    Object name
332
	 * @param string $label   Object label
333
	 * @param array  $options Object options
334
	 *
335
	 * @return array|boolean Object array or false if unsuccessful
336
	 * @since 2.3
337
	 */
338
	public function register_related_object( $name, $label, $options = null ) {
339
340
		if ( empty( $name ) || empty( $label ) ) {
341
			return false;
342
		}
343
344
		$related_object = array(
345
			'label'         => $label,
346
			'group'         => 'Custom Relationships',
347
			'simple'        => true,
348
			'bidirectional' => false,
349
			'data'          => array(),
350
			'data_callback' => null,
351
		);
352
353
		$related_object = array_merge( $related_object, $options );
354
355
		self::$custom_related_objects[ $name ] = $related_object;
356
357
		return true;
358
359
	}
360
361
	/**
362
	 * Setup related objects
363
	 *
364
	 * @param boolean $force Whether to force refresh of related objects
365
	 *
366
	 * @return bool True when data has been loaded
367
	 * @since 2.3
368
	 */
369
	public function setup_related_objects( $force = false ) {
370
371
		$new_data_loaded = false;
372
373
		if ( ! $force && empty( self::$related_objects ) ) {
374
			// Only load transient if we aren't forcing a refresh.
375
			self::$related_objects = pods_transient_get( 'pods_related_objects' );
376
377
			if ( false !== self::$related_objects ) {
378
				$new_data_loaded = true;
379
			}
380
		} elseif ( $force ) {
381
			// If we are rebuilding, make sure we start with a clean slate.
382
			self::$related_objects = array();
383
		}
384
385
		if ( empty( self::$related_objects ) ) {
386
			// Do a complete build of related_objects.
387
			$new_data_loaded = true;
388
389
			// Custom simple relationship lists.
390
			self::$related_objects['custom-simple'] = array(
391
				'label'  => __( 'Simple (custom defined list)', 'pods' ),
392
				'group'  => __( 'Custom', 'pods' ),
393
				'simple' => true,
394
			);
395
396
			// Pods options.
397
			$pod_options = array();
398
399
			// Include PodsMeta if not already included.
400
			pods_meta();
401
402
			// Advanced Content Types for relationships.
403
			$_pods = PodsMeta::$advanced_content_types;
404
405 View Code Duplication
			foreach ( $_pods as $pod ) {
406
				$pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')';
407
			}
408
409
			// Settings pods for relationships.
410
			$_pods = PodsMeta::$settings;
411
412 View Code Duplication
			foreach ( $_pods as $pod ) {
413
				$pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')';
414
			}
415
416
			asort( $pod_options );
417
418
			foreach ( $pod_options as $pod => $label ) {
419
				self::$related_objects[ 'pod-' . $pod ] = array(
420
					'label'         => $label,
421
					'group'         => __( 'Pods', 'pods' ),
422
					'bidirectional' => true,
423
				);
424
			}
425
426
			// Post Types for relationships.
427
			$post_types = get_post_types();
428
			asort( $post_types );
429
430
			$ignore = array( 'attachment', 'revision', 'nav_menu_item' );
431
432 View Code Duplication
			foreach ( $post_types as $post_type => $label ) {
433
				if ( in_array( $post_type, $ignore, true ) || empty( $post_type ) ) {
434
					unset( $post_types[ $post_type ] );
435
436
					continue;
437
				} elseif ( 0 === strpos( $post_type, '_pods_' ) && apply_filters( 'pods_pick_ignore_internal', true ) ) {
438
					unset( $post_types[ $post_type ] );
439
440
					continue;
441
				}
442
443
				$post_type = get_post_type_object( $post_type );
444
445
				self::$related_objects[ 'post_type-' . $post_type->name ] = array(
446
					'label'         => $post_type->label . ' (' . $post_type->name . ')',
447
					'group'         => __( 'Post Types', 'pods' ),
448
					'bidirectional' => true,
449
				);
450
			}
451
452
			// Taxonomies for relationships.
453
			$taxonomies = get_taxonomies();
454
			asort( $taxonomies );
455
456
			$ignore = array( 'nav_menu', 'post_format' );
457
458 View Code Duplication
			foreach ( $taxonomies as $taxonomy => $label ) {
459
				/**
460
				 * Prevent ability to extend core Pods content types.
461
				 *
462
				 * @param bool $ignore_internal Default is true, when set to false Pods internal content types can not be extended.
463
				 *
464
				 * @since 2.3.19
465
				 */
466
				$ignore_internal = apply_filters( 'pods_pick_ignore_internal', true );
467
468
				if ( in_array( $taxonomy, $ignore, true ) || empty( $taxonomy ) ) {
469
					unset( $taxonomies[ $taxonomy ] );
470
471
					continue;
472
				} elseif ( 0 === strpos( $taxonomy, '_pods_' ) && $ignore_internal ) {
473
					unset( $taxonomies[ $taxonomy ] );
474
475
					continue;
476
				}
477
478
				$taxonomy = get_taxonomy( $taxonomy );
479
480
				self::$related_objects[ 'taxonomy-' . $taxonomy->name ] = array(
481
					'label'         => $taxonomy->label . ' (' . $taxonomy->name . ')',
482
					'group'         => __( 'Taxonomies', 'pods' ),
483
					'bidirectional' => true,
484
				);
485
			}
486
487
			// Other WP Objects for relationships.
488
			self::$related_objects['user'] = array(
489
				'label'         => __( 'Users', 'pods' ),
490
				'group'         => __( 'Other WP Objects', 'pods' ),
491
				'bidirectional' => true,
492
			);
493
494
			self::$related_objects['role'] = array(
495
				'label'         => __( 'User Roles', 'pods' ),
496
				'group'         => __( 'Other WP Objects', 'pods' ),
497
				'simple'        => true,
498
				'data_callback' => array( $this, 'data_roles' ),
499
			);
500
501
			self::$related_objects['capability'] = array(
502
				'label'         => __( 'User Capabilities', 'pods' ),
503
				'group'         => __( 'Other WP Objects', 'pods' ),
504
				'simple'        => true,
505
				'data_callback' => array( $this, 'data_capabilities' ),
506
			);
507
508
			self::$related_objects['media'] = array(
509
				'label'         => __( 'Media', 'pods' ),
510
				'group'         => __( 'Other WP Objects', 'pods' ),
511
				'bidirectional' => true,
512
			);
513
514
			self::$related_objects['comment'] = array(
515
				'label'         => __( 'Comments', 'pods' ),
516
				'group'         => __( 'Other WP Objects', 'pods' ),
517
				'bidirectional' => true,
518
			);
519
520
			self::$related_objects['image-size'] = array(
521
				'label'         => __( 'Image Sizes', 'pods' ),
522
				'group'         => __( 'Other WP Objects', 'pods' ),
523
				'simple'        => true,
524
				'data_callback' => array( $this, 'data_image_sizes' ),
525
			);
526
527
			self::$related_objects['nav_menu'] = array(
528
				'label' => __( 'Navigation Menus', 'pods' ),
529
				'group' => __( 'Other WP Objects', 'pods' ),
530
			);
531
532
			self::$related_objects['post_format'] = array(
533
				'label' => __( 'Post Formats', 'pods' ),
534
				'group' => __( 'Other WP Objects', 'pods' ),
535
			);
536
537
			self::$related_objects['post-status'] = array(
538
				'label'         => __( 'Post Status', 'pods' ),
539
				'group'         => __( 'Other WP Objects', 'pods' ),
540
				'simple'        => true,
541
				'data_callback' => array( $this, 'data_post_stati' ),
542
			);
543
544
			do_action( 'pods_form_ui_field_pick_related_objects_other' );
545
546
			self::$related_objects['country'] = array(
547
				'label'         => __( 'Countries', 'pods' ),
548
				'group'         => __( 'Predefined Lists', 'pods' ),
549
				'simple'        => true,
550
				'data_callback' => array( $this, 'data_countries' ),
551
			);
552
553
			self::$related_objects['us_state'] = array(
554
				'label'         => __( 'US States', 'pods' ),
555
				'group'         => __( 'Predefined Lists', 'pods' ),
556
				'simple'        => true,
557
				'data_callback' => array( $this, 'data_us_states' ),
558
			);
559
560
			self::$related_objects['days_of_week'] = array(
561
				'label'         => __( 'Calendar - Days of Week', 'pods' ),
562
				'group'         => __( 'Predefined Lists', 'pods' ),
563
				'simple'        => true,
564
				'data_callback' => array( $this, 'data_days_of_week' ),
565
			);
566
567
			self::$related_objects['months_of_year'] = array(
568
				'label'         => __( 'Calendar - Months of Year', 'pods' ),
569
				'group'         => __( 'Predefined Lists', 'pods' ),
570
				'simple'        => true,
571
				'data_callback' => array( $this, 'data_months_of_year' ),
572
			);
573
574
			do_action( 'pods_form_ui_field_pick_related_objects_predefined' );
575
576
			if ( did_action( 'init' ) ) {
577
				pods_transient_set( 'pods_related_objects', self::$related_objects );
578
			}
579
		}
580
581
		/**
582
		 * Allow custom related objects to be defined
583
		 */
584
		do_action( 'pods_form_ui_field_pick_related_objects_custom' );
585
586
		foreach ( self::$custom_related_objects as $object => $related_object ) {
587
			if ( ! isset( self::$related_objects[ $object ] ) ) {
588
				$new_data_loaded = true;
589
590
				self::$related_objects[ $object ] = $related_object;
591
			}
592
		}
593
594
		return $new_data_loaded;
595
596
	}
597
598
	/**
599
	 * Return available related objects
600
	 *
601
	 * @param boolean $force Whether to force refresh of related objects
602
	 *
603
	 * @return array Field selection array
604
	 * @since 2.3
605
	 */
606
	public function related_objects( $force = false ) {
607
608
		if ( $this->setup_related_objects( $force ) || null === self::$names_related ) {
609
			$related_objects = array();
610
611
			foreach ( self::$related_objects as $related_object_name => $related_object ) {
612
				if ( ! isset( $related_objects[ $related_object['group'] ] ) ) {
613
					$related_objects[ $related_object['group'] ] = array();
614
				}
615
616
				$related_objects[ $related_object['group'] ][ $related_object_name ] = $related_object['label'];
617
			}
618
619
			self::$names_related = (array) apply_filters( 'pods_form_ui_field_pick_related_objects', $related_objects );
620
		}
621
622
		return self::$names_related;
623
624
	}
625
626
	/**
627
	 * Return available simple object names
628
	 *
629
	 * @return array Simple object names
630
	 * @since 2.3
631
	 */
632 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...
633
634
		if ( $this->setup_related_objects() || null === self::$names_simple ) {
635
			$simple_objects = array();
636
637
			foreach ( self::$related_objects as $object => $related_object ) {
638
				if ( ! isset( $related_object['simple'] ) || ! $related_object['simple'] ) {
639
					continue;
640
				}
641
642
				$simple_objects[] = $object;
643
			}
644
645
			self::$names_simple = (array) apply_filters( 'pods_form_ui_field_pick_simple_objects', $simple_objects );
646
		}
647
648
		return self::$names_simple;
649
650
	}
651
652
	/**
653
	 * Return available bidirectional object names
654
	 *
655
	 * @return array Bidirectional object names
656
	 * @since 2.3.4
657
	 */
658 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...
659
660
		if ( $this->setup_related_objects() || null === self::$names_bidirectional ) {
661
			$bidirectional_objects = array();
662
663
			foreach ( self::$related_objects as $object => $related_object ) {
664
				if ( ! isset( $related_object['bidirectional'] ) || ! $related_object['bidirectional'] ) {
665
					continue;
666
				}
667
668
				$bidirectional_objects[] = $object;
669
			}
670
671
			self::$names_bidirectional = (array) apply_filters( 'pods_form_ui_field_pick_bidirectional_objects', $bidirectional_objects );
672
		}
673
674
		return self::$names_bidirectional;
675
676
	}
677
678
	/**
679
	 * {@inheritdoc}
680
	 */
681
	public function schema( $options = null ) {
682
683
		$schema = false;
684
685
		$simple_tableless_objects = $this->simple_objects();
686
687
		if ( in_array( pods_v( self::$type . '_object', $options ), $simple_tableless_objects, true ) ) {
688
			$schema = 'LONGTEXT';
689
		}
690
691
		return $schema;
692
693
	}
694
695
	/**
696
	 * {@inheritdoc}
697
	 */
698
	public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
699
700
		$fields = null;
701
702
		if ( is_object( $pod ) && isset( $pod->fields ) ) {
703
			/**
704
			 * @var $pod Pods
705
			 */
706
			$fields = $pod->fields;
707
708
			if ( ! empty( $pod->pod_data['object_fields'] ) ) {
709
				$fields = array_merge( $fields, $pod->pod_data['object_fields'] );
710
			}
711 View Code Duplication
		} elseif ( is_array( $pod ) && isset( $pod['fields'] ) ) {
712
			$fields = $pod['fields'];
713
714
			if ( ! empty( $pod['object_fields'] ) ) {
715
				$fields = array_merge( $fields, $pod['object_fields'] );
716
			}
717
		}
718
719
		return pods_serial_comma( $value, array( 'field' => $name, 'fields' => $fields ) );
720
721
	}
722
723
	/**
724
	 * {@inheritdoc}
725
	 */
726
	public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
727
728
		$options = (array) $options;
729
730
		$type = pods_v( 'type', $options, static::$type );
731
732
		$args = compact( array_keys( get_defined_vars() ) );
733
		$args = (object) $args;
734
735
		wp_enqueue_style( 'pods-dfv-list' );
736
		wp_enqueue_script( 'pods-dfv' );
737
738
		wp_enqueue_style( 'pods-select2' );
739
		wp_enqueue_script( 'pods-select2' );
740
741
		$this->render_input_script( $args );
742
743
		return;
744
745
		// @todo Support custom integrations.
746
		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...
747
		do_action( 'pods_form_ui_field_pick_input', pods_v( self::$type . '_format_type', $options, 'single' ), $name, $value, $options, $pod, $id );
748
749
		// @todo Support custom integrations.
750
		do_action( 'pods_form_ui_field_pick_input', pods_v( self::$type . '_format_type', $options, 'single' ), $name, $value, $options, $pod, $id );
751
752
	}
753
754
	/**
755
	 * {@inheritdoc}
756
	 */
757
	public function build_dfv_field_options( $options, $args ) {
758
759
		$options['grouped'] = 1;
760
761
		if ( empty( $options['pick_object'] ) ) {
762
			$options['pick_object'] = '';
763
		}
764
765
		if ( empty( $options['pick_val'] ) ) {
766
			$options['pick_val'] = '';
767
		}
768
769
		$options['table_info'] = array();
770
771
		$custom = pods_v( $args->type . '_custom', $options, false );
772
773
		$custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $args->name, $args->value, $options, $args->pod, $args->id );
774
775
		$ajax = false;
776
777
		if ( ( 'custom-simple' !== pods_v( $args->type . '_object', $options ) || empty( $custom ) ) && '' !== pods_v( $args->type . '_object', $options, '', true ) ) {
778
			$ajax = true;
779
		}
780
781
		if ( ! empty( self::$field_data ) && self::$field_data['id'] === $options['id'] ) {
782
			$ajax = (boolean) self::$field_data['autocomplete'];
783
		}
784
785
		$ajax = apply_filters( 'pods_form_ui_field_pick_ajax', $ajax, $args->name, $args->value, $options, $args->pod, $args->id );
786
787
		if ( 0 === (int) pods_v( $args->type . '_ajax', $options, 1 ) ) {
788
			$ajax = false;
789
		}
790
791
		$options[ $args->type . '_ajax' ] = (int) $ajax;
792
793
		$format_type = pods_v( $args->type . '_format_type', $options, 'single', true );
794
795
		if ( 'single' === $format_type ) {
796
			$format_single = pods_v( $args->type . '_format_single', $options, 'dropdown', true );
797
798 View Code Duplication
			if ( 'dropdown' === $format_single ) {
799
				$options['view_name'] = 'select';
800
			} elseif ( 'radio' === $format_single ) {
801
				$options['view_name'] = 'radio';
802
			} elseif ( 'autocomplete' === $format_single ) {
803
				$options['view_name'] = 'select2';
804
			} elseif ( 'list' === $format_single ) {
805
				$options['view_name'] = 'list';
806
			} else {
807
				$options['view_name'] = $format_single;
808
			}
809
		} elseif ( 'multi' === $format_type ) {
810
			$format_multi = pods_v( $args->type . '_format_multi', $options, 'checkbox', true );
811
812
			if ( ! empty( $args->value ) && ! is_array( $args->value ) ) {
813
				$args->value = explode( ',', $args->value );
814
			}
815
816 View Code Duplication
			if ( 'checkbox' === $format_multi ) {
817
				$options['view_name'] = 'checkbox';
818
			} elseif ( 'multiselect' === $format_multi ) {
819
				$options['view_name'] = 'select';
820
			} elseif ( 'autocomplete' === $format_multi ) {
821
				$options['view_name'] = 'select2';
822
			} elseif ( 'list' === $format_multi ) {
823
				$options['view_name'] = 'list';
824
			} else {
825
				$options['view_name'] = $format_multi;
826
			}
827
		} else {
828
			$options['view_name'] = $format_type;
829
		}
830
831
		return $options;
832
833
	}
834
835
	/**
836
	 * {@inheritdoc}
837
	 */
838
	public function build_dfv_field_config( $args ) {
839
840
		$config = parent::build_dfv_field_config( $args );
841
842
		if ( ! isset( $config['optgroup'] ) ) {
843
			$config['optgroup'] = false;
844
		}
845
846
		$file_name  = '';
847
		$query_args = array();
848
849
		// Set the file name and args based on the content type of the relationship
850
		switch ( $args->options['pick_object'] ) {
851
			case 'post_type':
852
				$file_name  = 'post-new.php';
853
				$query_args = array(
854
					'post_type' => $args->options['pick_val'],
855
				);
856
				// @todo Access rights for add new
857
				break;
858
859
			case 'taxonomy':
860
				$file_name  = 'edit-tags.php';
861
				$query_args = array(
862
					'taxonomy' => $args->options['pick_val'],
863
				);
864
				// @todo Access rights for add new
865
				break;
866
867
			case 'user':
868
				$file_name  = 'user-new.php';
869
				$query_args = array();
870
				// @todo Access rights for add new
871
				break;
872
873
			case 'pod':
874
				$file_name  = 'admin.php';
875
				$query_args = array(
876
					'page'   => 'pods-manage-' . $args->options['pick_val'],
877
					'action' => 'add',
878
				);
879
				// @todo Access rights for add new
880
				break;
881
		}
882
883
		$iframe_src = '';
884
885
		if ( ! empty( $file_name ) ) {
886
			// @todo: Replace string literal with defined constant
887
			$query_args['pods_modal'] = 1;
888
889
			// Add args we always need
890
			$iframe_src = add_query_arg( $query_args, admin_url( $file_name ) );
891
		}
892
893
		$config['iframe_src'] = $iframe_src;
894
895
		return $config;
896
897
	}
898
899
	/**
900
	 * {@inheritdoc}
901
	 */
902
	public function build_dfv_field_item_data( $args ) {
903
904
		$args->options['supports_thumbnails'] = null;
905
906
		$item_data = array();
907
908
		if ( ! empty( $args->options['data'] ) ) {
909
			$item_data = $this->build_dfv_field_item_data_recurse( $args->options['data'], $args );
910
		}
911
912
		return $item_data;
913
914
	}
915
916
	/**
917
	 * Loop through relationship data and expand item data with additional information for DFV.
918
	 *
919
	 * @param array     $data    Item data to expand.
920
	 * @param object    $args    {
921
	 *                           Field information arguments.
922
	 *
923
	 * @type string     $name    Field name
924
	 * @type string     $type    Field type
925
	 * @type array      $options Field options
926
	 * @type mixed      $value   Current value
927
	 * @type array      $pod     Pod information
928
	 * @type int|string $id      Current item ID
929
	 * }
930
	 *
931
	 * @return array
932
	 */
933
	public function build_dfv_field_item_data_recurse( $data, $args ) {
934
935
		$item_data = array();
936
937
		foreach ( $data as $item_id => $item_title ) {
938
			if ( is_array( $item_title ) ) {
939
				$args->options['optgroup'] = true;
940
941
				$item_data[] = array(
942
					'label'      => $item_id,
943
					'collection' => $this->build_dfv_field_item_data_recurse( $item_title, $args ),
944
				);
945
			} else {
946
				$item_data[] = $this->build_dfv_field_item_data_recurse_item( $item_id, $item_title, $args );
947
			}
948
		}
949
950
		return $item_data;
951
952
	}
953
954
	/**
955
	 * Loop through relationship data and expand item data with additional information for DFV.
956
	 *
957
	 * @param int|string $item_id
958
	 * @param string     $item_title
959
	 * @param object     $args    {
960
	 *                            Field information arguments.
961
	 *
962
	 * @type string      $name    Field name
963
	 * @type string      $type    Field type
964
	 * @type array       $options Field options
965
	 * @type mixed       $value   Current value
966
	 * @type array       $pod     Pod information
967
	 * @type int|string  $id      Current item ID
968
	 * }
969
	 *
970
	 * @return array
971
	 */
972
	public function build_dfv_field_item_data_recurse_item( $item_id, $item_title, $args ) {
973
974
		$icon      = '';
975
		$edit_link = '';
976
		$link      = '';
977
978
		switch ( $args->options['pick_object'] ) {
979
			case 'post_type':
980
				if ( null === $args->options['supports_thumbnails'] ) {
981
					$args->options['supports_thumbnails'] = post_type_supports( $args->options['pick_val'], 'thumbnail' );
982
				}
983
984
				if ( true === $args->options['supports_thumbnails'] ) {
985
					$thumb = wp_get_attachment_image_src( $item_id, 'thumbnail', true );
986
987
					if ( ! empty( $thumb[0] ) ) {
988
						$icon = $thumb[0];
989
					}
990
				}
991
992
				// @todo Access rights for edit link
993
				$edit_link = get_edit_post_link( $item_id, 'raw' );
994
995
				$link = get_permalink( $item_id );
996
997
				break;
998
999
			case 'taxonomy':
1000
				// @todo Access rights for edit link
1001
				$edit_link = get_edit_term_link( $item_id, $args->options['pick_val'] );
1002
1003
				$link = get_term_link( $item_id, $args->options['pick_val'] );
1004
1005
				break;
1006
1007
			case 'user':
1008
				$args->options['supports_thumbnails'] = true;
1009
1010
				$icon = get_avatar_url( $item_id, array( 'size' => 150 ) );
1011
1012
				// @todo Access rights for edit link
1013
				$edit_link = get_edit_user_link( $item_id );
1014
1015
				$link = get_author_posts_url( $item_id );
1016
1017
				break;
1018
1019
			case 'pod':
1020
				$file_name  = 'admin.php';
1021
				$query_args = array(
1022
					'page'   => 'pods-manage-' . $args->options['pick_val'],
1023
					'action' => 'edit',
1024
					'id'     => $item_id,
1025
				);
1026
1027
				// @todo Access rights for edit link
1028
				$edit_link = add_query_arg( $query_args, admin_url( $file_name ) );
1029
1030
				// @todo Add $link support
1031
				$link = '';
1032
1033
				break;
1034
		}
1035
1036
		$item = array(
1037
			'id'        => $item_id,
1038
			'icon'      => $icon,
1039
			'name'      => $item_title,
1040
			'edit_link' => $edit_link,
1041
			'link'      => $link,
1042
			'selected'  => ( isset( $args->value[ $item_id ] ) ),
1043
		);
1044
1045
		return $item;
1046
1047
	}
1048
1049
	/**
1050
	 * {@inheritdoc}
1051
	 */
1052
	public function validate( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
1053
1054
		if ( empty( self::$api ) ) {
1055
			self::$api = pods_api();
1056
		}
1057
1058
		$simple_tableless_objects = $this->simple_objects();
1059
1060
		$related_pick_limit = 0;
1061
		$related_field      = $related_pod = $current_related_ids = false;
1062
1063
		// Bidirectional relationship requirement checks
1064
		$related_object = pods_v( self::$type . '_object', $options, '' ); // pod, post_type, taxonomy, etc..
1065
		$related_val    = pods_v( self::$type . '_val', $options, $related_object, null, true ); // pod name, post type name, taxonomy name, etc..
1066
		if ( empty( $related_val ) ) {
1067
			$related_val = $related_object;
1068
		}
1069
1070
		$related_sister_id = (int) pods_v( 'sister_id', $options, 0 );
1071
1072
		$options['id'] = (int) $options['id'];
1073
1074
		if ( ! isset( self::$related_data[ $options['id'] ] ) || empty( self::$related_data[ $options['id'] ] ) ) {
1075
			self::$related_data[ $options['id'] ] = array();
1076
		}
1077
1078
		if ( ! empty( $related_sister_id ) && ! in_array( $related_object, $simple_tableless_objects, true ) ) {
1079
			$related_pod = self::$api->load_pod( array( 'name' => $related_val, 'table_info' => false ), false );
1080
1081
			if ( false !== $related_pod && ( 'pod' === $related_object || $related_object === $related_pod['type'] ) ) {
1082
				$related_field = false;
1083
1084
				// Ensure sister_id exists on related Pod.
1085 View Code Duplication
				foreach ( $related_pod['fields'] as $related_pod_field ) {
1086
					if ( 'pick' === $related_pod_field['type'] && $related_sister_id === $related_pod_field['id'] ) {
1087
						$related_field = $related_pod_field;
1088
1089
						break;
1090
					}
1091
				}
1092
1093
				if ( ! empty( $related_field ) ) {
1094
					$current_ids = self::$api->lookup_related_items( $fields[ $name ]['id'], $pod['id'], $id, $fields[ $name ], $pod );
1095
1096
					self::$related_data[ $options['id'] ]['current_ids'] = $current_ids;
1097
1098
					$value_ids = $value;
1099
1100
					// Convert values from a comma-separated string into an array.
1101
					if ( ! is_array( $value_ids ) ) {
1102
						$value_ids = explode( ',', $value_ids );
1103
					}
1104
1105
					$value_ids = array_unique( array_filter( $value_ids ) );
1106
1107
					// Get ids to remove.
1108
					$remove_ids = array_diff( $current_ids, $value_ids );
1109
1110
					$related_required   = (boolean) pods_v( 'required', $related_field['options'], 0 );
1111
					$related_pick_limit = (int) pods_v( self::$type . '_limit', $related_field['options'], 0 );
1112
1113
					if ( 'single' === pods_v( self::$type . '_format_type', $related_field['options'] ) ) {
1114
						$related_pick_limit = 1;
1115
					}
1116
1117
					// Validate Required fields.
1118
					if ( $related_required && ! empty( $remove_ids ) ) {
1119
						foreach ( $remove_ids as $related_id ) {
1120
							$bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod );
1121
1122
							self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] = $bidirectional_ids;
1123
1124
							if ( empty( $bidirectional_ids ) || ( in_array( (int) $id, $bidirectional_ids, true ) && 1 === count( $bidirectional_ids ) ) ) {
1125
								return sprintf( __( 'The %1$s field is required and cannot be removed by the %2$s field', 'pods' ), $related_field['label'], $options['label'] );
1126
							}
1127
						}
1128
					}
1129
				} else {
1130
					$related_pod = false;
1131
				}
1132
			} else {
1133
				$related_pod = false;
1134
			}
1135
		}
1136
1137
		if ( empty( self::$related_data[ $options['id'] ] ) ) {
1138
			unset( self::$related_data[ $options['id'] ] );
1139
		} else {
1140
			self::$related_data[ $options['id'] ]['related_pod']        = $related_pod;
1141
			self::$related_data[ $options['id'] ]['related_field']      = $related_field;
1142
			self::$related_data[ $options['id'] ]['related_pick_limit'] = $related_pick_limit;
1143
1144
			$pick_limit = (int) pods_v( self::$type . '_limit', $options['options'], 0 );
1145
1146
			if ( 'single' === pods_v( self::$type . '_format_type', $options['options'] ) ) {
1147
				$pick_limit = 1;
1148
			}
1149
1150
			$related_field['id'] = (int) $related_field['id'];
1151
1152
			if ( ! isset( self::$related_data[ $related_field['id'] ] ) || empty( self::$related_data[ $related_field['id'] ] ) ) {
1153
				self::$related_data[ $related_field['id'] ] = array(
1154
					'related_pod'        => $pod,
1155
					'related_field'      => $options,
1156
					'related_pick_limit' => $pick_limit,
1157
				);
1158
			}
1159
		}
1160
1161
		return true;
1162
1163
	}
1164
1165
	/**
1166
	 * {@inheritdoc}
1167
	 */
1168
	public function save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
1169
1170
		if ( empty( self::$api ) ) {
1171
			self::$api = pods_api();
1172
		}
1173
1174
		$options['id'] = (int) $options['id'];
1175
1176
		if ( ! isset( self::$related_data[ $options['id'] ] ) ) {
1177
			return;
1178
		}
1179
1180
		$related_pod        = self::$related_data[ $options['id'] ]['related_pod'];
1181
		$related_field      = self::$related_data[ $options['id'] ]['related_field'];
1182
		$related_pick_limit = self::$related_data[ $options['id'] ]['related_pick_limit'];
1183
1184
		// Bidirectional relationship updates.
1185
		if ( ! empty( $related_field ) ) {
1186
			// Don't use no conflict mode unless this isn't the current pod type.
1187
			$no_conflict = true;
1188
1189
			if ( $related_pod['type'] !== $pod['type'] ) {
1190
				$no_conflict = pods_no_conflict_check( $related_pod['type'] );
1191
			}
1192
1193
			if ( ! $no_conflict ) {
1194
				pods_no_conflict_on( $related_pod['type'] );
1195
			}
1196
1197
			$value = array_filter( $value );
1198
1199
			foreach ( $value as $related_id ) {
1200
				if ( isset( self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] ) && ! empty( self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] ) ) {
1201
					$bidirectional_ids = self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ];
1202
				} else {
1203
					$bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod );
1204
				}
1205
1206
				$bidirectional_ids = array_filter( $bidirectional_ids );
1207
1208
				if ( empty( $bidirectional_ids ) ) {
1209
					$bidirectional_ids = array();
1210
				}
1211
1212
				$remove_ids = array();
1213
1214
				if ( 0 < $related_pick_limit && ! empty( $bidirectional_ids ) && ! in_array( $id, $bidirectional_ids, true ) ) {
1215
					while ( $related_pick_limit <= count( $bidirectional_ids ) ) {
1216
						$remove_ids[] = (int) array_pop( $bidirectional_ids );
1217
					}
1218
				}
1219
1220
				// Remove this item from related items no longer related to.
1221
				$remove_ids = array_unique( array_filter( $remove_ids ) );
1222
1223
				if ( ! in_array( $id, $bidirectional_ids, true ) ) {
1224
					// Add to related items.
1225
					$bidirectional_ids[] = $id;
1226
				} elseif ( empty( $remove_ids ) ) {
1227
					// Nothing to change.
1228
					continue;
1229
				}
1230
1231
				self::$api->save_relationships( $related_id, $bidirectional_ids, $related_pod, $related_field );
1232
1233
				if ( ! empty( $remove_ids ) ) {
1234
					self::$api->delete_relationships( $remove_ids, $related_id, $pod, $options );
1235
				}
1236
			}
1237
1238
			if ( ! $no_conflict ) {
1239
				pods_no_conflict_off( $related_pod['type'] );
1240
			}
1241
		}
1242
1243
	}
1244
1245
	/**
1246
	 * Delete the value from the DB
1247
	 *
1248
	 * @param int    $id
1249
	 * @param string $name
1250
	 * @param array  $options
1251
	 * @param array  $pod
1252
	 *
1253
	 * @since 2.3
1254
	 */
1255
	public function delete( $id = null, $name = null, $options = null, $pod = null ) {
1256
1257
		if ( empty( self::$api ) ) {
1258
			self::$api = pods_api();
1259
		}
1260
1261
		$simple_tableless_objects = $this->simple_objects();
1262
1263
		// Bidirectional relationship requirement checks.
1264
		$related_object    = pods_v( self::$type . '_object', $options, '' ); // pod, post_type, taxonomy, etc..
1265
		$related_val       = pods_v( self::$type . '_val', $options, $related_object, true ); // pod name, post type name, taxonomy name, etc..
1266
		$related_sister_id = (int) pods_v( 'sister_id', $options, 0 );
1267
1268
		if ( ! empty( $related_sister_id ) && ! in_array( $related_object, $simple_tableless_objects, true ) ) {
1269
			$related_pod = self::$api->load_pod( array( 'name' => $related_val, 'table_info' => false ), false );
1270
1271
			if ( false !== $related_pod && ( 'pod' === $related_object || $related_object === $related_pod['type'] ) ) {
1272
				$related_field = false;
1273
1274
				// Ensure sister_id exists on related Pod.
1275 View Code Duplication
				foreach ( $related_pod['fields'] as $related_pod_field ) {
1276
					if ( 'pick' === $related_pod_field['type'] && (int) $related_sister_id === (int) $related_pod_field['id'] ) {
1277
						$related_field = $related_pod_field;
1278
1279
						break;
1280
					}
1281
				}
1282
1283
				if ( ! empty( $related_field ) ) {
1284
					$values = self::$api->lookup_related_items( $options['id'], $pod['id'], $id, $options, $pod );
1285
1286
					if ( ! empty( $values ) ) {
1287
						$no_conflict = pods_no_conflict_check( $related_pod['type'] );
1288
1289
						if ( ! $no_conflict ) {
1290
							pods_no_conflict_on( $related_pod['type'] );
1291
						}
1292
1293
						self::$api->delete_relationships( $values, $id, $related_pod, $related_field );
1294
1295
						if ( ! $no_conflict ) {
1296
							pods_no_conflict_off( $related_pod['type'] );
1297
						}
1298
					}
1299
				}
1300
			}
1301
		}
1302
1303
	}
1304
1305
	/**
1306
	 * {@inheritdoc}
1307
	 */
1308
	public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) {
1309
1310
		$value = $this->simple_value( $name, $value, $options, $pod, $id );
1311
1312
		return $this->display( $value, $name, $options, $pod, $id );
1313
1314
	}
1315
1316
	/**
1317
	 * Get the data from the field
1318
	 *
1319
	 * @param string       $name    The name of the field
1320
	 * @param string|array $value   The value of the field
1321
	 * @param array        $options Field options
1322
	 * @param array        $pod     Pod data
1323
	 * @param int          $id      Item ID
1324
	 * @param boolean      $in_form
1325
	 *
1326
	 * @return array Array of possible field data
1327
	 *
1328
	 * @since 2.0
1329
	 */
1330
	public function data( $name, $value = null, $options = null, $pod = null, $id = null, $in_form = true ) {
1331
1332 View Code Duplication
		if ( isset( $options['options'] ) ) {
1333
			$options = array_merge( $options, $options['options'] );
1334
1335
			unset( $options['options'] );
1336
		}
1337
1338
		$data = pods_v( 'data', $options, null, true );
1339
1340
		$object_params = array(
1341
			'name'    => $name, // The name of the field.
1342
			'value'   => $value, // The value of the field.
1343
			'options' => $options, // Field options.
1344
			'pod'     => $pod, // Pod data.
1345
			'id'      => $id, // Item ID.
1346
			'context' => 'data', // Data context.
1347
		);
1348
1349
		if ( null !== $data ) {
1350
			$data = (array) $data;
1351
		} else {
1352
			$data = $this->get_object_data( $object_params );
1353
		}
1354
1355
		if ( 'single' === pods_v( self::$type . '_format_type', $options, 'single' ) && 'dropdown' === pods_v( self::$type . '_format_single', $options, 'dropdown' ) ) {
1356
			$data = array( '' => pods_v( self::$type . '_select_text', $options, __( '-- Select One --', 'pods' ), true ) ) + $data;
1357
		}
1358
1359
		$data = apply_filters( 'pods_field_pick_data', $data, $name, $value, $options, $pod, $id );
1360
1361
		return $data;
1362
1363
	}
1364
1365
	/**
1366
	 * Convert a simple value to the correct value
1367
	 *
1368
	 * @param string       $name    The name of the field
1369
	 * @param string|array $value   The value of the field
1370
	 * @param array        $options Field options
1371
	 * @param array        $pod     Pod data
1372
	 * @param int          $id      Item ID
1373
	 * @param boolean      $raw     Whether to return the raw list of keys (true) or convert to key=>value (false)
1374
	 *
1375
	 * @return mixed Corrected value
1376
	 */
1377
	public function simple_value( $name, $value = null, $options = null, $pod = null, $id = null, $raw = false ) {
1378
1379
		if ( in_array( pods_v( self::$type . '_object', $options ), self::simple_objects(), true ) ) {
1380 View Code Duplication
			if ( isset( $options['options'] ) ) {
1381
				$options = array_merge( $options, $options['options'] );
1382
1383
				unset( $options['options'] );
1384
			}
1385
1386
			if ( ! is_array( $value ) && 0 < strlen( $value ) ) {
1387
				$simple = @json_decode( $value, true );
1388
1389
				if ( is_array( $simple ) ) {
1390
					$value = $simple;
1391
				}
1392
			}
1393
1394
			$data = pods_v( 'data', $options, null, true );
1395
1396
			$object_params = array(
1397
				'name'    => $name, // The name of the field.
1398
				'value'   => $value, // The value of the field.
1399
				'options' => $options, // Field options.
1400
				'pod'     => $pod, // Pod data.
1401
				'id'      => $id, // Item ID.
1402
				'context' => 'simple_value', // Data context.
1403
			);
1404
1405
			if ( null === $data ) {
1406
				$data = $this->get_object_data( $object_params );
1407
			}
1408
1409
			$data = (array) $data;
1410
1411
			$key = 0;
1412
1413
			if ( is_array( $value ) ) {
1414
				if ( ! empty( $data ) ) {
1415
					$val = array();
1416
1417
					foreach ( $value as $k => $v ) {
1418
						if ( isset( $data[ $v ] ) ) {
1419
							if ( false === $raw ) {
1420
								$k = $v;
1421
								$v = $data[ $v ];
1422
							}
1423
1424
							$val[ $k ] = $v;
1425
						}
1426
					}
1427
1428
					$value = $val;
1429
				}
1430
			} elseif ( isset( $data[ $value ] ) && false === $raw ) {
1431
				$key   = $value;
1432
				$value = $data[ $value ];
1433
			}
1434
1435
			$single_multi = pods_v( self::$type . '_format_type', $options, 'single' );
1436
1437
			if ( 'multi' === $single_multi ) {
1438
				$limit = (int) pods_v( self::$type . '_limit', $options, 0 );
1439
			} else {
1440
				$limit = 1;
1441
			}
1442
1443
			if ( is_array( $value ) && 0 < $limit ) {
1444
				if ( 1 === $limit ) {
1445
					$value = current( $value );
1446
				} else {
1447
					$value = array_slice( $value, 0, $limit, true );
1448
				}
1449
			} elseif ( ! is_array( $value ) && null !== $value && 0 < strlen( $value ) ) {
1450
				if ( 1 !== $limit || ( true === $raw && 'multi' === $single_multi ) ) {
1451
					$value = array(
1452
						$key => $value,
1453
					);
1454
				}
1455
			}
1456
		}
1457
1458
		return $value;
1459
1460
	}
1461
1462
	/**
1463
	 * Get the label from a pick value
1464
	 *
1465
	 * @param string       $name    The name of the field
1466
	 * @param string|array $value   The value of the field
1467
	 * @param array        $options Field options
1468
	 * @param array        $pod     Pod data
1469
	 * @param int          $id      Item ID
1470
	 *
1471
	 * @return string
1472
	 *
1473
	 * @since 2.2
1474
	 */
1475
	public function value_to_label( $name, $value = null, $options = null, $pod = null, $id = null ) {
1476
1477 View Code Duplication
		if ( isset( $options['options'] ) ) {
1478
			$options = array_merge( $options, $options['options'] );
1479
1480
			unset( $options['options'] );
1481
		}
1482
1483
		$data = pods_v( 'data', $options, null, true );
1484
1485
		$object_params = array(
1486
			'name'    => $name, // The name of the field.
1487
			'value'   => $value, // The value of the field.
1488
			'options' => $options, // Field options.
1489
			'pod'     => $pod, // Pod data.
1490
			'id'      => $id, // Item ID.
1491
			'context' => 'value_to_label', // Data context.
1492
		);
1493
1494
		if ( null !== $data ) {
1495
			$data = (array) $data;
1496
		} else {
1497
			$data = $this->get_object_data( $object_params );
1498
		}
1499
1500
		$labels = array();
1501
1502
		$check_value = $value;
1503
1504
		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...
1505
			$check_v = (string) $check_v;
1506
		}
1507
1508
		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...
1509
			if ( ! in_array( (string) $l, $labels, true ) && ( (string) $value === (string) $v || ( is_array( $value ) && in_array( (string) $v, $value, true ) ) ) ) {
1510
				$labels[] = (string) $l;
1511
			}
1512
		}
1513
1514
		$labels = apply_filters( 'pods_field_pick_value_to_label', $labels, $name, $value, $options, $pod, $id );
1515
1516
		$labels = pods_serial_comma( $labels );
1517
1518
		return $labels;
1519
1520
	}
1521
1522
	/**
1523
	 * Get available items from a relationship field
1524
	 *
1525
	 * @param array|string $field         Field array or field name
1526
	 * @param array        $options       [optional] Field options array overrides
1527
	 * @param array        $object_params [optional] Additional get_object_data options
1528
	 *
1529
	 * @return array An array of available items from a relationship field
1530
	 */
1531
	public function get_field_data( $field, $options = array(), $object_params = array() ) {
1532
1533
		// Handle field array overrides.
1534
		if ( is_array( $field ) ) {
1535
			$options = array_merge( $field, $options );
1536
		}
1537
1538
		// Get field name from array.
1539
		$field = pods_v( 'name', $options, $field, true );
1540
1541
		// Field name or options not set.
1542
		if ( empty( $field ) || empty( $options ) ) {
1543
			return array();
1544
		}
1545
1546
		// Options normalization.
1547
		$options = array_merge( $options, pods_v( 'options', $options, array(), true ) );
1548
1549
		// Setup object params.
1550
		$object_params = array_merge( array(
1551
			'name'    => $field, // The name of the field.
1552
			'options' => $options, // Field options.
1553
		), $object_params );
1554
1555
		// Get data override.
1556
		$data = pods_v( 'data', $options, null, true );
1557
1558
		if ( null !== $data ) {
1559
			// Return data override.
1560
			$data = (array) $data;
1561
		} else {
1562
			// Get object data.
1563
			$data = $this->get_object_data( $object_params );
1564
		}
1565
1566
		return $data;
1567
1568
	}
1569
1570
	/**
1571
	 * Get data from relationship objects
1572
	 *
1573
	 * @param array $object_params Object data parameters
1574
	 *
1575
	 * @return array|bool Object data
1576
	 */
1577
	public function get_object_data( $object_params = null ) {
1578
1579
		/**
1580
		 * @var $wpdb wpdb
1581
		 */
1582
		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...
1583
1584
		$object_params = array_merge( array(
1585
			// The name of the field.
1586
			'name'        => '',
1587
			// The value of the field.
1588
			'value'       => '',
1589
			// Field options.
1590
			'options'     => array(),
1591
			// Pod data.
1592
			'pod'         => '',
1593
			// Item ID.
1594
			'id'          => '',
1595
			// Data context.
1596
			'context'     => '',
1597
			// Data parameters.
1598
			'data_params' => array(
1599
				'query' => '', // Query being searched.
1600
			),
1601
			// Page number of results to get.
1602
			'page'        => 1,
1603
			// How many data items to limit to (autocomplete defaults to 30, set to -1 or 1+ to override).
1604
			'limit'       => 0,
1605
		), $object_params );
1606
1607
		$name        = $object_params['name'];
1608
		$value       = $object_params['value'];
1609
		$options     = $object_params['options'] = (array) $object_params['options'];
1610
		$pod         = $object_params['pod'];
1611
		$id          = $object_params['id'];
1612
		$context     = $object_params['context'];
1613
		$data_params = $object_params['data_params'] = (array) $object_params['data_params'];
1614
		$page        = min( 1, (int) $object_params['page'] );
1615
		$limit       = (int) $object_params['limit'];
1616
1617 View Code Duplication
		if ( isset( $options['options'] ) ) {
1618
			$options = array_merge( $options, $options['options'] );
1619
1620
			unset( $options['options'] );
1621
		}
1622
1623
		$data  = apply_filters( 'pods_field_pick_object_data', null, $name, $value, $options, $pod, $id, $object_params );
1624
		$items = array();
1625
1626
		if ( ! isset( $options[ self::$type . '_object' ] ) ) {
1627
			$data = pods_v( 'data', $options, array(), true );
1628
		}
1629
1630
		$simple = false;
1631
1632
		if ( null === $data ) {
1633
			$data = array();
1634
1635
			if ( 'custom-simple' === $options[ self::$type . '_object' ] ) {
1636
				$custom = pods_v( self::$type . '_custom', $options, '' );
1637
1638
				$custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $name, $value, $options, $pod, $id, $object_params );
1639
1640
				if ( ! empty( $custom ) ) {
1641
					if ( ! is_array( $custom ) ) {
1642
						$data = array();
1643
1644
						$custom = explode( "\n", trim( $custom ) );
1645
1646
						foreach ( $custom as $custom_value ) {
1647
							$custom_label = explode( '|', $custom_value );
1648
1649
							if ( empty( $custom_label ) ) {
1650
								continue;
1651
							}
1652
1653
							if ( 1 === count( $custom_label ) ) {
1654
								$custom_label = $custom_value;
1655
							} else {
1656
								$custom_value = $custom_label[0];
1657
								$custom_label = $custom_label[1];
1658
							}
1659
1660
							$custom_value = trim( (string) $custom_value );
1661
							$custom_label = trim( (string) $custom_label );
1662
1663
							$data[ $custom_value ] = $custom_label;
1664
						}
1665
					} else {
1666
						$data = $custom;
1667
					}
1668
1669
					$simple = true;
1670
				}
1671
			} 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'] ) ) {
1672
				$data = self::$related_objects[ $options[ self::$type . '_object' ] ]['data'];
1673
1674
				$simple = true;
1675
			} 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'] ) ) {
1676
				$data = call_user_func_array( self::$related_objects[ $options[ self::$type . '_object' ] ]['data_callback'], array(
1677
						$name,
1678
						$value,
1679
						$options,
1680
						$pod,
1681
						$id,
1682
					)
1683
				);
1684
1685 View Code Duplication
				if ( 'data' === $context ) {
1686
					self::$field_data = array(
1687
						'field'        => $name,
1688
						'id'           => $options['id'],
1689
						'autocomplete' => false,
1690
					);
1691
				}
1692
1693
				$simple = true;
1694
1695
				// Cache data from callback.
1696
				if ( ! empty( $data ) ) {
1697
					self::$related_objects[ $options[ self::$type . '_object' ] ]['data'] = $data;
1698
				}
1699
			} elseif ( 'simple_value' !== $context ) {
1700
				$pick_val = pods_v( self::$type . '_val', $options );
1701
1702
				if ( 'table' === pods_v( self::$type . '_object', $options ) ) {
1703
					$pick_val = pods_v( self::$type . '_table', $options, $pick_val, true );
1704
				}
1705
1706 View Code Duplication
				if ( '__current__' === $pick_val ) {
1707
					if ( is_object( $pod ) ) {
1708
						$pick_val = $pod->pod;
1709
					} elseif ( is_array( $pod ) ) {
1710
						$pick_val = $pod['name'];
1711
					} elseif ( 0 < strlen( $pod ) ) {
1712
						$pick_val = $pod;
1713
					}
1714
				}
1715
1716
				$options['table_info'] = pods_api()->get_table_info( pods_v( self::$type . '_object', $options ), $pick_val, null, null, $options );
1717
1718
				$search_data = pods_data();
1719
				$search_data->table( $options['table_info'] );
1720
1721
				if ( isset( $options['table_info']['pod'] ) && ! empty( $options['table_info']['pod'] ) && isset( $options['table_info']['pod']['name'] ) ) {
1722
					$search_data->pod    = $options['table_info']['pod']['name'];
1723
					$search_data->fields = $options['table_info']['pod']['fields'];
1724
				}
1725
1726
				$params = array(
1727
					'select'     => "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`",
1728
					'table'      => $search_data->table,
1729
					'where'      => pods_v( self::$type . '_where', $options, (array) $options['table_info']['where_default'], true ),
1730
					'orderby'    => pods_v( self::$type . '_orderby', $options, null, true ),
1731
					'groupby'    => pods_v( self::$type . '_groupby', $options, null, true ),
1732
					// '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...
1733
					'pagination' => false,
1734
					'search'     => false
1735
				);
1736
1737
				if ( in_array( $options[ self::$type . '_object' ], array( 'site', 'network' ), true ) ) {
1738
					$params['select'] .= ', `t`.`path`';
1739
				}
1740
1741
				if ( ! empty( $params['where'] ) && (array) $options['table_info']['where_default'] !== $params['where'] ) {
1742
					$params['where'] = pods_evaluate_tags( $params['where'], true );
1743
				}
1744
1745
				if ( empty( $params['where'] ) || ( ! is_array( $params['where'] ) && strlen( trim( $params['where'] ) ) < 1 ) ) {
1746
					$params['where'] = array();
1747
				} elseif ( ! is_array( $params['where'] ) ) {
1748
					$params['where'] = (array) $params['where'];
1749
				}
1750
1751
				if ( 'value_to_label' === $context ) {
1752
					$params['where'][] = "`t`.`{$search_data->field_id}` = " . number_format( $value, 0, '', '' );
1753
				}
1754
1755
				/*
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...
1756
				if ( ! empty( $params['orderby'] ) ) {
1757
					$params['orderby'] = pods_evaluate_tags( $params['orderby'], true );
1758
				}
1759
1760
				if ( ! empty( $params['groupby'] ) ) {
1761
					$params['groupby'] = pods_evaluate_tags( $params['groupby'], true );
1762
				}
1763
				*/
1764
1765
				$display = trim( pods_v( self::$type . '_display', $options ), ' {@}' );
1766
1767
				if ( 0 < strlen( $display ) ) {
1768
					if ( isset( $options['table_info']['pod'] ) && ! empty( $options['table_info']['pod'] ) ) {
1769
						if ( isset( $options['table_info']['pod']['object_fields'] ) && isset( $options['table_info']['pod']['object_fields'][ $display ] ) ) {
1770
							$search_data->field_index = $display;
1771
1772
							$params['select'] = "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`";
1773
						} elseif ( isset( $options['table_info']['pod']['fields'][ $display ] ) ) {
1774
							$search_data->field_index = $display;
1775
1776
							if ( 'table' === $options['table_info']['pod']['storage'] && ! in_array( $options['table_info']['pod']['type'], array(
1777
									'pod',
1778
									'table',
1779
								), true )
1780
							) {
1781
								$params['select'] = "`t`.`{$search_data->field_id}`, `d`.`{$search_data->field_index}`";
1782
							} elseif ( 'meta' === $options['table_info']['pod']['storage'] ) {
1783
								$params['select'] = "`t`.`{$search_data->field_id}`, `{$search_data->field_index}`.`meta_value` AS {$search_data->field_index}";
1784
							} else {
1785
								$params['select'] = "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`";
1786
							}
1787
						}
1788
					} elseif ( isset( $options['table_info']['object_fields'] ) && isset( $options['table_info']['object_fields'][ $display ] ) ) {
1789
						$search_data->field_index = $display;
1790
1791
						$params['select'] = "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`";
1792
					}
1793
				}
1794
1795
				$autocomplete = false;
1796
1797
				if ( 'single' === pods_v( self::$type . '_format_type', $options, 'single' ) && 'autocomplete' === pods_v( self::$type . '_format_single', $options, 'dropdown' ) ) {
1798
					$autocomplete = true;
1799
				} elseif ( 'multi' === pods_v( self::$type . '_format_type', $options, 'single' ) && 'autocomplete' === pods_v( self::$type . '_format_multi', $options, 'checkbox' ) ) {
1800
					$autocomplete = true;
1801
				}
1802
1803
				$hierarchy = false;
1804
1805
				if ( 'data' === $context && ! $autocomplete ) {
1806
					if ( 'single' === pods_v( self::$type . '_format_type', $options, 'single' ) && in_array( pods_v( self::$type . '_format_single', $options, 'dropdown' ), array(
1807
							'dropdown',
1808
							'radio',
1809
						), true )
1810
					) {
1811
						$hierarchy = true;
1812
					} elseif ( 'multi' === pods_v( self::$type . '_format_type', $options, 'single' ) && in_array( pods_v( self::$type . '_format_multi', $options, 'checkbox' ), array(
1813
							'multiselect',
1814
							'checkbox',
1815
						), true )
1816
					) {
1817
						$hierarchy = true;
1818
					}
1819
				}
1820
1821
				if ( $hierarchy && $options['table_info']['object_hierarchical'] && ! empty( $options['table_info']['field_parent'] ) ) {
1822
					$params['select'] .= ', ' . $options['table_info']['field_parent_select'];
1823
				}
1824
1825
				if ( $autocomplete ) {
1826
					if ( 0 === $limit ) {
1827
						$limit = 30;
1828
					}
1829
1830
					$params['limit'] = apply_filters( 'pods_form_ui_field_pick_autocomplete_limit', $limit, $name, $value, $options, $pod, $id, $object_params );
1831
1832
					if ( is_array( $value ) && $params['limit'] < count( $value ) ) {
1833
						$params['limit'] = count( $value );
1834
					}
1835
1836
					$params['page'] = $page;
1837
1838
					if ( 'admin_ajax_relationship' === $context ) {
1839
						$lookup_where = array(
1840
							$search_data->field_index => "`t`.`{$search_data->field_index}` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'",
1841
						);
1842
1843
						// @todo Hook into WPML for each table
1844
						if ( $wpdb->users === $search_data->table ) {
1845
							$lookup_where['display_name'] = "`t`.`display_name` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1846
							$lookup_where['user_login']   = "`t`.`user_login` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1847
							$lookup_where['user_email']   = "`t`.`user_email` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1848
						} elseif ( $wpdb->posts === $search_data->table ) {
1849
							$lookup_where['post_title']   = "`t`.`post_title` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1850
							$lookup_where['post_name']    = "`t`.`post_name` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1851
							$lookup_where['post_content'] = "`t`.`post_content` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1852
							$lookup_where['post_excerpt'] = "`t`.`post_excerpt` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1853
						} elseif ( $wpdb->terms === $search_data->table ) {
1854
							$lookup_where['name'] = "`t`.`name` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1855
							$lookup_where['slug'] = "`t`.`slug` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1856
						} elseif ( $wpdb->comments === $search_data->table ) {
1857
							$lookup_where['comment_content']      = "`t`.`comment_content` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1858
							$lookup_where['comment_author']       = "`t`.`comment_author` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1859
							$lookup_where['comment_author_email'] = "`t`.`comment_author_email` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%'";
1860
						}
1861
1862
						$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 );
1863
1864
						if ( ! empty( $lookup_where ) ) {
1865
							$params['where'][] = implode( ' OR ', $lookup_where );
1866
						}
1867
1868
						$orderby   = array();
1869
						$orderby[] = "(`t`.`{$search_data->field_index}` LIKE '%" . pods_sanitize_like( $data_params['query'] ) . "%' ) DESC";
1870
1871
						$pick_orderby = pods_v( self::$type . '_orderby', $options, null, true );
1872
1873
						if ( 0 < strlen( $pick_orderby ) ) {
1874
							$orderby[] = $pick_orderby;
1875
						}
1876
1877
						$orderby[] = "`t`.`{$search_data->field_index}`";
1878
						$orderby[] = "`t`.`{$search_data->field_id}`";
1879
1880
						$params['orderby'] = $orderby;
1881
					}
1882
				} elseif ( 0 < $limit ) {
1883
					$params['limit'] = $limit;
1884
					$params['page']  = $page;
1885
				}
1886
1887
				$extra = '';
1888
1889
				if ( $wpdb->posts === $search_data->table ) {
1890
					$extra = ', `t`.`post_type`';
1891
				} elseif ( $wpdb->terms === $search_data->table ) {
1892
					$extra = ', `tt`.`taxonomy`';
1893
				} elseif ( $wpdb->comments === $search_data->table ) {
1894
					$extra = ', `t`.`comment_type`';
1895
				}
1896
1897
				$params['select'] .= $extra;
1898
1899
				if ( 'user' === pods_v( self::$type . '_object', $options ) ) {
1900
					$roles = pods_v( self::$type . '_user_role', $options );
1901
1902
					if ( ! empty( $roles ) ) {
1903
						$where = array();
1904
1905
						foreach ( (array) $roles as $role ) {
1906
							if ( empty( $role ) || ( pods_clean_name( $role ) !== $role && sanitize_title( $role ) !== $role ) ) {
1907
								continue;
1908
							}
1909
1910
							$where[] = $wpdb->base_prefix . ( ( is_multisite() && ! is_main_site() ) ? get_current_blog_id() . '_' : '' ) . 'capabilities.meta_value LIKE "%\"' . pods_sanitize_like( $role ) . '\"%"';
1911
						}
1912
1913
						if ( ! empty( $where ) ) {
1914
							$params['where'][] = implode( ' OR ', $where );
1915
						}
1916
					}
1917
				}
1918
1919
				$results = $search_data->select( $params );
1920
1921
				if ( $autocomplete && $params['limit'] < $search_data->total_found() ) {
1922
					if ( ! empty( $value ) ) {
1923
						$ids = $value;
1924
1925
						if ( is_array( $ids ) && isset( $ids[0] ) && is_array( $ids[0] ) ) {
1926
							$ids = wp_list_pluck( $ids, $search_data->field_id );
1927
						}
1928
1929
						if ( is_array( $ids ) ) {
1930
							$ids = implode( ', ', $ids );
1931
						}
1932
1933
						if ( is_array( $params['where'] ) ) {
1934
							$params['where'] = implode( ' AND ', $params['where'] );
1935
						}
1936
						if ( ! empty( $params['where'] ) ) {
1937
							$params['where'] .= ' AND ';
1938
						}
1939
1940
						$params['where'] .= "`t`.`{$search_data->field_id}` IN ( {$ids} )";
1941
1942
						$results = $search_data->select( $params );
1943
					}
1944
				} else {
1945
					$autocomplete = false;
1946
				}
1947
1948 View Code Duplication
				if ( 'data' === $context ) {
1949
					self::$field_data = array(
1950
						'field'        => $name,
1951
						'id'           => $options['id'],
1952
						'autocomplete' => $autocomplete,
1953
					);
1954
				}
1955
1956
				if ( $hierarchy && ! $autocomplete && ! empty( $results ) && $options['table_info']['object_hierarchical'] && ! empty( $options['table_info']['field_parent'] ) ) {
1957
					$select_args = array(
1958
						'id'     => $options['table_info']['field_id'],
1959
						'index'  => $options['table_info']['field_index'],
1960
						'parent' => $options['table_info']['field_parent'],
1961
					);
1962
1963
					$results = pods_hierarchical_select( $results, $select_args );
1964
				}
1965
1966
				$ids = array();
1967
1968
				if ( ! empty( $results ) ) {
1969
					$display_filter = pods_v( 'display_filter', pods_v( 'options', pods_v( $search_data->field_index, $search_data->pod_data['object_fields'] ) ) );
1970
1971
					foreach ( $results as $result ) {
1972
						$result = get_object_vars( $result );
1973
1974
						if ( ! isset( $result[ $search_data->field_id ] ) || ! isset( $result[ $search_data->field_index ] ) ) {
1975
							continue;
1976
						}
1977
1978
						$result[ $search_data->field_index ] = trim( $result[ $search_data->field_index ] );
1979
1980
						$object = $object_type = '';
1981
1982
						if ( $wpdb->posts === $search_data->table && isset( $result['post_type'] ) ) {
1983
							$object      = $result['post_type'];
1984
							$object_type = 'post_type';
1985
						} elseif ( $wpdb->terms === $search_data->table && isset( $result['taxonomy'] ) ) {
1986
							$object      = $result['taxonomy'];
1987
							$object_type = 'taxonomy';
1988
						}
1989
1990
						if ( 0 < strlen( $display_filter ) ) {
1991
							$display_filter_args = pods_v( 'display_filter_args', pods_v( 'options', pods_v( $search_data->field_index, $search_data->pod_data['object_fields'] ) ) );
1992
1993
							$filter_args = array(
1994
								$display_filter,
1995
								$result[ $search_data->field_index ],
1996
							);
1997
1998
							if ( ! empty( $display_filter_args ) ) {
1999
								foreach ( (array) $display_filter_args as $display_filter_arg ) {
2000
									if ( isset( $result[ $display_filter_arg ] ) ) {
2001
										$filter_args[] = $result[ $display_filter_arg ];
2002
									}
2003
								}
2004
							}
2005
2006
							$result[ $search_data->field_index ] = call_user_func_array( 'apply_filters', $filter_args );
2007
						}
2008
2009
						if ( in_array( $options[ self::$type . '_object' ], array( 'site', 'network' ), true ) ) {
2010
							$result[ $search_data->field_index ] = $result[ $search_data->field_index ] . $result['path'];
2011
						} elseif ( strlen( $result[ $search_data->field_index ] ) < 1 ) {
2012
							$result[ $search_data->field_index ] = '(No Title)';
2013
						}
2014
2015
						if ( 'admin_ajax_relationship' === $context ) {
2016
							$items[] = array(
2017
								'id'    => $result[ $search_data->field_id ],
2018
								'text'  => $result[ $search_data->field_index ],
2019
								'image' => '',
2020
							);
2021
						} else {
2022
							$data[ $result[ $search_data->field_id ] ] = $result[ $search_data->field_index ];
2023
						}
2024
2025
						$ids[] = $result[ $search_data->field_id ];
2026
					}
2027
				}
2028
			}
2029
2030
			if ( $simple && 'admin_ajax_relationship' === $context ) {
2031
				$found_data = array();
2032
2033
				foreach ( $data as $k => $v ) {
2034
					if ( false !== stripos( $v, $data_params['query'] ) || false !== stripos( $k, $data_params['query'] ) ) {
2035
						$found_data[ $k ] = $v;
2036
					}
2037
				}
2038
2039
				$data = $found_data;
2040
			}
2041
		}
2042
2043
		if ( 'admin_ajax_relationship' === $context ) {
2044
			if ( empty( $items ) && ! empty( $data ) ) {
2045
				foreach ( $data as $k => $v ) {
2046
					$items[] = array(
2047
						'id'    => $k,
2048
						'text'  => $v,
2049
						'image' => '',
2050
					);
2051
				}
2052
			}
2053
2054
			$data = $items;
2055
		}
2056
2057
		return $data;
2058
2059
	}
2060
2061
	/**
2062
	 * Handle autocomplete AJAX.
2063
	 *
2064
	 * @since 2.3
2065
	 */
2066
	public function admin_ajax_relationship() {
2067
2068
		pods_session_start();
2069
2070
		// Sanitize input.
2071
		$params = pods_unslash( (array) $_POST );
2072
2073 View Code Duplication
		foreach ( $params as $key => $value ) {
2074
			if ( 'action' === $key ) {
2075
				continue;
2076
			}
2077
2078
			unset( $params[ $key ] );
2079
2080
			$params[ str_replace( '_podsfix_', '', $key ) ] = $value;
2081
		}
2082
2083
		$params = (object) $params;
2084
2085
		$uid = @session_id();
2086
2087
		if ( is_user_logged_in() ) {
2088
			$uid = 'user_' . get_current_user_id();
2089
		}
2090
2091
		$nonce_check = 'pods_relationship_' . (int) $params->pod . '_' . $uid . '_' . $params->uri . '_' . (int) $params->field;
2092
2093 View Code Duplication
		if ( ! isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, $nonce_check ) ) {
2094
			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...
2095
		}
2096
2097
		if ( empty( self::$api ) ) {
2098
			self::$api = pods_api();
2099
		}
2100
2101
		$pod   = self::$api->load_pod( array( 'id' => (int) $params->pod ) );
2102
		$field = self::$api->load_field( array( 'id' => (int) $params->field, 'table_info' => true ) );
2103
		$id    = (int) $params->id;
2104
2105
		$limit = 15;
2106
2107
		if ( isset( $params->limit ) ) {
2108
			$limit = (int) $params->limit;
2109
		}
2110
2111
		$page = 1;
2112
2113
		if ( isset( $params->page ) ) {
2114
			$page = (int) $params->page;
2115
		}
2116
2117
		if ( ! isset( $params->query ) || strlen( trim( $params->query ) ) < 1 ) {
2118
			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...
2119
		} elseif ( empty( $pod ) || empty( $field ) || (int) $pod['id'] !== (int) $field['pod_id'] || ! isset( $pod['fields'][ $field['name'] ] ) ) {
2120
			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...
2121
		} elseif ( 'pick' !== $field['type'] || empty( $field['table_info'] ) ) {
2122
			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...
2123
		} elseif ( 'single' === pods_v( self::$type . '_format_type', $field ) && 'autocomplete' === pods_v( self::$type . '_format_single', $field ) ) {
2124
			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...
2125
		} elseif ( 'multi' === pods_v( self::$type . '_format_type', $field ) && 'autocomplete' === pods_v( self::$type . '_format_multi', $field ) ) {
2126
			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...
2127
		}
2128
2129
		$object_params = array(
2130
			'name'        => $field['name'], // The name of the field.
2131
			'value'       => null, // The value of the field.
2132
			'options'     => array_merge( $field, $field['options'] ), // Field options.
2133
			'pod'         => $pod, // Pod data.
2134
			'id'          => $id, // Item ID.
2135
			'context'     => 'admin_ajax_relationship', // Data context.
2136
			'data_params' => $params,
2137
			'page'        => $page,
2138
			'limit'       => $limit
2139
		);
2140
2141
		$pick_data = apply_filters( 'pods_field_pick_data_ajax', null, $field['name'], null, $field, $pod, $id );
2142
2143
		if ( null !== $pick_data ) {
2144
			$items = $pick_data;
2145
		} else {
2146
			$items = $this->get_object_data( $object_params );
2147
		}
2148
2149
		if ( ! empty( $items ) && isset( $items[0] ) && ! is_array( $items[0] ) ) {
2150
			$new_items = array();
2151
2152
			foreach ( $items as $id => $text ) {
2153
				$new_items[] = array(
2154
					'id'    => $id,
2155
					'text'  => $text,
2156
					'image' => '',
2157
				);
2158
			}
2159
2160
			$items = $new_items;
2161
		}
2162
2163
		$items = apply_filters( 'pods_field_pick_data_ajax_items', $items, $field['name'], null, $field, $pod, $id );
2164
2165
		$items = array(
2166
			'results' => $items,
2167
		);
2168
2169
		wp_send_json( $items );
2170
2171
		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...
2172
2173
	}
2174
2175
	/**
2176
	 * Data callback for Post Stati
2177
	 *
2178
	 * @param string       $name    The name of the field
2179
	 * @param string|array $value   The value of the field
2180
	 * @param array        $options Field options
2181
	 * @param array        $pod     Pod data
2182
	 * @param int          $id      Item ID
2183
	 *
2184
	 * @return array
2185
	 *
2186
	 * @since 2.3
2187
	 */
2188
	public function data_post_stati( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2189
2190
		$data = array();
2191
2192
		$post_stati = get_post_stati( array(), 'objects' );
2193
2194
		foreach ( $post_stati as $post_status ) {
2195
			$data[ $post_status->name ] = $post_status->label;
2196
		}
2197
2198
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2199
2200
	}
2201
2202
	/**
2203
	 * Data callback for User Roles
2204
	 *
2205
	 * @param string       $name    The name of the field
2206
	 * @param string|array $value   The value of the field
2207
	 * @param array        $options Field options
2208
	 * @param array        $pod     Pod data
2209
	 * @param int          $id      Item ID
2210
	 *
2211
	 * @return array
2212
	 *
2213
	 * @since 2.3
2214
	 */
2215
	public function data_roles( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2216
2217
		$data = array();
2218
2219
		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...
2220
2221
		foreach ( $wp_roles->role_objects as $key => $role ) {
2222
			$data[ $key ] = $wp_roles->role_names[ $key ];
2223
		}
2224
2225
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2226
2227
	}
2228
2229
	/**
2230
	 * Data callback for User Capabilities
2231
	 *
2232
	 * @param string       $name    The name of the field
2233
	 * @param string|array $value   The value of the field
2234
	 * @param array        $options Field options
2235
	 * @param array        $pod     Pod data
2236
	 * @param int          $id      Item ID
2237
	 *
2238
	 * @return array
2239
	 *
2240
	 * @since 2.3
2241
	 */
2242
	public function data_capabilities( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2243
2244
		$data = array();
2245
2246
		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...
2247
2248
		$default_caps = array(
2249
			'activate_plugins',
2250
			'add_users',
2251
			'create_users',
2252
			'delete_others_pages',
2253
			'delete_others_posts',
2254
			'delete_pages',
2255
			'delete_plugins',
2256
			'delete_posts',
2257
			'delete_private_pages',
2258
			'delete_private_posts',
2259
			'delete_published_pages',
2260
			'delete_published_posts',
2261
			'delete_users',
2262
			'edit_dashboard',
2263
			'edit_files',
2264
			'edit_others_pages',
2265
			'edit_others_posts',
2266
			'edit_pages',
2267
			'edit_plugins',
2268
			'edit_posts',
2269
			'edit_private_pages',
2270
			'edit_private_posts',
2271
			'edit_published_pages',
2272
			'edit_published_posts',
2273
			'edit_theme_options',
2274
			'edit_themes',
2275
			'edit_users',
2276
			'import',
2277
			'install_plugins',
2278
			'install_themes',
2279
			'list_users',
2280
			'manage_categories',
2281
			'manage_links',
2282
			'manage_options',
2283
			'moderate_comments',
2284
			'promote_users',
2285
			'publish_pages',
2286
			'publish_posts',
2287
			'read',
2288
			'read_private_pages',
2289
			'read_private_posts',
2290
			'remove_users',
2291
			'switch_themes',
2292
			'unfiltered_html',
2293
			'unfiltered_upload',
2294
			'update_core',
2295
			'update_plugins',
2296
			'update_themes',
2297
			'upload_files',
2298
		);
2299
2300
		$role_caps = array();
2301
2302 View Code Duplication
		foreach ( $wp_roles->role_objects as $key => $role ) {
2303
			if ( is_array( $role->capabilities ) ) {
2304
				foreach ( $role->capabilities as $cap => $grant ) {
2305
					$role_caps[ $cap ] = $cap;
2306
				}
2307
			}
2308
		}
2309
2310
		$role_caps = array_unique( $role_caps );
2311
2312
		$capabilities = array_merge( $default_caps, $role_caps );
2313
2314
		// To support Members filters
2315
		$capabilities = apply_filters( 'members_get_capabilities', $capabilities );
2316
2317
		$capabilities = apply_filters( 'pods_roles_get_capabilities', $capabilities );
2318
2319
		sort( $capabilities );
2320
2321
		$capabilities = array_unique( $capabilities );
2322
2323
		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...
2324
2325
		foreach ( $capabilities as $capability ) {
2326
			$data[ $capability ] = $capability;
2327
		}
2328
2329
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2330
2331
	}
2332
2333
	/**
2334
	 * Data callback for Image Sizes
2335
	 *
2336
	 * @param string       $name    The name of the field
2337
	 * @param string|array $value   The value of the field
2338
	 * @param array        $options Field options
2339
	 * @param array        $pod     Pod data
2340
	 * @param int          $id      Item ID
2341
	 *
2342
	 * @return array
2343
	 *
2344
	 * @since 2.3
2345
	 */
2346 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...
2347
2348
		$data = array();
2349
2350
		$image_sizes = get_intermediate_image_sizes();
2351
2352
		foreach ( $image_sizes as $image_size ) {
2353
			$data[ $image_size ] = ucwords( str_replace( '-', ' ', $image_size ) );
2354
		}
2355
2356
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2357
2358
	}
2359
2360
	/**
2361
	 * Data callback for Countries
2362
	 *
2363
	 * @param string       $name    The name of the field
2364
	 * @param string|array $value   The value of the field
2365
	 * @param array        $options Field options
2366
	 * @param array        $pod     Pod data
2367
	 * @param int          $id      Item ID
2368
	 *
2369
	 * @return array
2370
	 *
2371
	 * @since 2.3
2372
	 */
2373
	public function data_countries( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2374
2375
		$data = array(
2376
			'AF' => __( 'Afghanistan' ),
2377
			'AL' => __( 'Albania' ),
2378
			'DZ' => __( 'Algeria' ),
2379
			'AS' => __( 'American Samoa' ),
2380
			'AD' => __( 'Andorra' ),
2381
			'AO' => __( 'Angola' ),
2382
			'AI' => __( 'Anguilla' ),
2383
			'AQ' => __( 'Antarctica' ),
2384
			'AG' => __( 'Antigua and Barbuda' ),
2385
			'AR' => __( 'Argentina' ),
2386
			'AM' => __( 'Armenia' ),
2387
			'AW' => __( 'Aruba' ),
2388
			'AU' => __( 'Australia' ),
2389
			'AT' => __( 'Austria' ),
2390
			'AZ' => __( 'Azerbaijan' ),
2391
			'BS' => __( 'Bahamas' ),
2392
			'BH' => __( 'Bahrain' ),
2393
			'BD' => __( 'Bangladesh' ),
2394
			'BB' => __( 'Barbados' ),
2395
			'BY' => __( 'Belarus' ),
2396
			'BE' => __( 'Belgium' ),
2397
			'BZ' => __( 'Belize' ),
2398
			'BJ' => __( 'Benin' ),
2399
			'BM' => __( 'Bermuda' ),
2400
			'BT' => __( 'Bhutan' ),
2401
			'BO' => __( 'Bolivia' ),
2402
			'BA' => __( 'Bosnia and Herzegovina' ),
2403
			'BW' => __( 'Botswana' ),
2404
			'BV' => __( 'Bouvet Island' ),
2405
			'BR' => __( 'Brazil' ),
2406
			'BQ' => __( 'British Antarctic Territory' ),
2407
			'IO' => __( 'British Indian Ocean Territory' ),
2408
			'VG' => __( 'British Virgin Islands' ),
2409
			'BN' => __( 'Brunei' ),
2410
			'BG' => __( 'Bulgaria' ),
2411
			'BF' => __( 'Burkina Faso' ),
2412
			'BI' => __( 'Burundi' ),
2413
			'KH' => __( 'Cambodia' ),
2414
			'CM' => __( 'Cameroon' ),
2415
			'CA' => __( 'Canada' ),
2416
			'CT' => __( 'Canton and Enderbury Islands' ),
2417
			'CV' => __( 'Cape Verde' ),
2418
			'KY' => __( 'Cayman Islands' ),
2419
			'CF' => __( 'Central African Republic' ),
2420
			'TD' => __( 'Chad' ),
2421
			'CL' => __( 'Chile' ),
2422
			'CN' => __( 'China' ),
2423
			'CX' => __( 'Christmas Island' ),
2424
			'CC' => __( 'Cocos [Keeling] Islands' ),
2425
			'CO' => __( 'Colombia' ),
2426
			'KM' => __( 'Comoros' ),
2427
			'CG' => __( 'Congo - Brazzaville' ),
2428
			'CD' => __( 'Congo - Kinshasa' ),
2429
			'CK' => __( 'Cook Islands' ),
2430
			'CR' => __( 'Costa Rica' ),
2431
			'HR' => __( 'Croatia' ),
2432
			'CU' => __( 'Cuba' ),
2433
			'CY' => __( 'Cyprus' ),
2434
			'CZ' => __( 'Czech Republic' ),
2435
			'CI' => __( 'Côte d’Ivoire' ),
2436
			'DK' => __( 'Denmark' ),
2437
			'DJ' => __( 'Djibouti' ),
2438
			'DM' => __( 'Dominica' ),
2439
			'DO' => __( 'Dominican Republic' ),
2440
			'NQ' => __( 'Dronning Maud Land' ),
2441
			'DD' => __( 'East Germany' ),
2442
			'EC' => __( 'Ecuador' ),
2443
			'EG' => __( 'Egypt' ),
2444
			'SV' => __( 'El Salvador' ),
2445
			'GQ' => __( 'Equatorial Guinea' ),
2446
			'ER' => __( 'Eritrea' ),
2447
			'EE' => __( 'Estonia' ),
2448
			'ET' => __( 'Ethiopia' ),
2449
			'FK' => __( 'Falkland Islands' ),
2450
			'FO' => __( 'Faroe Islands' ),
2451
			'FJ' => __( 'Fiji' ),
2452
			'FI' => __( 'Finland' ),
2453
			'FR' => __( 'France' ),
2454
			'GF' => __( 'French Guiana' ),
2455
			'PF' => __( 'French Polynesia' ),
2456
			'TF' => __( 'French Southern Territories' ),
2457
			'FQ' => __( 'French Southern and Antarctic Territories' ),
2458
			'GA' => __( 'Gabon' ),
2459
			'GM' => __( 'Gambia' ),
2460
			'GE' => __( 'Georgia' ),
2461
			'DE' => __( 'Germany' ),
2462
			'GH' => __( 'Ghana' ),
2463
			'GI' => __( 'Gibraltar' ),
2464
			'GR' => __( 'Greece' ),
2465
			'GL' => __( 'Greenland' ),
2466
			'GD' => __( 'Grenada' ),
2467
			'GP' => __( 'Guadeloupe' ),
2468
			'GU' => __( 'Guam' ),
2469
			'GT' => __( 'Guatemala' ),
2470
			'GG' => __( 'Guernsey' ),
2471
			'GN' => __( 'Guinea' ),
2472
			'GW' => __( 'Guinea-Bissau' ),
2473
			'GY' => __( 'Guyana' ),
2474
			'HT' => __( 'Haiti' ),
2475
			'HM' => __( 'Heard Island and McDonald Islands' ),
2476
			'HN' => __( 'Honduras' ),
2477
			'HK' => __( 'Hong Kong SAR China' ),
2478
			'HU' => __( 'Hungary' ),
2479
			'IS' => __( 'Iceland' ),
2480
			'IN' => __( 'India' ),
2481
			'ID' => __( 'Indonesia' ),
2482
			'IR' => __( 'Iran' ),
2483
			'IQ' => __( 'Iraq' ),
2484
			'IE' => __( 'Ireland' ),
2485
			'IM' => __( 'Isle of Man' ),
2486
			'IL' => __( 'Israel' ),
2487
			'IT' => __( 'Italy' ),
2488
			'JM' => __( 'Jamaica' ),
2489
			'JP' => __( 'Japan' ),
2490
			'JE' => __( 'Jersey' ),
2491
			'JT' => __( 'Johnston Island' ),
2492
			'JO' => __( 'Jordan' ),
2493
			'KZ' => __( 'Kazakhstan' ),
2494
			'KE' => __( 'Kenya' ),
2495
			'KI' => __( 'Kiribati' ),
2496
			'KW' => __( 'Kuwait' ),
2497
			'KG' => __( 'Kyrgyzstan' ),
2498
			'LA' => __( 'Laos' ),
2499
			'LV' => __( 'Latvia' ),
2500
			'LB' => __( 'Lebanon' ),
2501
			'LS' => __( 'Lesotho' ),
2502
			'LR' => __( 'Liberia' ),
2503
			'LY' => __( 'Libya' ),
2504
			'LI' => __( 'Liechtenstein' ),
2505
			'LT' => __( 'Lithuania' ),
2506
			'LU' => __( 'Luxembourg' ),
2507
			'MO' => __( 'Macau SAR China' ),
2508
			'MK' => __( 'Macedonia' ),
2509
			'MG' => __( 'Madagascar' ),
2510
			'MW' => __( 'Malawi' ),
2511
			'MY' => __( 'Malaysia' ),
2512
			'MV' => __( 'Maldives' ),
2513
			'ML' => __( 'Mali' ),
2514
			'MT' => __( 'Malta' ),
2515
			'MH' => __( 'Marshall Islands' ),
2516
			'MQ' => __( 'Martinique' ),
2517
			'MR' => __( 'Mauritania' ),
2518
			'MU' => __( 'Mauritius' ),
2519
			'YT' => __( 'Mayotte' ),
2520
			'FX' => __( 'Metropolitan France' ),
2521
			'MX' => __( 'Mexico' ),
2522
			'FM' => __( 'Micronesia' ),
2523
			'MI' => __( 'Midway Islands' ),
2524
			'MD' => __( 'Moldova' ),
2525
			'MC' => __( 'Monaco' ),
2526
			'MN' => __( 'Mongolia' ),
2527
			'ME' => __( 'Montenegro' ),
2528
			'MS' => __( 'Montserrat' ),
2529
			'MA' => __( 'Morocco' ),
2530
			'MZ' => __( 'Mozambique' ),
2531
			'MM' => __( 'Myanmar [Burma]' ),
2532
			'NA' => __( 'Namibia' ),
2533
			'NR' => __( 'Nauru' ),
2534
			'NP' => __( 'Nepal' ),
2535
			'NL' => __( 'Netherlands' ),
2536
			'AN' => __( 'Netherlands Antilles' ),
2537
			'NT' => __( 'Neutral Zone' ),
2538
			'NC' => __( 'New Caledonia' ),
2539
			'NZ' => __( 'New Zealand' ),
2540
			'NI' => __( 'Nicaragua' ),
2541
			'NE' => __( 'Niger' ),
2542
			'NG' => __( 'Nigeria' ),
2543
			'NU' => __( 'Niue' ),
2544
			'NF' => __( 'Norfolk Island' ),
2545
			'KP' => __( 'North Korea' ),
2546
			'VD' => __( 'North Vietnam' ),
2547
			'MP' => __( 'Northern Mariana Islands' ),
2548
			'NO' => __( 'Norway' ),
2549
			'OM' => __( 'Oman' ),
2550
			'PC' => __( 'Pacific Islands Trust Territory' ),
2551
			'PK' => __( 'Pakistan' ),
2552
			'PW' => __( 'Palau' ),
2553
			'PS' => __( 'Palestinian Territories' ),
2554
			'PA' => __( 'Panama' ),
2555
			'PZ' => __( 'Panama Canal Zone' ),
2556
			'PG' => __( 'Papua New Guinea' ),
2557
			'PY' => __( 'Paraguay' ),
2558
			'YD' => __( "People's Democratic Republic of Yemen" ),
2559
			'PE' => __( 'Peru' ),
2560
			'PH' => __( 'Philippines' ),
2561
			'PN' => __( 'Pitcairn Islands' ),
2562
			'PL' => __( 'Poland' ),
2563
			'PT' => __( 'Portugal' ),
2564
			'PR' => __( 'Puerto Rico' ),
2565
			'QA' => __( 'Qatar' ),
2566
			'RO' => __( 'Romania' ),
2567
			'RU' => __( 'Russia' ),
2568
			'RW' => __( 'Rwanda' ),
2569
			'RE' => __( 'Réunion' ),
2570
			'BL' => __( 'Saint Barthélemy' ),
2571
			'SH' => __( 'Saint Helena' ),
2572
			'KN' => __( 'Saint Kitts and Nevis' ),
2573
			'LC' => __( 'Saint Lucia' ),
2574
			'MF' => __( 'Saint Martin' ),
2575
			'PM' => __( 'Saint Pierre and Miquelon' ),
2576
			'VC' => __( 'Saint Vincent and the Grenadines' ),
2577
			'WS' => __( 'Samoa' ),
2578
			'SM' => __( 'San Marino' ),
2579
			'SA' => __( 'Saudi Arabia' ),
2580
			'SN' => __( 'Senegal' ),
2581
			'RS' => __( 'Serbia' ),
2582
			'CS' => __( 'Serbia and Montenegro' ),
2583
			'SC' => __( 'Seychelles' ),
2584
			'SL' => __( 'Sierra Leone' ),
2585
			'SG' => __( 'Singapore' ),
2586
			'SK' => __( 'Slovakia' ),
2587
			'SI' => __( 'Slovenia' ),
2588
			'SB' => __( 'Solomon Islands' ),
2589
			'SO' => __( 'Somalia' ),
2590
			'ZA' => __( 'South Africa' ),
2591
			'GS' => __( 'South Georgia and the South Sandwich Islands' ),
2592
			'KR' => __( 'South Korea' ),
2593
			'ES' => __( 'Spain' ),
2594
			'LK' => __( 'Sri Lanka' ),
2595
			'SD' => __( 'Sudan' ),
2596
			'SR' => __( 'Suriname' ),
2597
			'SJ' => __( 'Svalbard and Jan Mayen' ),
2598
			'SZ' => __( 'Swaziland' ),
2599
			'SE' => __( 'Sweden' ),
2600
			'CH' => __( 'Switzerland' ),
2601
			'SY' => __( 'Syria' ),
2602
			'ST' => __( 'São Tomé and Príncipe' ),
2603
			'TW' => __( 'Taiwan' ),
2604
			'TJ' => __( 'Tajikistan' ),
2605
			'TZ' => __( 'Tanzania' ),
2606
			'TH' => __( 'Thailand' ),
2607
			'TL' => __( 'Timor-Leste' ),
2608
			'TG' => __( 'Togo' ),
2609
			'TK' => __( 'Tokelau' ),
2610
			'TO' => __( 'Tonga' ),
2611
			'TT' => __( 'Trinidad and Tobago' ),
2612
			'TN' => __( 'Tunisia' ),
2613
			'TR' => __( 'Turkey' ),
2614
			'TM' => __( 'Turkmenistan' ),
2615
			'TC' => __( 'Turks and Caicos Islands' ),
2616
			'TV' => __( 'Tuvalu' ),
2617
			'UM' => __( 'U.S. Minor Outlying Islands' ),
2618
			'PU' => __( 'U.S. Miscellaneous Pacific Islands' ),
2619
			'VI' => __( 'U.S. Virgin Islands' ),
2620
			'UG' => __( 'Uganda' ),
2621
			'UA' => __( 'Ukraine' ),
2622
			'SU' => __( 'Union of Soviet Socialist Republics' ),
2623
			'AE' => __( 'United Arab Emirates' ),
2624
			'GB' => __( 'United Kingdom' ),
2625
			'US' => __( 'United States' ),
2626
			'ZZ' => __( 'Unknown or Invalid Region' ),
2627
			'UY' => __( 'Uruguay' ),
2628
			'UZ' => __( 'Uzbekistan' ),
2629
			'VU' => __( 'Vanuatu' ),
2630
			'VA' => __( 'Vatican City' ),
2631
			'VE' => __( 'Venezuela' ),
2632
			'VN' => __( 'Vietnam' ),
2633
			'WK' => __( 'Wake Island' ),
2634
			'WF' => __( 'Wallis and Futuna' ),
2635
			'EH' => __( 'Western Sahara' ),
2636
			'YE' => __( 'Yemen' ),
2637
			'ZM' => __( 'Zambia' ),
2638
			'ZW' => __( 'Zimbabwe' ),
2639
			'AX' => __( 'Åland Islands' ),
2640
		);
2641
2642
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2643
2644
	}
2645
2646
	/**
2647
	 * Data callback for US States
2648
	 *
2649
	 * @param string       $name    The name of the field
2650
	 * @param string|array $value   The value of the field
2651
	 * @param array        $options Field options
2652
	 * @param array        $pod     Pod data
2653
	 * @param int          $id      Item ID
2654
	 *
2655
	 * @return array
2656
	 *
2657
	 * @since 2.3
2658
	 */
2659
	public function data_us_states( $name = null, $value = null, $options = null, $pod = null, $id = null ) {
2660
2661
		$data = array(
2662
			'AL' => __( 'Alabama' ),
2663
			'AK' => __( 'Alaska' ),
2664
			'AZ' => __( 'Arizona' ),
2665
			'AR' => __( 'Arkansas' ),
2666
			'CA' => __( 'California' ),
2667
			'CO' => __( 'Colorado' ),
2668
			'CT' => __( 'Connecticut' ),
2669
			'DE' => __( 'Delaware' ),
2670
			'DC' => __( 'District Of Columbia' ),
2671
			'FL' => __( 'Florida' ),
2672
			'GA' => __( 'Georgia' ),
2673
			'HI' => __( 'Hawaii' ),
2674
			'ID' => __( 'Idaho' ),
2675
			'IL' => __( 'Illinois' ),
2676
			'IN' => __( 'Indiana' ),
2677
			'IA' => __( 'Iowa' ),
2678
			'KS' => __( 'Kansas' ),
2679
			'KY' => __( 'Kentucky' ),
2680
			'LA' => __( 'Louisiana' ),
2681
			'ME' => __( 'Maine' ),
2682
			'MD' => __( 'Maryland' ),
2683
			'MA' => __( 'Massachusetts' ),
2684
			'MI' => __( 'Michigan' ),
2685
			'MN' => __( 'Minnesota' ),
2686
			'MS' => __( 'Mississippi' ),
2687
			'MO' => __( 'Missouri' ),
2688
			'MT' => __( 'Montana' ),
2689
			'NE' => __( 'Nebraska' ),
2690
			'NV' => __( 'Nevada' ),
2691
			'NH' => __( 'New Hampshire' ),
2692
			'NJ' => __( 'New Jersey' ),
2693
			'NM' => __( 'New Mexico' ),
2694
			'NY' => __( 'New York' ),
2695
			'NC' => __( 'North Carolina' ),
2696
			'ND' => __( 'North Dakota' ),
2697
			'OH' => __( 'Ohio' ),
2698
			'OK' => __( 'Oklahoma' ),
2699
			'OR' => __( 'Oregon' ),
2700
			'PA' => __( 'Pennsylvania' ),
2701
			'RI' => __( 'Rhode Island' ),
2702
			'SC' => __( 'South Carolina' ),
2703
			'SD' => __( 'South Dakota' ),
2704
			'TN' => __( 'Tennessee' ),
2705
			'TX' => __( 'Texas' ),
2706
			'UT' => __( 'Utah' ),
2707
			'VT' => __( 'Vermont' ),
2708
			'VA' => __( 'Virginia' ),
2709
			'WA' => __( 'Washington' ),
2710
			'WV' => __( 'West Virginia' ),
2711
			'WI' => __( 'Wisconsin' ),
2712
			'WY' => __( 'Wyoming' ),
2713
		);
2714
2715
		return apply_filters( 'pods_form_ui_field_pick_' . __FUNCTION__, $data, $name, $value, $options, $pod, $id );
2716
2717
	}
2718
2719
	/**
2720
	 * Data callback for US States
2721
	 *
2722
	 * @param string       $name    The name of the field
2723
	 * @param string|array $value   The value of the field
2724
	 * @param array        $options Field options
2725
	 * @param array        $pod     Pod data
2726
	 * @param int          $id      Item ID
2727
	 *
2728
	 * @return array
2729
	 *
2730
	 * @since 2.3
2731
	 */
2732
	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...
2733
2734
		/**
2735
		 * @var WP_Locale
2736
		 */
2737
		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...
2738
2739
		return $wp_locale->weekday;
2740
2741
	}
2742
2743
	/**
2744
	 * Data callback for US States
2745
	 *
2746
	 * @param string       $name    The name of the field
2747
	 * @param string|array $value   The value of the field
2748
	 * @param array        $options Field options
2749
	 * @param array        $pod     Pod data
2750
	 * @param int          $id      Item ID
2751
	 *
2752
	 * @return array
2753
	 *
2754
	 * @since 2.3
2755
	 */
2756
	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...
2757
2758
		/**
2759
		 * @var WP_Locale
2760
		 */
2761
		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...
2762
2763
		return $wp_locale->month;
2764
2765
	}
2766
2767
}
2768