Completed
Push — 2.x ( 4ed99b...cdb245 )
by Scott Kingsley
06:09
created

data.php ➔ pods_hierarchical_list_recurse()   F

Complexity

Conditions 34
Paths 1344

Size

Total Lines 86
Code Lines 54

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 34
eloc 54
nc 1344
nop 3
dl 0
loc 86
rs 2.2409

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
 * @package Pods\Global\Functions\Data
4
 */
5
/**
6
 * Filter input and return sanitized output
7
 *
8
 * @param mixed $input The string, array, or object to sanitize
9
 * @param array $params Additional options
10
 *
11
 * @return array|mixed|object|string|void
12
 *
13
 * @since 1.2.0
14
 *
15
 * @see wp_slash
16
 */
17
function pods_sanitize( $input, $params = array() ) {
18
19
	if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) {
20
		return $input;
21
	}
22
23
	$output = array();
24
25
	$defaults = array(
26
		'nested' => false,
27
		'type' => null // %s %d %f etc
28
	);
29
30 View Code Duplication
	if ( !is_array( $params ) ) {
31
		$defaults[ 'type' ] = $params;
32
33
		$params = $defaults;
34
	}
35
	else {
36
		$params = array_merge( $defaults, (array) $params );
37
	}
38
39
	if ( is_object( $input ) ) {
40
		$input = get_object_vars( $input );
41
42
		$n_params = $params;
43
		$n_params[ 'nested' ] = true;
44
45
		foreach ( $input as $key => $val ) {
46
			$output[ pods_sanitize( $key ) ] = pods_sanitize( $val, $n_params );
47
		}
48
49
		$output = (object) $output;
50
	}
51 View Code Duplication
	elseif ( is_array( $input ) ) {
52
		$n_params = $params;
53
		$n_params[ 'nested' ] = true;
54
55
		foreach ( $input as $key => $val ) {
56
			$output[ pods_sanitize( $key ) ] = pods_sanitize( $val, $n_params );
57
		}
58
	}
59 View Code Duplication
	elseif ( !empty( $params[ 'type' ] ) && false !== strpos( $params[ 'type' ], '%' ) ) {
60
		/**
61
		 * @var $wpdb wpdb
62
		 */
63
		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...
64
65
		$output = $wpdb->prepare( $params[ 'type' ], $output );
66
	}
67
	// @todo Switch this full over to esc_sql once we get sanitization sane again in PodsAPI so we *don't* have to unsanitize in various places
68
	elseif ( function_exists( 'wp_slash' ) ) {
69
		$output = wp_slash( $input );
70
	}
71
	else {
72
		$output = esc_sql( $input );
73
	}
74
75
	return $output;
76
77
}
78
79
/**
80
 * Filter input and return sanitized SQL LIKE output
81
 *
82
 * @param mixed $input The string, array, or object to sanitize
83
 *
84
 * @return array|mixed|object|string|void
85
 *
86
 * @since 2.3.9
87
 *
88
 * @see like_escape
89
 */
90 View Code Duplication
function pods_sanitize_like( $input ) {
0 ignored issues
show
Duplication introduced by
This function 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...
91
92
	if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) {
93
		return $input;
94
	}
95
96
	$output = array();
97
98
	if ( is_object( $input ) ) {
99
		$input = get_object_vars( $input );
100
101
		foreach ( $input as $key => $val ) {
102
			$output[ $key ] = pods_sanitize_like( $val );
103
		}
104
105
		$output = (object) $output;
106
	}
107
	elseif ( is_array( $input ) ) {
108
		foreach ( $input as $key => $val ) {
109
			$output[ $key ] = pods_sanitize_like( $val );
110
		}
111
	}
112
	else {
113
		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...
114
115
		if ( pods_version_check( 'wp', '4.0' ) ) {
116
			$output = $wpdb->esc_like( pods_sanitize( $input ) );
117
		}
118
		else {
119
			// like_escape is deprecated in WordPress 4.0
120
			$output = like_escape( pods_sanitize( $input ) );
121
		}
122
	}
123
124
	return $output;
125
126
}
127
128
/**
129
 * Filter input and return slashed output
130
 *
131
 * @param mixed $input The string, array, or object to sanitize
132
 * @param array $params Additional options
133
 *
134
 * @return array|mixed|object|string|void
135
 *
136
 * @since 2.3.9
137
 *
138
 * @see wp_slash
139
 */
140
function pods_slash( $input, $params = array() ) {
141
142
	if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) {
143
		return $input;
144
	}
145
146
	$output = array();
147
148
	$defaults = array(
149
		'type' => null // %s %d %f etc
150
	);
151
152 View Code Duplication
	if ( !is_array( $params ) ) {
153
		$defaults[ 'type' ] = $params;
154
155
		$params = $defaults;
156
	}
157
	else {
158
		$params = array_merge( $defaults, (array) $params );
159
	}
160
161
	if ( empty( $input ) ) {
162
		$output = $input;
163
	}
164
	elseif ( is_object( $input ) ) {
165
		$input = get_object_vars( $input );
166
167
		foreach ( $input as $key => $val ) {
168
			$output[ $key ] = pods_slash( $val, $params );
169
		}
170
171
		$output = (object) $output;
172
	}
173
	elseif ( is_array( $input ) ) {
174
		foreach ( $input as $key => $val ) {
175
			$output[ $key ] = pods_slash( $val, $params );
176
		}
177
	}
178 View Code Duplication
	elseif ( !empty( $params[ 'type' ] ) && false !== strpos( $params[ 'type' ], '%' ) ) {
179
		/**
180
		 * @var $wpdb wpdb
181
		 */
182
		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...
183
184
		$output = $wpdb->prepare( $params[ 'type' ], $output );
185
	}
186
	elseif ( function_exists( 'wp_slash' ) ) {
187
		$output = wp_slash( $input );
188
	}
189
	else {
190
		$output = addslashes( $input );
191
	}
192
193
	return $output;
194
195
}
196
197
/**
198
 * Filter input and return unsanitized output
199
 *
200
 * @param mixed $input The string, array, or object to unsanitize
201
 * @param array $params Additional options
202
 *
203
 * @return array|mixed|object|string|void
204
 *
205
 * @since 1.2.0
206
 */
207
function pods_unsanitize( $input, $params = array() ) {
208
209
	if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) {
210
		return $input;
211
	}
212
213
	$output = array();
214
215
	if ( empty( $input ) ) {
216
		$output = $input;
217
	}
218
	elseif ( is_object( $input ) ) {
219
		$input = get_object_vars( $input );
220
221
		$n_params = (array) $params;
222
		$n_params[ 'nested' ] = true;
223
224
		foreach ( $input as $key => $val ) {
225
			$output[ pods_unsanitize( $key ) ] = pods_unsanitize( $val, $n_params );
226
		}
227
228
		$output = (object) $output;
229
	}
230 View Code Duplication
	elseif ( is_array( $input ) ) {
231
		$n_params             = (array) $params;
232
		$n_params[ 'nested' ] = true;
233
234
		foreach ( $input as $key => $val ) {
235
			$output[ pods_unsanitize( $key ) ] = pods_unsanitize( $val, $n_params );
236
		}
237
	}
238
	else {
239
		// @todo Figure out what to do to unescape mysql_real_escape_string
240
		if ( pods_version_check( 'wp', '3.6' ) ) {
241
			$output = stripslashes( $input );
242
		}
243
		else {
244
			$output = stripslashes( $input );
245
		}
246
	}
247
248
	return $output;
249
250
}
251
252
/**
253
 * Filter input and return unslashed output
254
 *
255
 * @param mixed $input The string, array, or object to unsanitize
256
 *
257
 * @return array|mixed|object|string|void
258
 *
259
 * @since 2.3.9
260
 *
261
 * @see wp_unslash
262
 */
263 View Code Duplication
function pods_unslash( $input ) {
0 ignored issues
show
Duplication introduced by
This function 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...
264
265
	if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) {
266
		return $input;
267
	}
268
269
	$output = array();
270
271
	if ( empty( $input ) ) {
272
		$output = $input;
273
	}
274
	elseif ( is_object( $input ) ) {
275
		$input = get_object_vars( $input );
276
277
		foreach ( $input as $key => $val ) {
278
			$output[ $key ] = pods_unslash( $val );
279
		}
280
281
		$output = (object) $output;
282
	}
283
	elseif ( is_array( $input ) ) {
284
		foreach ( $input as $key => $val ) {
285
			$output[ $key ] = pods_unslash( $val );
286
		}
287
	}
288
	else {
289
		// @todo Figure out what to do to unescape mysql_real_escape_string
290
		if ( pods_version_check( 'wp', '3.6' ) ) {
291
			$output = wp_unslash( $input );
292
		}
293
		else {
294
			$output = stripslashes( $input );
295
		}
296
	}
297
298
	return $output;
299
300
}
301
302
/**
303
 * Filter input and return sanitized output
304
 *
305
 * @param mixed $input The string, array, or object to sanitize
306
 * @param string $charlist (optional) List of characters to be stripped from the input.
307
 * @param string $lr Direction of the trim, can either be 'l' or 'r'.
308
 *
309
 * @return array|object|string
310
 * @since 1.2.0
311
 */
312
function pods_trim ( $input, $charlist = null, $lr = null ) {
313
314
	$output = array();
315
316
	if ( is_object( $input ) ) {
317
		$input = get_object_vars( $input );
318
319
		foreach ( $input as $key => $val ) {
320
			$output[ pods_sanitize( $key ) ] = pods_trim( $val, $charlist, $lr );
321
		}
322
323
		$output = (object) $output;
324
	}
325
	elseif ( is_array( $input ) ) {
326
		foreach ( $input as $key => $val ) {
327
			$output[ pods_sanitize( $key ) ] = pods_trim( $val, $charlist, $lr );
328
		}
329
	}
330
	else {
331
		if ( 'l' == $lr ) {
332
			$output = ltrim( $input, $charlist );
333
		}
334
		elseif ( 'r' == $lr ) {
335
			$output = rtrim( $input, $charlist );
336
		}
337
		else {
338
			$output = trim( $input, $charlist );
339
		}
340
	}
341
342
	return $output;
343
344
}
345
346
/**
347
 * Return a variable (if exists)
348
 *
349
 * @param mixed $var The variable name, can also be a modifier for specific types
350
 * @param string|array|object $type (optional) Super globals, url/url-relative, constants, globals, options, transients, cache, user data, Pod field values, dates
351
 * @param mixed $default (optional) The default value to set if variable doesn't exist
352
 * @param bool $strict (optional) Only allow values (must not be empty)
353
 * @param array $params (optional) Set 'casting'=>true to cast value from $default, 'allowed'=>$allowed to restrict a value to what's allowed
354
 *
355
 * @return mixed The variable (if exists), or default value
356
 * @since 2.3.10
357
 */
358
function pods_v( $var = null, $type = 'get', $default = null, $strict = false, $params = array() ) {
359
360
	$defaults = array(
361
		'casting' => false,
362
		'allowed' => null
363
	);
364
365
	$params = (object) array_merge( $defaults, (array) $params );
366
367
	$output = null;
368
369
	if ( null === $type || '' === $type ) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
370
		// Invalid $type
371
	} elseif ( is_array( $type ) ) {
372
		if ( isset( $type[ $var ] ) ) {
373
			$output = $type[ $var ];
374
		}
375
	} elseif ( is_object( $type ) ) {
376
		if ( isset( $type->{$var} ) ) {
377
			$output = $type->{$var};
378
		}
379
	} else {
380
		$type = strtolower( (string) $type );
381
		switch ( $type ) {
382
			case 'get':
383
				if ( isset( $_GET[ $var ] ) ) {
384
					$output = pods_unslash( $_GET[ $var ] );
385
				}
386
				break;
387
			case 'post':
388
				if ( isset( $_POST[ $var ] ) ) {
389
					$output = pods_unslash( $_POST[ $var ] );
390
				}
391
				break;
392
			case 'request':
393
				if ( isset( $_REQUEST[ $var ] ) ) {
394
					$output = pods_unslash( $_REQUEST[ $var ] );
395
				}
396
				break;
397
			case 'url':
398
			case 'uri':
399
				$url = parse_url( pods_current_url() );
400
				$uri = trim( $url[ 'path' ], '/' );
401
				$uri = array_filter( explode( '/', $uri ) );
402
403
				if ( 'first' == $var ) {
404
					$var = 0;
405
				} elseif ( 'last' == $var ) {
406
					$var = - 1;
407
				}
408
409 View Code Duplication
				if ( is_numeric( $var ) ) {
410
					$output = ( $var < 0 ) ? pods_v( count( $uri ) + $var, $uri ) : pods_v( $var, $uri );
411
				}
412
				break;
413
			case 'url-relative':
414
				$url_raw = pods_current_url();
415
				$prefix  = get_site_url();
416
417 View Code Duplication
				if ( substr( $url_raw, 0, strlen( $prefix ) ) == $prefix ) {
418
					$url_raw = substr( $url_raw, strlen( $prefix ) + 1, strlen( $url_raw ) );
419
				}
420
421
				$url = parse_url( $url_raw );
422
				$uri = trim( $url[ 'path' ], '/' );
423
				$uri = array_filter( explode( '/', $uri ) );
424
425
				if ( 'first' == $var ) {
426
					$var = 0;
427
				} elseif ( 'last' == $var ) {
428
					$var = - 1;
429
				}
430
431 View Code Duplication
				if ( is_numeric( $var ) ) {
432
					$output = ( $var < 0 ) ? pods_v( count( $uri ) + $var, $uri ) : pods_v( $var, $uri );
433
				}
434
				break;
435
			case 'template-url':
436
				$output = get_template_directory_uri();
437
				break;
438
			case 'stylesheet-url':
439
				$output = get_stylesheet_directory_uri();
440
				break;
441 View Code Duplication
			case 'site-url':
442
				$blog_id = $scheme = null;
443
				$path    = '';
444
445
				if ( is_array( $var ) ) {
446
					if ( isset( $var[ 0 ] ) ) {
447
						$blog_id = $var[ 0 ];
448
					} elseif ( isset( $var[ 1 ] ) ) {
449
						$path = $var[ 1 ];
450
					} elseif ( isset( $var[ 2 ] ) ) {
451
						$scheme = $var[ 2 ];
452
					}
453
				} else {
454
					$blog_id = $var;
455
				}
456
457
				$output = get_site_url( $blog_id, $path, $scheme );
458
				break;
459 View Code Duplication
			case 'home-url':
460
				$blog_id = $scheme = null;
461
				$path    = '';
462
463
				if ( is_array( $var ) ) {
464
					if ( isset( $var[ 0 ] ) ) {
465
						$blog_id = $var[ 0 ];
466
					} elseif ( isset( $var[ 1 ] ) ) {
467
						$path = $var[ 1 ];
468
					} elseif ( isset( $var[ 2 ] ) ) {
469
						$scheme = $var[ 2 ];
470
					}
471
				} else {
472
					$blog_id = $var;
473
				}
474
475
				$output = get_home_url( $blog_id, $path, $scheme );
476
				break;
477 View Code Duplication
			case 'admin-url':
478
				$blog_id = $scheme = null;
479
				$path    = '';
480
481
				if ( is_array( $var ) ) {
482
					if ( isset( $var[ 0 ] ) ) {
483
						$blog_id = $var[ 0 ];
484
					} elseif ( isset( $var[ 1 ] ) ) {
485
						$path = $var[ 1 ];
486
					} elseif ( isset( $var[ 2 ] ) ) {
487
						$scheme = $var[ 2 ];
488
					}
489
				} else {
490
					$blog_id = $var;
491
				}
492
493
				$output = get_admin_url( $blog_id, $path, $scheme );
494
				break;
495
			case 'includes-url':
496
				$output = includes_url( $var );
497
				break;
498
			case 'content-url':
499
				$output = content_url( $var );
500
				break;
501
			case 'plugins-url':
502
				$path = $plugin = '';
503
504
				if ( is_array( $var ) ) {
505
					if ( isset( $var[ 0 ] ) ) {
506
						$path = $var[ 0 ];
507
					} elseif ( isset( $var[ 1 ] ) ) {
508
						$plugin = $var[ 1 ];
509
					}
510
				} else {
511
					$path = $var;
512
				}
513
514
				$output = plugins_url( $path, $plugin );
515
				break;
516 View Code Duplication
			case 'network-site-url':
517
				$path   = '';
518
				$scheme = null;
519
520
				if ( is_array( $var ) ) {
521
					if ( isset( $var[ 0 ] ) ) {
522
						$path = $var[ 0 ];
523
					} elseif ( isset( $var[ 1 ] ) ) {
524
						$scheme = $var[ 1 ];
525
					}
526
				} else {
527
					$path = $var;
528
				}
529
530
				$output = network_site_url( $path, $scheme );
531
				break;
532 View Code Duplication
			case 'network-home-url':
533
				$path   = '';
534
				$scheme = null;
535
536
				if ( is_array( $var ) ) {
537
					if ( isset( $var[ 0 ] ) ) {
538
						$path = $var[ 0 ];
539
					} elseif ( isset( $var[ 1 ] ) ) {
540
						$scheme = $var[ 1 ];
541
					}
542
				} else {
543
					$path = $var;
544
				}
545
546
				$output = network_home_url( $path, $scheme );
547
				break;
548 View Code Duplication
			case 'network-admin-url':
549
				$path   = '';
550
				$scheme = null;
551
552
				if ( is_array( $var ) ) {
553
					if ( isset( $var[ 0 ] ) ) {
554
						$path = $var[ 0 ];
555
					} elseif ( isset( $var[ 1 ] ) ) {
556
						$scheme = $var[ 1 ];
557
					}
558
				} else {
559
					$path = $var;
560
				}
561
562
				$output = network_admin_url( $path, $scheme );
563
				break;
564 View Code Duplication
			case 'user-admin-url':
565
				$path   = '';
566
				$scheme = null;
567
568
				if ( is_array( $var ) ) {
569
					if ( isset( $var[ 0 ] ) ) {
570
						$path = $var[ 0 ];
571
					} elseif ( isset( $var[ 1 ] ) ) {
572
						$scheme = $var[ 1 ];
573
					}
574
				} else {
575
					$path = $var;
576
				}
577
578
				$output = user_admin_url( $path, $scheme );
579
				break;
580
			case 'prefix':
581
				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...
582
583
				$output = $wpdb->prefix;
584
				break;
585
			case 'server':
586
				if ( ! pods_strict() ) {
587
					if ( isset( $_SERVER[ $var ] ) ) {
588
						$output = pods_unslash( $_SERVER[ $var ] );
589
					} elseif ( isset( $_SERVER[ strtoupper( $var ) ] ) ) {
590
						$output = pods_unslash( $_SERVER[ strtoupper( $var ) ] );
591
					}
592
				}
593
				break;
594
			case 'session':
595
				if ( isset( $_SESSION[ $var ] ) )
596
					$output = $_SESSION[ $var ];
597
				break;
598
			case 'global':
599
			case 'globals':
600
				if ( isset( $GLOBALS[ $var ] ) )
601
					$output = $GLOBALS[ $var ];
602
				break;
603
			case 'cookie':
604
				if ( isset( $_COOKIE[ $var ] ) )
605
					$output = pods_unslash( $_COOKIE[ $var ] );
606
				break;
607
			case 'constant':
608
				if ( defined( $var ) )
609
					$output = constant( $var );
610
				break;
611
			case 'user':
612
				if ( is_user_logged_in() ) {
613
					$user = get_userdata( get_current_user_id() );
614
615
					if ( isset( $user->{$var} ) ) {
616
						$value = $user->{$var};
617
					} elseif ( 'role' == $var ) {
618
						$value = '';
619
620
						if ( ! empty( $user->roles ) ) {
621
							$value = array_shift( $user->roles );
622
						}
623
					} else {
624
						$value = get_user_meta( $user->ID, $var );
625
					}
626
627
					if ( is_array( $value ) && ! empty( $value ) ) {
628
						$output = $value;
629
					} elseif ( ! is_array( $value ) && 0 < strlen( $value ) ) {
630
						$output = $value;
631
					}
632
				}
633
				break;
634
			case 'option':
635
				$output = get_option( $var, $default );
636
				break;
637
			case 'site-option':
638
				$output = get_site_option( $var, $default );
639
				break;
640
			case 'transient':
641
				$output = get_transient( $var );
642
				break;
643
			case 'site-transient':
644
				$output = get_site_transient( $var );
645
				break;
646 View Code Duplication
			case 'cache':
647
				if ( isset( $GLOBALS[ 'wp_object_cache' ] ) && is_object( $GLOBALS[ 'wp_object_cache' ] ) ) {
648
					$group = 'default';
649
					$force = false;
650
651
					if ( ! is_array( $var ) ) {
652
						$var = explode( '|', $var );
653
					}
654
655
					if ( isset( $var[ 0 ] ) ) {
656
						if ( isset( $var[ 1 ] ) ) {
657
							$group = $var[ 1 ];
658
						}
659
660
						if ( isset( $var[ 2 ] ) ) {
661
							$force = $var[ 2 ];
662
						}
663
664
						$var = $var[ 0 ];
665
666
						$output = wp_cache_get( $var, $group, $force );
667
					}
668
				}
669
				break;
670 View Code Duplication
			case 'pods-transient':
671
				$callback = null;
672
673
				if ( ! is_array( $var ) ) {
674
					$var = explode( '|', $var );
675
				}
676
677
				if ( isset( $var[ 0 ] ) ) {
678
					if ( isset( $var[ 1 ] ) ) {
679
						$callback = $var[ 1 ];
680
					}
681
682
					$var = $var[ 0 ];
683
684
					$output = pods_transient_get( $var, $callback );
685
				}
686
				break;
687 View Code Duplication
			case 'pods-site-transient':
688
				$callback = null;
689
690
				if ( ! is_array( $var ) ) {
691
					$var = explode( '|', $var );
692
				}
693
694
				if ( isset( $var[ 0 ] ) ) {
695
					if ( isset( $var[ 1 ] ) ) {
696
						$callback = $var[ 1 ];
697
					}
698
699
					$var = $var[ 0 ];
700
701
					$output = pods_site_transient_get( $var, $callback );
702
				}
703
				break;
704 View Code Duplication
			case 'pods-cache':
705
				if ( isset( $GLOBALS[ 'wp_object_cache' ] ) && is_object( $GLOBALS[ 'wp_object_cache' ] ) ) {
706
					$group    = 'default';
707
					$callback = null;
708
709
					if ( ! is_array( $var ) ) {
710
						$var = explode( '|', $var );
711
					}
712
713
					if ( isset( $var[ 0 ] ) ) {
714
						if ( isset( $var[ 1 ] ) ) {
715
							$group = $var[ 1 ];
716
						}
717
718
						if ( isset( $var[ 2 ] ) ) {
719
							$callback = $var[ 2 ];
720
						}
721
722
						$var = $var[ 0 ];
723
724
						$output = pods_cache_get( $var, $group, $callback );
725
					}
726
				}
727
				break;
728
			case 'pods-option-cache':
729
				$group    = 'default';
730
				$callback = null;
731
732
				if ( ! is_array( $var ) ) {
733
					$var = explode( '|', $var );
734
				}
735
736
				if ( isset( $var[ 0 ] ) ) {
737
					if ( isset( $var[ 1 ] ) ) {
738
						$group = $var[ 1 ];
739
					}
740
741
					if ( isset( $var[ 2 ] ) ) {
742
						$callback = $var[ 2 ];
743
					}
744
745
					$var = $var[ 0 ];
746
747
					$output = pods_option_cache_get( $var, $group, $callback );
748
				}
749
				break;
750
			case 'date':
751
				$var = explode( '|', $var );
752
753
				if ( ! empty( $var ) ) {
754
					$output = date_i18n( $var[ 0 ], ( isset( $var[ 1 ] ) ? strtotime( $var[ 1 ] ) : false ) );
755
				}
756
				break;
757
			case 'pods':
758
			case 'pods_display':
759
				/**
760
				 * @var $pods Pods
761
				 */
762
				global $pods;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
763
764
				if ( is_object( $pods ) && 'Pods' == get_class( $pods ) ) {
765
					if ( 'pods' === $type ) {
766
						$output = $pods->field( $var );
767
768
						if ( is_array( $output ) ) {
769
							$options = array(
770
								'field'  => $var,
771
								'fields' => $pods->fields
772
							);
773
774
							$output = pods_serial_comma( $output, $options );
775
						}
776
					} elseif ( 'pods_display' === $type ) {
777
						$output = $pods->display( $var );
778
					}
779
				}
780
				break;
781
			default:
782
				$output = apply_filters( 'pods_var_' . $type, $default, $var, $strict, $params );
783
		}
784
	}
785
786
	if ( null !== $default ) {
787
		// Set default
788
		if ( null === $output ) {
789
			$output = $default;
790
		}
791
792
		// Casting
793
		if ( true === $params->casting ) {
794
			$output = pods_cast( $output, $default );
795
		}
796
	}
797
798
	// Strict defaults for empty values
799
	if ( true === $strict ) {
800
		if ( empty( $output ) ) {
801
			$output = $default;
802
		}
803
	}
804
805
	// Allowed values
806
	if ( null !== $params->allowed ) {
807
		if ( is_array( $params->allowed ) ) {
808
			// Not in array and is not the same array
809
			if ( ! in_array( $output, $params->allowed ) && ( ! is_array( $output ) || $output !== $params->allowed ) ) {
810
				$output = $default;
811
			}
812
		} elseif ( $output !== $params->allowed ) {
813
			// Value doesn't match
814
			$output = $default;
815
		}
816
	}
817
818
	return $output;
819
}
820
821
/**
822
 * Return a sanitized variable (if exists)
823
 *
824
 * @param mixed $var The variable name, can also be a modifier for specific types
825
 * @param string|array|object $type (optional) Super globals, url/url-relative, constants, globals, options, transients, cache, user data, Pod field values, dates
826
 * @param mixed $default (optional) The default value to set if variable doesn't exist
827
 * @param bool $strict (optional) Only allow values (must not be empty)
828
 * @param array $params (optional) Set 'casting'=>true to cast value from $default, 'allowed'=>$allowed to restrict a value to what's allowed
829
 *
830
 * @return mixed The variable (if exists), or default value
831
 * @since 2.3.10
832
 *
833
 * @see pods_v
834
 */
835
function pods_v_sanitized( $var = null, $type = 'get', $default = null, $strict = false, $params = array() ) {
836
837
	$output = pods_v( $var, $type, $default, $strict, $params );
838
839
	$output = pods_sanitize( $output, $params );
840
841
	return $output;
842
843
}
844
845
/**
846
 * Set a variable
847
 *
848
 * @param mixed $value The value to be set
849
 * @param mixed $var The variable name, or URI segment position / query var name (if $type is 'url')
850
 * @param string|array|object $type (optional) Super globals, url/url-relative, constants, globals, user data, Pod field values
851
 *
852
 * @return mixed Updated URL (if $type is 'url'), $value (if $type is 'constant'), Item ID (if $type is 'pods'), $type, or false if not set
853
 * @since 2.3.10
854
 */
855
function pods_v_set( $value, $var, $type = 'get' ) {
856
857
	$ret = false;
858
859
	if ( null === $var || '' === $var ) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
860
		// Invalid $var
861
	}
862
	elseif ( null === $type || '' === $type ) {
0 ignored issues
show
Unused Code introduced by
This elseif statement is empty, and could be removed.

This check looks for the bodies of elseif statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These elseif bodies can be removed. If you have an empty elseif but statements in the else branch, consider inverting the condition.

Loading history...
863
		// Invalid $type
864
	}
865
	elseif ( is_array( $type ) ) {
866
		$type[ $var ] = $value;
867
868
		$ret = $type;
869
	}
870
	elseif ( is_object( $type ) ) {
871
		$type->{$var} = $value;
872
873
		$ret = $type;
874
	}
875
	else {
876
		$type = strtolower( $type );
877
878
		if ( 'get' == $type ) {
879
			$_GET[ $var ] = $value;
880
881
			$ret = $_GET;
882
		}
883
		elseif ( 'post' == $type ) {
884
			$_POST[ $var ] = $value;
885
886
			$ret = $_POST;
887
		}
888
		elseif ( 'request' == $type ) {
889
			$_REQUEST[ $var ] = $value;
890
891
			$ret = $_REQUEST;
892
		}
893
		elseif ( 'url' == $type ) {
894
			if ( is_numeric( $var ) && function_exists( 'http_build_url' ) ) {
895
				$url = parse_url( pods_current_url() );
896
				$uri = trim( $url[ 'path' ], '/' );
897
				$uri = array_filter( explode( '/', $uri ) );
898
899
				if ( 'first' == $var ) {
900
					$var = 0;
901
				}
902
				elseif ( 'last' == $var ) {
903
					$var = -1;
904
				}
905
906
				if ( $var < 0 ) {
907
					$uri[ count( $uri ) + $var ] = $value;
908
				}
909
				else {
910
					$uri[ $var ] = $value;
911
				}
912
913
				$url[ 'path' ] = '/' . implode( '/', $uri ) . '/';
914
				$url[ 'path' ] = trim( $url[ 'path' ], '/' );
915
916
				$ret = http_build_url( $url );
917
			}
918
			else {
919
				$ret = add_query_arg( array( $var => $value ) );
920
			}
921
		}
922
		elseif ( 'server' == $type ) {
923
			$_SERVER[ $var ] = $value;
924
925
			$ret = $_SERVER;
926
		}
927
		elseif ( in_array( $type, array( 'global', 'globals' ) ) ) {
928
			$GLOBALS[ $var ] = $value;
929
930
			$ret = $GLOBALS;
931
		}
932
		elseif ( 'session' == $type ) {
933
			// Session start
934
			pods_session_start();
935
936
			$_SESSION[ $var ] = $value;
937
938
			$ret = $_SESSION;
939
		}
940
		elseif ( 'cookie' == $type && !headers_sent() ) {
941
			setcookie( $var, $value, time() + 10 * DAY_IN_SECONDS, COOKIEPATH );
942
943
			$ret = $_COOKIE;
944
		}
945
		elseif ( 'constant' == $type && !defined( $var ) && ( is_scalar( $value ) || null === $value ) ) {
946
			define( $var, $value );
947
948
			$ret = constant( $var );
949
		}
950
		elseif ( 'user' == $type && is_user_logged_in() ) {
951
			$user = get_userdata( get_current_user_id() );
952
953
			if ( !pods_version_check( 'wp', '3.5' ) ) {
954
				$user_data = get_object_vars( $user->data );
955
			}
956
			else {
957
				$user_data = $user->to_array();
958
			}
959
960
			// Role
961
			if ( 'role' == $var ) {
962
				$user->set_role( $value );
963
			}
964
			// Core field
965
			elseif ( isset( $user_data[ $var ] ) ) {
966
				wp_update_user( array( 'ID' => $user->ID, $var => $value ) );
967
			}
968
			// Meta field
969
			else {
970
				update_user_meta( $user->ID, $var, $value );
971
			}
972
973
			$ret = get_userdata( $user->ID );
974
		}
975
		elseif ( 'pods' == $type ) {
976
			/**
977
			 * @var $pods Pods
978
			 */
979
			global $pods;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
980
981
			if ( is_object( $pods ) && 'Pods' == get_class( $pods ) && $pods->exists() ) {
982
				$ret = $pods->save( $var, $value );
983
			}
984
		}
985
		else {
986
			$ret = apply_filters( 'pods_var_set_' . $type, $value, $var );
987
		}
988
	}
989
990
	return $ret;
991
992
}
993
994
/**
995
 * Return a variable (if exists)
996
 *
997
 * @param mixed $var The variable name or URI segment position
998
 * @param string $type (optional) Super globals, url/url-relative, constants, globals, options, transients, cache, user data, Pod field values, dates
999
 * @param mixed $default (optional) The default value to set if variable doesn't exist
1000
 * @param mixed $allowed (optional) The value(s) allowed
1001
 * @param bool $strict (optional) Only allow values (must not be empty)
1002
 * @param bool $casting (optional) Whether to cast the value returned like provided in $default
1003
 * @param string $context (optional) All returned values are sanitized unless this is set to 'raw'
1004
 *
1005
 * @return mixed The variable (if exists), or default value
1006
 * @since 1.10.6
1007
 *
1008
 * @deprecated 2.4 Use pods_v() or pods_v_sanitized() instead.
1009
 * @see pods_v_sanitized
1010
 */
1011
function pods_var( $var = 'last', $type = 'get', $default = null, $allowed = null, $strict = false, $casting = false, $context = 'display' ) {
1012
1013
	if ( 'raw' == $context ) {
1014
		$output = pods_v( $var, $type, $default, $strict, array( 'allowed' => $allowed, 'casting' => $casting ) );
1015
	}
1016
	else {
1017
		$output = pods_v_sanitized( $var, $type, $default, $strict, array( 'allowed' => $allowed, 'casting' => $casting ) );
1018
	}
1019
1020
    return $output;
1021
1022
}
1023
1024
/**
1025
 * Return a variable's raw value (if exists)
1026
 *
1027
 * @param mixed $var The variable name or URI segment position
1028
 * @param string $type (optional) Super globals, url/url-relative, constants, globals, options, transients, cache, user data, Pod field values, dates
1029
 * @param mixed $default (optional) The default value to set if variable doesn't exist
1030
 * @param mixed $allowed (optional) The value(s) allowed
1031
 * @param bool $strict (optional) Only allow values (must not be empty)
1032
 * @param bool $casting (optional) Whether to cast the value returned like provided in $default
1033
 *
1034
 * @return mixed The variable (if exists), or default value
1035
 * @since 2.0
1036
 *
1037
 * @deprecated 2.4 Use pods_v() instead.
1038
 * @see pods_v
1039
 */
1040
function pods_var_raw( $var = 'last', $type = 'get', $default = null, $allowed = null, $strict = false, $casting = false ) {
1041
1042
    return pods_v( $var, $type, $default, $strict, array( 'allowed' => $allowed, 'casting' => $casting ) );
1043
1044
}
1045
1046
/**
1047
 * Set a variable
1048
 *
1049
 * @param mixed $value The value to be set
1050
 * @param mixed $var The variable name or URI segment position
1051
 * @param string $type (optional) "url", "get", "post", "request", "server", "session", "cookie", "constant", or "user"
1052
 *
1053
 * @return mixed $value (if set), $type (if $type is array or object), or $url (if $type is 'url')
1054
 * @since 1.10.6
1055
 *
1056
 * @deprecated 2.4 Use pods_v_set() instead.
1057
 * @see pods_v_set
1058
 */
1059
function pods_var_set( $value, $var = 'last', $type = 'url' ) {
1060
1061
	return pods_v_set( $value, $var, $type );
1062
1063
}
1064
1065
/**
1066
 * Create a new URL off of the current one, with updated parameters
1067
 *
1068
 * @param array $array Parameters to be set (empty will remove it)
1069
 * @param array $allowed Parameters to keep (if empty, all are kept)
1070
 * @param array $excluded Parameters to always remove
1071
 * @param string $url URL to base update off of
1072
 *
1073
 * @return mixed
1074
 *
1075
 * @since 2.3.10
1076
 *
1077
 * @see add_query_arg
1078
 */
1079
function pods_query_arg( $array = null, $allowed = null, $excluded = null, $url = null ) {
1080
1081
	$array = (array) $array;
1082
	$allowed = (array) $allowed;
1083
	$excluded = (array) $excluded;
1084
1085
	if ( !isset( $_GET ) ) {
1086
		$query_args = array();
1087
	}
1088
	else {
1089
		$query_args = pods_unsanitize( $_GET );
1090
	}
1091
1092
	foreach ( $query_args as $key => $val ) {
1093
		if ( is_array( $val ) && empty( $val ) ) {
1094
			$query_args[ $key ] = false;
1095
		}
1096 View Code Duplication
		elseif ( !is_array( $val ) && strlen( $val ) < 1 ) {
1097
			$query_args[ $key ] = false;
1098
		}
1099
		elseif ( !empty( $allowed ) ) {
1100
			$allow_it = false;
1101
1102
			foreach ( $allowed as $allow ) {
1103
				if ( $allow == $key ) {
1104
					$allow_it = true;
1105
				}
1106
				elseif ( false !== strpos( $allow, '*' ) && 0 === strpos( $key, trim( $allow, '*' ) ) ) {
1107
					$allow_it = true;
1108
				}
1109
			}
1110
1111
			if ( !$allow_it ) {
1112
				$query_args[ $key ] = false;
1113
			}
1114
		}
1115
	}
1116
1117
	if ( !empty( $excluded ) ) {
1118
		foreach ( $excluded as $exclusion ) {
1119
			if ( isset( $query_args[ $exclusion ] ) && !in_array( $exclusion, $allowed ) ) {
1120
				$query_args[ $exclusion ] = false;
1121
			}
1122
		}
1123
	}
1124
1125
	if ( !empty( $array ) ) {
1126
		foreach ( $array as $key => $val ) {
1127
			if ( null !== $val || false === strpos( $key, '*' ) ) {
1128
				if ( is_array( $val ) && !empty( $val ) ) {
1129
					$query_args[ $key ] = $val;
1130
				}
1131 View Code Duplication
				elseif ( !is_array( $val ) && 0 < strlen( $val ) ) {
1132
					$query_args[ $key ] = $val;
1133
				}
1134
				elseif ( isset( $query_args[ $key ] ) ) {
1135
					$query_args[ $key ] = false;
1136
				}
1137
			}
1138
			else {
1139
				$key = str_replace( '*', '', $key );
1140
1141
				foreach ( $query_args as $k => $v ) {
1142
					if ( false !== strpos( $k, $key ) ) {
1143
						$query_args[ $k ] = false;
1144
					}
1145
				}
1146
			}
1147
		}
1148
	}
1149
1150
	if ( null === $url ) {
1151
		$url = add_query_arg( $query_args );
1152
	}
1153
	else {
1154
		$url = add_query_arg( $query_args, $url );
1155
	}
1156
1157
	return $url;
1158
1159
}
1160
1161
/**
1162
 * Create a new URL off of the current one, with updated parameters
1163
 *
1164
 * @param array $array Parameters to be set (empty will remove it)
1165
 * @param array $allowed Parameters to keep (if empty, all are kept)
1166
 * @param array $excluded Parameters to always remove
1167
 * @param string $url URL to base update off of
1168
 *
1169
 * @return mixed
1170
 *
1171
 * @since 2.0
1172
 *
1173
 * @deprecated 2.4 Use pods_query_arg() instead.
1174
 * @see pods_query_arg
1175
 */
1176
function pods_var_update( $array = null, $allowed = null, $excluded = null, $url = null ) {
1177
1178
	return pods_query_arg( $array, $allowed, $excluded, $url );
1179
1180
}
1181
1182
/**
1183
 * Cast a value as a specific type
1184
 *
1185
 * @param mixed $value
1186
 * @param mixed $cast_from
1187
 *
1188
 * @return bool
1189
 *
1190
 * @since 2.0
1191
 */
1192
function pods_cast( $value, $cast_from = null ) {
1193
1194
	if ( null !== $cast_from ) {
1195
		if ( is_object( $value ) && is_array( $cast_from ) ) {
1196
			$value = get_object_vars( $value );
1197
		}
1198
		elseif ( is_array( $value ) && is_object( $cast_from ) ) {
1199
			$value = (object) $value;
1200
		}
1201
		else {
1202
			settype( $value, gettype( $cast_from ) );
1203
		}
1204
	}
1205
1206
	return $value;
1207
1208
}
1209
1210
/**
1211
 * Create a slug from an input string
1212
 *
1213
 * @param $orig
1214
 *
1215
 * @return string Sanitized slug
1216
 *
1217
 * @since 1.8.9
1218
 */
1219
function pods_create_slug ( $orig, $strict = true ) {
1220
    $str = preg_replace( "/([_ \\/])/", "-", trim( $orig ) );
1221
1222
    if ( $strict )
1223
        $str = preg_replace( "/([^0-9a-z\-])/", "", strtolower( $str ) );
1224
    else
1225
        $str = urldecode( sanitize_title( strtolower( $str ) ) );
1226
1227
    $str = preg_replace( "/(\-){2,}/", "-", $str );
1228
    $str = trim( $str, '-' );
1229
    $str = apply_filters( 'pods_create_slug', $str, $orig );
1230
1231
    return $str;
1232
}
1233
1234
/**
1235
 * Build a unique slug
1236
 *
1237
 * @param string $slug The slug value
1238
 * @param string $column_name The column name
1239
 * @param string|array $pod The Pod name or array of Pod data
1240
 * @param int $pod_id The Pod ID
1241
 * @param int $id The item ID
1242
 * @param object $obj (optional)
1243
 *
1244
 * @return string The unique slug name
1245
 * @since 1.7.2
1246
 */
1247
function pods_unique_slug ( $slug, $column_name, $pod, $pod_id = 0, $id = 0, $obj = null, $strict = true ) {
1248
    $slug = pods_create_slug( $slug, $strict );
1249
1250
    $pod_data = array();
1251
1252
    if ( is_array( $pod ) ) {
1253
        $pod_data = $pod;
1254
        $pod_id = pods_v_sanitized( 'id', $pod_data, 0 );
1255
        $pod = pods_v_sanitized( 'name', $pod_data );
1256
    }
1257
1258
    $pod_id = absint( $pod_id );
1259
    $id = absint( $id );
1260
1261
    if ( empty( $pod_data ) )
1262
        $pod_data = pods_api()->load_pod( array( 'id' => $pod_id, 'name' => $pod ), false );
1263
1264
    if ( empty( $pod_data ) || empty( $pod_id ) || empty( $pod ) )
1265
        return $slug;
1266
1267
    if ( 'table' != $pod_data[ 'storage' ] || !in_array( $pod_data[ 'type' ], array( 'pod', 'table' ) ) )
1268
        return $slug;
1269
1270
    $check_sql = "
1271
        SELECT DISTINCT `t`.`{$column_name}` AS `slug`
1272
        FROM `@wp_pods_{$pod}` AS `t`
1273
        WHERE `t`.`{$column_name}` = %s AND `t`.`id` != %d
1274
        LIMIT 1
1275
    ";
1276
1277
    $slug_check = pods_query( array( $check_sql, $slug, $id ), $obj );
1278
1279
    if ( !empty( $slug_check ) || apply_filters( 'pods_unique_slug_is_bad_flat_slug', false, $slug, $column_name, $pod, $pod_id, $id, $pod_data, $obj ) ) {
1280
        $suffix = 2;
1281
1282
        do {
1283
            $alt_slug = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-{$suffix}";
1284
1285
            $slug_check = pods_query( array( $check_sql, $alt_slug, $id ), $obj );
1286
1287
            $suffix++;
1288
        }
1289
        while ( !empty( $slug_check ) || apply_filters( 'pods_unique_slug_is_bad_flat_slug', false, $alt_slug, $column_name, $pod, $pod_id, $id, $pod_data, $obj ) );
1290
1291
        $slug = $alt_slug;
1292
    }
1293
1294
    $slug = apply_filters( 'pods_unique_slug', $slug, $id, $column_name, $pod, $pod_id, $obj );
1295
1296
    return $slug;
1297
}
1298
1299
/**
1300
 * Return a lowercase alphanumeric name (use pods_js_name if you want "_" instead of "-" )
1301
 *
1302
 * @param string $orig Input string to clean
1303
 * @param boolean $lower Force lowercase
1304
 * @param boolean $trim_underscores Whether to trim off underscores
1305
 *
1306
 * @return string Sanitized name
1307
 *
1308
 * @since 1.2.0
1309
 */
1310
function pods_clean_name ( $orig, $lower = true, $trim_underscores = false ) {
1311
1312
	$str = trim( $orig );
1313
	$str = preg_replace( '/(\s)/', '_', $str );
1314
	$str = preg_replace( '/([^0-9a-zA-Z\-_])/', '', $str );
1315
	$str = preg_replace( '/(_){2,}/', '_', $str );
1316
	$str = preg_replace( '/(-){2,}/', '-', $str );
1317
1318
	if ( $lower ) {
1319
		$str = strtolower( $str );
1320
	}
1321
1322
	if ( $trim_underscores ) {
1323
		$str = trim( $str, '_' );
1324
	}
1325
1326
	return $str;
1327
}
1328
1329
/**
1330
 * Return a lowercase alphanumeric name (with underscores) for safe Javascript variable names
1331
 *
1332
 * @param string $orig Input string to clean
1333
 * @param boolean $lower Force lowercase
1334
 *
1335
 * @return string Sanitized name
1336
 *
1337
 * @since 2.5.3
1338
 */
1339
function pods_js_name( $orig, $lower = true ) {
1340
1341
	$str = pods_clean_name( $orig, $lower );
1342
	$str = str_replace( '-', '_', $str );
1343
1344
	return $str;
1345
}
1346
1347
/**
1348
 * Get the Absolute Integer of a value
1349
 *
1350
 * @param string $maybeint
1351
 * @param bool $strict (optional) Check if $maybeint is a integer.
1352
 * @param bool $allow_negative (optional)
1353
 *
1354
 * @return integer
1355
 * @since 2.0
1356
 */
1357
function pods_absint ( $maybeint, $strict = true, $allow_negative = false ) {
1358
    if ( true === $strict && !is_numeric( trim( $maybeint ) ) )
1359
        return 0;
1360
1361
    if ( false !== $allow_negative )
1362
        return intval( $maybeint );
1363
1364
    return absint( $maybeint );
1365
}
1366
1367
/**
1368
 * Functions like str_replace except it will restrict $occurrences
1369
 *
1370
 * @param mixed $find
1371
 * @param mixed $replace
1372
 * @param string $string
1373
 * @param int $occurrences (optional)
1374
 *
1375
 * @return mixed
1376
 * @version 2.0
1377
 */
1378
function pods_str_replace ( $find, $replace, $string, $occurrences = -1 ) {
1379 View Code Duplication
    if ( is_array( $string ) ) {
1380
        foreach ( $string as $k => $v ) {
1381
            $string[ $k ] = pods_str_replace( $find, $replace, $v, $occurrences );
1382
        }
1383
1384
        return $string;
1385
    }
1386
    elseif ( is_object( $string ) ) {
1387
        $string = get_object_vars( $string );
1388
1389
        foreach ( $string as $k => $v ) {
1390
            $string[ $k ] = pods_str_replace( $find, $replace, $v, $occurrences );
1391
        }
1392
1393
        return (object) $string;
1394
    }
1395
1396
    if ( is_array( $find ) ) {
1397
        foreach ( $find as &$f ) {
1398
            $f = '/' . preg_quote( $f, '/' ) . '/';
1399
        }
1400
    }
1401
    else
1402
        $find = '/' . preg_quote( $find, '/' ) . '/';
1403
1404
    return preg_replace( $find, $replace, $string, $occurrences );
1405
}
1406
1407
/**
1408
 * Use mb_strlen if available, otherwise fallback to strlen
1409
 *
1410
 * @param string $string
1411
 *
1412
 * @return int
1413
 */
1414
function pods_mb_strlen( $string ) {
1415
1416
	if ( function_exists( 'mb_strlen' ) ) {
1417
		return mb_strlen( $string );
1418
	}
1419
1420
	return strlen( $string );
1421
1422
}
1423
1424
/**
1425
 * Use mb_substr if available, otherwise fallback to substr
1426
 *
1427
 * @param string $string
1428
 * @param int $start
1429
 * @param null|int $length
1430
 * @param null|string $encoding
1431
 *
1432
 * @return string
1433
 */
1434
function pods_mb_substr( $string, $start, $length = null, $encoding = null ) {
1435
1436
	if ( function_exists( 'mb_substr' ) ) {
1437
		if ( null === $encoding ) {
1438
			$encoding = mb_internal_encoding();
1439
		}
1440
1441
		return mb_substr( $string, $start, $length, $encoding );
1442
	}
1443
1444
	return substr( $string, $start, $length );
1445
1446
}
1447
1448
/**
1449
 * Evaluate tags like magic tags but through pods_var
1450
 *
1451
 * @param string|array|object $tags String to be evaluated
1452
 * @param bool $sanitize Whether to sanitize tags
1453
 *
1454
 * @return string
1455
 *
1456
 * @version 2.1
1457
 *
1458
 * @see pods_evaluate_tag
1459
 */
1460
function pods_evaluate_tags ( $tags, $sanitize = false ) {
1461
1462 View Code Duplication
	if ( is_array( $tags ) ) {
1463
		foreach ( $tags as $k => $tag ) {
1464
			$tags[ $k ] = pods_evaluate_tags( $tag, $sanitize );
1465
		}
1466
1467
		return $tags;
1468
	}
1469
	elseif ( is_object( $tags ) ) {
1470
		$tags = get_object_vars( $tags );
1471
1472
		foreach ( $tags as $k => $tag ) {
1473
			$tags[ $k ] = pods_evaluate_tags( $tag, $sanitize );
1474
		}
1475
1476
		$tags = (object) $tags;
1477
1478
		return $tags;
1479
	}
1480
1481
	$callback = 'pods_evaluate_tag';
1482
1483
	if ( true === $sanitize ) {
1484
		$callback = 'pods_evaluate_tag_sanitized';
1485
	}
1486
1487
	return preg_replace_callback( '/({@(.*?)})/m', $callback, (string) $tags );
1488
1489
}
1490
1491
/**
1492
 * Evaluate tag like magic tag but mapped through pods_v_sanitized
1493
 *
1494
 * @param string|array $tag
1495
 *
1496
 * @return string
1497
 *
1498
 * @version 2.1
1499
 *
1500
 * @see pods_evaluate_tag
1501
 */
1502
function pods_evaluate_tag_sanitized( $tag ) {
1503
1504
	return pods_evaluate_tag( $tag, true );
1505
1506
}
1507
1508
/**
1509
 * Evaluate tag like magic tag but mapped through pods_v
1510
 *
1511
 * @param string|array $tag
1512
 * @param bool $sanitize Whether to sanitize tags
1513
 *
1514
 * @return string
1515
 *
1516
 * @version 2.1
1517
 */
1518
function pods_evaluate_tag( $tag, $sanitize = false ) {
1519
1520
	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...
1521
1522
	// Handle pods_evaluate_tags
1523 View Code Duplication
	if ( is_array( $tag ) ) {
1524
		if ( !isset( $tag[ 2 ] ) && strlen( trim( $tag[ 2 ] ) ) < 1 ) {
1525
			return '';
1526
		}
1527
1528
		$tag = $tag[ 2 ];
1529
	}
1530
1531
	$tag = trim( $tag, ' {@}' );
1532
	$tag = explode( '.', $tag );
1533
1534 View Code Duplication
	if ( empty( $tag ) || !isset( $tag[ 0 ] ) || strlen( trim( $tag[ 0 ] ) ) < 1 ) {
1535
		return '';
1536
	}
1537
1538
	// Fix formatting that may be after the first .
1539
	if ( 2 < count( $tag ) ) {
1540
		$first_tag = $tag[ 0 ];
1541
		unset( $tag[ 0 ] );
1542
1543
		$tag = array(
1544
			$first_tag,
1545
			implode( '.', $tag )
1546
		);
1547
	}
1548
1549
	foreach ( $tag as $k => $v ) {
1550
		$tag[ $k ] = trim( $v );
1551
	}
1552
1553
	$value = '';
1554
1555
	$single_supported = array(
1556
		'template-url',
1557
		'stylesheet-url',
1558
		'site-url',
1559
		'home-url',
1560
		'admin-url',
1561
		'includes-url',
1562
		'content-url',
1563
		'plugins-url',
1564
		'network-site-url',
1565
		'network-home-url',
1566
		'network-admin-url',
1567
		'user-admin-url',
1568
		'prefix'
1569
	);
1570
1571
	if ( in_array( $tag[ 0 ], $single_supported ) ) {
1572
		$value = pods_v( '', $tag[ 0 ], '', true );
1573
	}
1574 View Code Duplication
	elseif ( 1 == count( $tag ) ) {
1575
		$value = pods_v( $tag[ 0 ], 'get', '', true );
1576
	}
1577 View Code Duplication
	elseif ( 2 == count( $tag ) ) {
1578
		$value = pods_v( $tag[ 1 ], $tag[ 0 ], '', true );
1579
	}
1580
1581
	$value = apply_filters( 'pods_evaluate_tag', $value, $tag );
1582
1583
	if ( is_array( $value ) && 1 == count( $value ) ) {
1584
		$value = current( $value );
1585
	}
1586
1587
	if ( is_array( $value ) ) {
1588
		$value = pods_serial_comma( $value );
1589
	}
1590
1591
	if ( $sanitize ) {
1592
		$value = pods_sanitize( $value );
1593
	}
1594
1595
	return $value;
1596
1597
}
1598
1599
/**
1600
 * Split an array into human readable text (Item, Item, and Item)
1601
 *
1602
 * @param array $value
1603
 * @param string $field
1604
 * @param array $fields
1605
 * @param string $and
1606
 * @param string $field_index
1607
 *
1608
 * @return string
1609
 *
1610
 * @since 2.0
1611
 */
1612
function pods_serial_comma ( $value, $field = null, $fields = null, $and = null, $field_index = null ) {
1613
    if ( is_object( $value ) )
1614
        $value = get_object_vars( $value );
1615
1616
    $defaults = array(
1617
        'field' => $field,
1618
        'fields' => $fields,
1619
        'and' => $and,
1620
        'field_index' => $field_index,
1621
        'separator' => ',',
1622
        'serial' => true
1623
    );
1624
1625 View Code Duplication
    if ( is_array( $field ) ) {
1626
        $defaults[ 'field' ] = null;
1627
1628
        $params = array_merge( $defaults, $field );
1629
    }
1630
    else
1631
        $params = $defaults;
1632
1633
    $params = (object) $params;
1634
1635
    $simple = false;
1636
1637
    if ( !empty( $params->fields ) && is_array( $params->fields ) && isset( $params->fields[ $params->field ] ) ) {
1638
        $params->field = $params->fields[ $params->field ];
1639
1640
	    $simple_tableless_objects = PodsForm::simple_tableless_objects();
1641
1642
        if ( !empty( $params->field ) && is_array( $params->field ) && in_array( $params->field[ 'type' ], PodsForm::tableless_field_types() ) ) {
1643
            if ( in_array( $params->field[ 'type' ], PodsForm::file_field_types() ) ) {
1644
                if ( null === $params->field_index )
1645
                    $params->field_index = 'guid';
1646
            }
1647
            elseif ( in_array( $params->field[ 'pick_object' ], $simple_tableless_objects ) )
1648
                $simple = true;
1649
            else {
1650
                $table = pods_api()->get_table_info( $params->field[ 'pick_object' ], $params->field[ 'pick_val' ], null, null, $params->field );
1651
1652
                if ( !empty( $table ) ) {
1653
                    if ( null === $params->field_index )
1654
                        $params->field_index = $table[ 'field_index' ];
1655
                }
1656
            }
1657
        }
1658
    }
1659
    else
1660
        $params->field = null;
1661
1662 View Code Duplication
    if ( $simple && is_array( $params->field ) && !is_array( $value ) && '' !== $value && null !== $value )
1663
        $value = PodsForm::field_method( 'pick', 'simple_value', $params->field[ 'name' ], $value, $params->field );
1664
1665
    if ( !is_array( $value ) )
1666
        return $value;
1667
1668
    if ( null === $params->and )
1669
        $params->and = ' ' . __( 'and', 'pods' ) . ' ';
1670
1671
    $last = '';
1672
1673
    $original_value = $value;
1674
1675
    if ( !empty( $value ) )
1676
        $last = array_pop( $value );
1677
1678 View Code Duplication
    if ( $simple && is_array( $params->field ) && !is_array( $last ) && '' !== $last && null !== $last )
1679
        $last = PodsForm::field_method( 'pick', 'simple_value', $params->field[ 'name' ], $last, $params->field );
1680
1681
    if ( is_array( $last ) ) {
1682
        if ( null !== $params->field_index && isset( $last[ $params->field_index ] ) )
1683
            $last = $last[ $params->field_index ];
1684
        elseif ( isset( $last[ 0 ] ) )
1685
            $last = $last[ 0 ];
1686
        elseif ( $simple )
1687
            $last = current( $last );
1688
        else
1689
            $last = '';
1690
    }
1691
1692
    if ( !empty( $value ) ) {
1693
        if ( null !== $params->field_index && isset( $original_value[ $params->field_index ] ) )
1694
            return $original_value[ $params->field_index ];
1695 View Code Duplication
        elseif ( null !== $params->field_index && isset( $value[ $params->field_index ] ) )
1696
            return $value[ $params->field_index ];
1697
        elseif ( !isset( $value[ 0 ] ) )
1698
            $value = array( $value );
1699
1700
        foreach ( $value as $k => $v ) {
1701 View Code Duplication
            if ( $simple && is_array( $params->field ) && !is_array( $v ) && '' !== $v && null !== $v )
1702
                $v = PodsForm::field_method( 'pick', 'simple_value', $params->field[ 'name' ], $v, $params->field );
1703
1704
            if ( is_array( $v ) ) {
1705
                if ( null !== $params->field_index && isset( $v[ $params->field_index ] ) )
1706
                    $v = $v[ $params->field_index ];
1707
                elseif ( $simple )
1708
                    $v = trim( implode( $params->separator . ' ', $v ), $params->separator . ' ' );
1709
                else {
1710
                    unset( $value[ $k ] );
1711
1712
                    continue;
1713
                }
1714
            }
1715
1716
            $value[ $k ] = $v;
1717
        }
1718
1719
        if ( 1 == count( $value ) || !$params->serial )
1720
            $value = trim( implode( $params->separator . ' ', $value ), $params->separator . ' ' );
1721
        else
1722
            $value = trim( implode( $params->separator . ' ', $value ), $params->separator . ' ' ) . apply_filters( 'pods_serial_comma', $params->separator . ' ', $value, $original_value, $params );
1723
1724
        $value = trim( $value );
1725
        $last = trim( $last );
1726
1727
        if ( 0 < strlen( $value ) && 0 < strlen( $last ) )
1728
            $value = $value . $params->and . $last;
1729
        elseif ( 0 < strlen( $last ) )
1730
            $value = $last;
1731
        else
1732
            $value = '';
1733
    }
1734
    else
1735
        $value = $last;
1736
1737
    $value = trim( $value, $params->separator . ' ' );
1738
1739
    $value = apply_filters( 'pods_serial_comma_value', $value, $original_value, $params );
1740
1741
    return (string) $value;
1742
}
1743
1744
/**
1745
 * Return a variable if a user is logged in or anonymous, or a specific capability
1746
 *
1747
 * @param mixed $anon Variable to return if user is anonymous (not logged in)
1748
 * @param mixed $user Variable to return if user is logged in
1749
 * @param string|array $capability Capability or array of Capabilities to check to return $user on
1750
 *
1751
 * @return mixed $user Variable to return if user is logged in (if logged in), otherwise $anon
1752
 *
1753
 * @since 2.0.5
1754
 */
1755
function pods_var_user ( $anon = false, $user = true, $capability = null ) {
1756
    $value = $anon;
1757
1758
    if ( is_user_logged_in() ) {
1759
        if ( empty( $capability ) )
1760
            $value = $user;
1761
        else {
1762
            $capabilities = (array) $capability;
1763
1764
            foreach ( $capabilities as $capability ) {
1765
                if ( current_user_can( $capability ) ) {
1766
                    $value = $user;
1767
1768
                    break;
1769
                }
1770
            }
1771
        }
1772
    }
1773
1774
    return $value;
1775
}
1776
1777
/**
1778
 * Take a one-level list of items and make it hierarchical
1779
 *
1780
 * @param array|object $list List of items
1781
 * @param array $args Array of parent, children, and id keys to use
1782
 *
1783
 * @return array|object
1784
 * @since 2.3
1785
 */
1786
function pods_hierarchical_list ( $list, $args = array() ) {
1787
    if ( empty( $args ) || ( !is_object( $list ) && !is_array( $list ) ) )
1788
        return $list;
1789
1790
    $defaults = array(
1791
        'id' => 'id',
1792
        'parent' => 'parent',
1793
        'children' => 'children',
1794
        'orphans' => true,
1795
        'found' => array(),
1796
        'list' => array(),
1797
        'current_depth' => -1
1798
    );
1799
1800
    $args = array_merge( $defaults, (array) $args );
1801
1802
    $list = pods_hierarchical_list_recurse( 0, $list, $args );
1803
1804
    return $list;
1805
}
1806
1807
/**
1808
 * Recurse list of items and make it hierarchical
1809
 *
1810
 * @param int $parent Parent ID
1811
 * @param array|object $list List of items
1812
 * @param array $args Array of parent, children, and id keys to use
1813
 *
1814
 * @return array|object
1815
 * @since 2.3
1816
 */
1817
function pods_hierarchical_list_recurse ( $parent, $list, &$args ) {
1818
    $new = array();
1819
1820
    $object = false;
1821
1822
    if ( is_object( $list ) ) {
1823
        $object = true;
1824
        $list = get_object_vars( $list );
1825
    }
1826
1827
    $args[ 'current_depth' ]++;
1828
1829
    $depth = $args[ 'current_depth' ];
1830
1831
    if ( 0 == $depth )
1832
        $args[ 'list' ] = $list;
1833
1834
    foreach ( $list as $k => $list_item ) {
1835
        if ( is_object( $list_item ) && isset( $list_item->{$args[ 'id' ]} ) ) {
1836
            $list_item->{$args[ 'parent' ]} = (int) pods_v( $args[ 'parent' ], $list_item );
1837
1838
            if ( is_array( $list_item->{$args[ 'parent' ]} ) && isset( $list_item->{$args[ 'parent' ]}[ $args[ 'id' ] ] ) && $parent == $list_item->{$args[ 'parent' ]}[ $args[ 'id' ] ] )
1839
                $list_item->{$args[ 'children' ]} = pods_hierarchical_list_recurse( $list_item->{$args[ 'id' ]}, $list, $args );
1840
            elseif ( $parent == $list_item->{$args[ 'parent' ]} || ( 0 == $depth && $parent == $list_item->{$args[ 'id' ]} ) )
1841
                $list_item->{$args[ 'children' ]} = pods_hierarchical_list_recurse( $list_item->{$args[ 'id' ]}, $list, $args );
1842
            else
1843
                continue;
1844
1845
            $args[ 'found' ][ $k ] = $list_item;
1846
        }
1847
        elseif ( is_array( $list_item ) && isset( $list_item[ $args[ 'id' ] ] ) ) {
1848
            $list_item[ $args[ 'parent' ] ] = (int) pods_v( $args[ 'parent' ], $list_item );
1849
1850
            if ( is_array( $list_item[ $args[ 'parent' ] ] ) && isset( $list_item[ $args[ 'parent' ] ][ $args[ 'id' ] ] ) && $parent == $list_item[ $args[ 'parent' ] ][ $args[ 'id' ] ] )
1851
                $list_item[ $args[ 'children' ] ] = pods_hierarchical_list_recurse( $list_item[ $args[ 'id' ] ], $list, $args );
1852
            elseif ( $parent == $list_item[ $args[ 'parent' ] ] || ( 0 == $depth && $parent == $list_item[ $args[ 'id' ] ] ) )
1853
                $list_item[ $args[ 'children' ] ] = pods_hierarchical_list_recurse( $list_item[ $args[ 'id' ] ], $list, $args );
1854
            else
1855
                continue;
1856
1857
            $args[ 'found' ][ $k ] = $list_item;
1858
        }
1859
        else
1860
            continue;
1861
1862
        $new[ $k ] = $list_item;
1863
1864
        $args[ 'current_depth' ] = $depth;
1865
    }
1866
1867
    if ( 0 == $depth && empty( $new ) && !empty( $list ) ) {
1868
        $first = current( array_slice( $list, 0, 1 ) );
1869
1870
        $new_parent = 0;
1871
1872
        $args[ 'current_depth' ] = -1;
1873
1874
        if ( is_object( $first ) && isset( $first->{$args[ 'parent' ]} ) )
1875
            $new_parent = (int) $first->{$args[ 'parent' ]};
1876
        elseif ( is_array( $first ) && isset( $first[ $args[ 'parent' ] ] ) )
1877
            $new_parent = (int) $first[ $args[ 'parent' ] ];
1878
1879
        if ( !empty( $new_parent ) )
1880
            $new = pods_hierarchical_list_recurse( $new_parent, $list, $args );
1881
    }
1882
1883
    if ( 0 == $depth ) {
1884
        $orphans = array();
1885
1886
        foreach ( $args[ 'list' ] as $k => $list_item ) {
1887
            if ( !isset( $args[ 'found' ][ $k ] ) )
1888
                $orphans[ $k ] = $list_item;
1889
        }
1890
1891
        if ( !empty( $orphans ) ) {
1892
            foreach ( $orphans as $orphan ) {
1893
                $new[] = $orphan;
1894
            }
1895
        }
1896
    }
1897
1898
    if ( $object )
1899
        $new = (object) $new;
1900
1901
    return $new;
1902
}
1903
1904
/**
1905
 * Take a one-level list of items and make it hierarchical for <select>
1906
 *
1907
 * @param array|object $list List of items
1908
 * @param array $args Array of index, parent, children, id, and prefix keys to use
1909
 * @param string $children_key Key to recurse children into
0 ignored issues
show
Bug introduced by
There is no parameter named $children_key. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1910
 *
1911
 * @return array|object
1912
 * @since 2.3
1913
 */
1914
function pods_hierarchical_select ( $list, $args = array() ) {
1915
    $object = false;
1916
1917
    if ( is_object( $list ) ) {
1918
        $object = true;
1919
        $list = get_object_vars( $list );
1920
    }
1921
1922
    $list = pods_hierarchical_list( $list, $args );
1923
1924
    $defaults = array(
1925
        'index' => 'name',
1926
        'children' => 'children',
1927
        'prefix' => '&nbsp;&nbsp;&nbsp;'
1928
    );
1929
1930
    $args = array_merge( $defaults, (array) $args );
1931
1932
    $list = pods_hierarchical_select_recurse( $list, $args, 0 );
1933
1934
    if ( $object )
1935
        $list = (object) $list;
1936
1937
    return $list;
1938
}
1939
1940
/**
1941
 * Recurse list of hierarchical data
1942
 *
1943
 * @param array|object $list List of items
0 ignored issues
show
Bug introduced by
There is no parameter named $list. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1944
 * @param array $args Array of children and prefix keys to use
1945
 * @param string $children_key Key to recurse children into
0 ignored issues
show
Bug introduced by
There is no parameter named $children_key. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1946
 *
1947
 * @see pods_hierarchical_select
1948
 * @return array
1949
 * @since 2.3
1950
 */
1951
function pods_hierarchical_select_recurse ( $items, $args, $depth = 0 ) {
1952
    $data = array();
1953
1954
    foreach ( $items as $k => $v ) {
1955
        $object = false;
1956
1957
        if ( is_object( $v ) ) {
1958
            $object = true;
1959
            $v = get_object_vars( $v );
1960
        }
1961
1962
        if ( isset( $v[ $args[ 'index' ] ] ) )
1963
            $v[ $args[ 'index' ] ] = ( 0 < $depth ? str_repeat( $args[ 'prefix' ], $depth ) : '' ) . $v[ $args[ 'index' ] ];
1964
1965
        $children = array();
1966
1967
        if ( isset( $v[ $args[ 'children' ] ] ) ) {
1968
            if ( !empty( $v[ $args[ 'children' ] ] ) )
1969
                $children = pods_hierarchical_select_recurse( $v[ $args[ 'children' ] ], $args, ( $depth + 1 ) );
1970
1971
            unset( $v[ $args[ 'children' ] ] );
1972
        }
1973
1974
        if ( $object )
1975
            $v = (object) $v;
1976
1977
        $data[ $k ] = $v;
1978
1979
        if ( !empty( $children ) ) {
1980
            foreach ( $children as $ck => $cv ) {
1981
                $data[ $ck ] = $cv;
1982
            }
1983
        }
1984
    }
1985
1986
    return $data;
1987
}
1988
1989
/**
1990
 * Filters a list of objects or arrays, based on a set of key => value arguments.
1991
 *
1992
 * @param array|object $list An array or object, with objects/arrays to filter
1993
 * @param array $args An array of key => value arguments to match against each object
1994
 * @param string $operator The logical operation to perform:
1995
 *    'AND' means all elements from the array must match;
1996
 *    'OR' means only one element needs to match;
1997
 *    'NOT' means no elements may match.
1998
 *   The default is 'AND'.
1999
 *
2000
 * @see wp_list_filter
2001
 * @return array
2002
 * @since 2.3
2003
 */
2004
function pods_list_filter ( $list, $args = array(), $operator = 'AND' ) {
2005
    if ( empty( $args ) )
2006
        return $list;
2007
2008
    $data = $list;
2009
2010
    $object = false;
2011
2012
    if ( is_object( $data ) ) {
2013
        $object = true;
2014
        $data = get_object_vars( $data );
2015
    }
2016
2017
    $operator = strtoupper( $operator );
2018
    $count = count( $args );
2019
    $filtered = array();
2020
2021
    foreach ( $data as $key => $obj ) {
2022
        $to_match = $obj;
2023
2024
        if ( is_object( $to_match ) )
2025
            $to_match = get_object_vars( $to_match );
2026
        elseif ( !is_array( $to_match ) )
2027
            continue;
2028
2029
        $matched = 0;
2030
2031
        foreach ( $args as $m_key => $m_value ) {
2032
            if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] )
2033
                $matched++;
2034
        }
2035
2036
        if ( 'AND' == $operator && $matched == $count )
2037
            $filtered[ $key ] = $obj;
2038
        elseif ( 'OR' == $operator && $matched > 0 )
2039
            $filtered[ $key ] = $obj;
2040
        elseif ( 'NOT' == $operator && 0 == $matched )
2041
            $filtered[ $key ] = $obj;
2042
        else
2043
            continue;
2044
    }
2045
2046
    if ( $object )
2047
        $filtered = (object) $filtered;
2048
2049
    return $filtered;
2050
}
2051