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

general.php ➔ pods_field_raw()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 13
nc 8
nop 4
dl 0
loc 25
rs 8.439
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 18 and the first side effect is on line 101.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * @package Pods\Global\Functions\General
4
 */
5
/**
6
 * Standardize queries and error reporting. It replaces @wp_ with $wpdb->prefix.
7
 *
8
 * @see   PodsData::query
9
 *
10
 * @param string $sql              SQL Query
11
 * @param string $error            (optional) The failure message
12
 * @param string $results_error    (optional) Throw an error if a records are found
0 ignored issues
show
Documentation introduced by
Should the type for parameter $results_error not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
13
 * @param string $no_results_error (optional) Throw an error if no records are found
0 ignored issues
show
Documentation introduced by
Should the type for parameter $no_results_error not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
14
 *
15
 * @return array|bool|mixed|null|void
16
 * @since 2.0
17
 */
18
function pods_query( $sql, $error = 'Database Error', $results_error = null, $no_results_error = null ) {
19
20
	$podsdata = pods_data();
21
22
	$sql = apply_filters( 'pods_query_sql', $sql, $error, $results_error, $no_results_error );
23
	$sql = $podsdata->get_sql( $sql );
24
25
	if ( is_array( $error ) ) {
26
		if ( ! is_array( $sql ) ) {
27
			$sql = array( $sql, $error );
28
		}
29
30
		$error = 'Database Error';
31
	}
32
33
	if ( 1 === (int) pods_v( 'pods_debug_sql_all' ) && is_user_logged_in() && pods_is_admin( array( 'pods' ) ) ) {
34
		$debug_sql = $sql;
35
36
		echo '<textarea cols="100" rows="24">';
37
38
		if ( is_array( $debug_sql ) ) {
39
			$debug_sql = print_r( $debug_sql, true );
40
		}
41
42
		echo esc_textarea( $debug_sql );
43
44
		echo '</textarea>';
45
	}
46
47
	return $podsdata->query( $sql, $error, $results_error, $no_results_error );
48
}
49
50
/**
51
 * Standardize filters / actions
52
 *
53
 * @param string $scope Scope of the filter / action (ui for PodsUI, api for PodsAPI, etc..)
54
 * @param string $name  Name of filter / action to run
55
 * @param mixed  $args  (optional) Arguments to send to filter / action
56
 * @param object $obj   (optional) Object to reference for filter / action
0 ignored issues
show
Documentation introduced by
Should the type for parameter $obj not be object|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
57
 *
58
 * @return mixed
59
 * @since 2.0
60
 * @todo  Need to figure out how to handle $scope = 'pods' for the Pods class
61
 */
62
function pods_do_hook( $scope, $name, $args = null, $obj = null ) {
63
64
	// Add filter name
65
	array_unshift( $args, "pods_{$scope}_{$name}" );
66
67
	// Add object
68
	$args[] = $obj;
69
70
	// Run apply_filters and give it all the arguments
71
	$args = call_user_func_array( 'apply_filters', $args );
72
73
	return $args;
74
}
75
76
/**
77
 * Message / Notice handling for Admin UI
78
 *
79
 * @param string $message The notice / error message shown
80
 * @param string $type    Message type
0 ignored issues
show
Documentation introduced by
Should the type for parameter $type not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
81
 *
82
 * @return void
83
 */
84
function pods_message( $message, $type = null ) {
85
86
	if ( empty( $type ) || ! in_array( $type, array( 'notice', 'error' ), true ) ) {
87
		$type = 'notice';
88
	}
89
90
	$class = '';
91
92
	if ( 'notice' === $type ) {
93
		$class = 'updated';
94
	} elseif ( 'error' === $type ) {
95
		$class = 'error';
96
	}
97
98
	echo '<div id="message" class="' . esc_attr( $class ) . ' fade"><p>' . $message . '</p></div>';
99
}
100
101
$GLOBALS['pods_errors'] = array();
102
103
/**
104
 * Error Handling which throws / displays errors
105
 *
106
 * @param string|array        $error The error message(s) to be thrown / displayed.
107
 * @param object|boolean|null $obj   If $obj->display_errors is set and is set to true it will display errors, if
108
 *                                   boolean and is set to true it will display errors.
109
 *
110
 * @throws Exception Throws exception for developer-oriented error handling.
111
 *
112
 * @return mixed
113
 *
114
 * @since 2.0
115
 */
116
function pods_error( $error, $obj = null ) {
117
118
	global $pods_errors;
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...
119
120
	$error_mode = 'exception';
121
122
	if ( is_object( $obj ) && isset( $obj->display_errors ) ) {
123
		if ( true === $obj->display_errors ) {
124
			$error_mode = 'exit';
125
		} elseif ( false === $obj->display_errors ) {
126
			$error_mode = 'exception';
127
		} else {
128
			$error_mode = $obj->display_errors;
129
		}
130
	} elseif ( true === $obj ) {
131
		$error_mode = 'exit';
132
	} elseif ( false === $obj ) {
133
		$error_mode = 'exception';
134
	} elseif ( is_string( $obj ) ) {
135
		$error_mode = $obj;
136
	}
137
138
	if ( is_object( $error ) && 'Exception' === get_class( $error ) ) {
139
		$error = $error->getMessage();
140
141
		$error_mode = 'exception';
142
	}
143
144
	/**
145
	 * @var string $error_mode Throw an exception, exit with the message, return false, or return WP_Error
146
	 */
147
	if ( ! in_array( $error_mode, array( 'exception', 'exit', 'false', 'wp_error' ), true ) ) {
148
		$error_mode = 'exception';
149
	}
150
151
	/**
152
	 * Filter the error mode used by pods_error.
153
	 *
154
	 * @param string                     $error_mode Error mode
155
	 * @param string|array               $error      Error message(s)
156
	 * @param object|boolean|string|null $obj
157
	 */
158
	$error_mode = apply_filters( 'pods_error_mode', $error_mode, $error, $obj );
159
160
	if ( is_array( $error ) ) {
161
		$error = array_map( 'wp_kses_post', $error );
162
163
		if ( 1 === count( $error ) ) {
164
			$error = current( $error );
165
166
			// Create WP_Error for use later.
167
			$wp_error = new WP_Error( 'pods-error-' . md5( $error ), $error );
168
		} else {
169
			// Create WP_Error for use later.
170
			$wp_error = new WP_Error();
171
172
			foreach ( $error as $error_message ) {
173
				$wp_error->add( 'pods-error-' . md5( $error_message ), $error_message );
174
			}
175
176
			if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
177
				$error = __( 'The following issue occurred:', 'pods' ) . "\n\n- " . implode( "\n- ", $error );
178
			} else {
179
				$error = __( 'The following issues occurred:', 'pods' ) . "\n<ul><li>" . implode( "</li>\n<li>", $error ) . '</li></ul>';
180
			}
181
		}
182
	} else {
183
		if ( is_object( $error ) ) {
184
			$error = __( 'An unknown error has occurred', 'pods' );
185
		}
186
187
		$error = wp_kses_post( $error );
188
189
		// Create WP_Error for use later.
190
		$wp_error = new WP_Error( 'pods-error-' . md5( $error ), $error );
191
	}//end if
192
193
	$last_error = $pods_errors;
194
195
	$pods_errors = array();
196
197
	if ( $last_error === $error && 'exception' === $error_mode ) {
198
		$error_mode = 'exit';
199
	}
200
201
	if ( ! empty( $error ) ) {
202
		if ( 'exception' === $error_mode ) {
203
			$exception_bypass = apply_filters( 'pods_error_exception', null, $error );
204
205
			if ( null !== $exception_bypass ) {
206
				return $exception_bypass;
207
			}
208
209
			$pods_errors = $error;
210
211
			set_exception_handler( 'pods_error' );
212
213
			throw new Exception( $error );
214
		} elseif ( 'exit' === $error_mode ) {
215
			$die_bypass = apply_filters( 'pods_error_die', null, $error );
216
217
			if ( null !== $die_bypass ) {
218
				return $die_bypass;
219
			}
220
221
			// die with error
222
			if ( ! defined( 'DOING_AJAX' ) && ! headers_sent() && ( is_admin() || false !== strpos( $_SERVER['REQUEST_URI'], 'wp-comments-post.php' ) ) ) {
223
				wp_die( $error, '', array( 'back_link' => true ) );
224
			} else {
225
				die( sprintf( '<e>%s</e>', $error ) );
226
			}
227
		} elseif ( 'wp_error' === $error_mode ) {
228
			return $wp_error;
229
		}//end if
230
	}//end if
231
232
	return false;
233
234
}
235
236
/**
237
 * Debug variable used in pods_debug to count the instances debug is used
238
 */
239
global $pods_debug;
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...
240
$pods_debug = 0;
241
/**
242
 * Debugging common issues using this function saves a few lines and is compatible with
243
 *
244
 * @param mixed   $debug The error message to be thrown / displayed
245
 * @param boolean $die   If set to true, a die() will occur, if set to (int) 2 then a wp_die() will occur
246
 * @param string  $prefix
247
 *
248
 * @return void
249
 *
250
 * @since 2.0
251
 */
252
function pods_debug( $debug = '_null', $die = false, $prefix = '_null' ) {
253
254
	global $pods_debug;
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...
255
256
	$pods_debug ++;
257
258
	ob_start();
259
260
	if ( '_null' !== $prefix ) {
261
		var_dump( $prefix );
0 ignored issues
show
Security Debugging Code introduced by
var_dump($prefix); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
262
	}
263
264
	if ( '_null' !== $debug ) {
265
		var_dump( $debug );
266
	} else {
267
		var_dump( 'Pods Debug #' . $pods_debug );
268
	}
269
270
	$debug = ob_get_clean();
271
272
	if ( false === strpos( $debug, "<pre class='xdebug-var-dump'" ) && ( ! ini_get( 'xdebug.overload_var_dump' ) && ! ini_get( 'html_errors' ) ) ) {
273
		if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
274
			$debug = esc_html( $debug );
275
		}
276
277
		$debug = '<pre>' . $debug . '</pre>';
278
	}
279
280
	$debug = '<e>' . $debug;
281
282
	if ( 2 === $die ) {
283
		wp_die( $debug, '', array( 'back_link' => true ) );
284
	} elseif ( true === $die ) {
285
		die( $debug );
286
	}
287
288
	echo $debug;
289
}
290
291
/**
292
 * Determine if user has admin access
293
 *
294
 * @param string|array $cap Additional capabilities to check
0 ignored issues
show
Documentation introduced by
Should the type for parameter $cap not be string|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
295
 *
296
 * @return bool Whether user has admin access
297
 *
298
 * @since 2.3.5
299
 */
300
function pods_is_admin( $cap = null ) {
301
302
	if ( is_user_logged_in() ) {
303
		// Default is_super_admin() checks against this.
304
		$pods_admin_capabilities = array(
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $pods_admin_capabilities exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
305
			'delete_users',
306
		);
307
308
		$pods_admin_capabilities = apply_filters( 'pods_admin_capabilities', $pods_admin_capabilities, $cap );
309
310
		if ( is_multisite() && is_super_admin() ) {
311
			return apply_filters( 'pods_is_admin', true, $cap, '_super_admin' );
312
		}
313
314
		if ( empty( $cap ) ) {
315
			$cap = array();
316
		} else {
317
			$cap = (array) $cap;
318
		}
319
320
		$cap = array_unique( array_filter( array_merge( $pods_admin_capabilities, $cap ) ) );
321
322
		foreach ( $cap as $capability ) {
323
			if ( current_user_can( $capability ) ) {
324
				return apply_filters( 'pods_is_admin', true, $cap, $capability );
325
			}
326
		}
327
	}//end if
328
329
	return apply_filters( 'pods_is_admin', false, $cap, null );
330
}
331
332
/**
333
 * Determine if Developer Mode is enabled
334
 *
335
 * @return bool Whether Developer Mode is enabled
336
 *
337
 * @since 2.3
338
 */
339
function pods_developer() {
340
341
	if ( defined( 'PODS_DEVELOPER' ) && PODS_DEVELOPER ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return (bool) (defined('...R') && PODS_DEVELOPER);.
Loading history...
342
		return true;
343
	}
344
345
	return false;
346
}
347
348
/**
349
 * Determine if Tableless Mode is enabled
350
 *
351
 * @return bool Whether Tableless Mode is enabled
352
 *
353
 * @since 2.3
354
 */
355
function pods_tableless() {
356
357
	if ( defined( 'PODS_TABLELESS' ) && PODS_TABLELESS ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return defined('PODS_TAB...SS') && PODS_TABLELESS;.
Loading history...
358
		return true;
359
	}
360
361
	return false;
362
}
363
364
/**
365
 * Determine if Strict Mode is enabled
366
 *
367
 * @param bool $include_debug Whether to include WP_DEBUG in strictness level
368
 *
369
 * @return bool Whether Strict Mode is enabled
370
 *
371
 * @since 2.3.5
372
 */
373
function pods_strict( $include_debug = true ) {
374
375
	if ( defined( 'PODS_STRICT' ) && PODS_STRICT ) {
376
		// Deprecated PODS_STRICT_MODE since 2.3.5
377
		return true;
378
	} elseif ( defined( 'PODS_STRICT_MODE' ) && PODS_STRICT_MODE && pods_allow_deprecated( false ) ) {
379
		return true;
380
	} elseif ( $include_debug && defined( 'WP_DEBUG' ) && WP_DEBUG ) {
381
		return true;
382
	}
383
384
	return false;
385
386
}
387
388
/**
389
 * Determine if Deprecated Mode is enabled
390
 *
391
 * @param bool $include_debug Whether to include strict mode
0 ignored issues
show
Bug introduced by
There is no parameter named $include_debug. 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...
392
 *
393
 * @return bool Whether Deprecated Mode is enabled
394
 *
395
 * @since 2.3.10
396
 */
397
function pods_allow_deprecated( $strict = true ) {
398
399
	if ( $strict && pods_strict() ) {
400
		return false;
401
	} elseif ( ! defined( 'PODS_DEPRECATED' ) || PODS_DEPRECATED ) {
402
		return true;
403
	}
404
405
	return false;
406
407
}
408
409
/**
410
 * Determine if Pods API Caching is enabled
411
 *
412
 * @return bool Whether Pods API Caching is enabled
413
 *
414
 * @since 2.3.9
415
 */
416
function pods_api_cache() {
417
418
	if ( defined( 'PODS_API_CACHE' ) && ! PODS_API_CACHE ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !(defined('PODS_A...') && !PODS_API_CACHE);.
Loading history...
419
		return false;
420
	}
421
422
	return true;
423
}
424
425
/**
426
 * Marks a function as deprecated and informs when it has been used.
427
 *
428
 * There is a hook deprecated_function_run that will be called that can be used
429
 * to get the backtrace up to what file and function called the deprecated
430
 * function.
431
 *
432
 * The current behavior is to trigger a user error if WP_DEBUG is true.
433
 *
434
 * This function is to be used in every function that is deprecated.
435
 *
436
 * @uses  do_action() Calls 'deprecated_function_run' and passes the function name, what to use instead,
437
 *   and the version the function was deprecated in.
438
 * @uses  apply_filters() Calls 'deprecated_function_trigger_error' and expects boolean value of true to do
439
 *   trigger or false to not trigger error.
440
 *
441
 * @param string $function    The function that was called
442
 * @param string $version     The version of WordPress that deprecated the function
443
 * @param string $replacement Optional. The function that should have been called
0 ignored issues
show
Documentation introduced by
Should the type for parameter $replacement not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
444
 *
445
 * @since 2.0
446
 */
447
function pods_deprecated( $function, $version, $replacement = null ) {
448
449
	if ( ! version_compare( $version, PODS_VERSION, '<=' ) && ! version_compare( $version . '-a-0', PODS_VERSION, '<=' ) ) {
450
		return;
451
	}
452
453
	do_action( 'deprecated_function_run', $function, $replacement, $version );
454
455
	// Allow plugin to filter the output error trigger
456
	if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
457
		if ( ! is_null( $replacement ) ) {
458
			$error = __( '%1$s has been <strong>deprecated</strong> since Pods version %2$s! Use %3$s instead.', 'pods' );
459
		} else {
460
			$error = __( '%1$s has been <strong>deprecated</strong> since Pods version %2$s with no alternative available.', 'pods' );
461
		}
462
463
		trigger_error( sprintf( $error, $function, $version, $replacement ) );
464
	}
465
}
466
467
/**
468
 * Inline help
469
 *
470
 * @param string $text Help text
471
 * @param string $url  Documentation URL
0 ignored issues
show
Documentation introduced by
Should the type for parameter $url not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
472
 *
473
 * @return void
474
 *
475
 * @since 2.0
476
 */
477
function pods_help( $text, $url = null ) {
478
479
	if ( ! wp_script_is( 'jquery-qtip2', 'registered' ) ) {
480
		wp_register_script( 'jquery-qtip2', PODS_URL . 'ui/js/jquery.qtip.min.js', array( 'jquery' ), '2.2' );
481
	} elseif ( ! wp_script_is( 'jquery-qtip2', 'queue' ) && ! wp_script_is( 'jquery-qtip2', 'to_do' ) && ! wp_script_is( 'jquery-qtip2', 'done' ) ) {
482
		wp_enqueue_script( 'jquery-qtip2' );
483
	}
484
485
	if ( ! wp_script_is( 'pods-qtip-init', 'registered' ) ) {
486
		wp_register_script(
487
			'pods-qtip-init', PODS_URL . 'ui/js/qtip.js', array(
488
				'jquery',
489
				'jquery-qtip2',
490
			), PODS_VERSION
491
		);
492
		wp_enqueue_script( 'pods-qtip-init' );
493
	} elseif ( ! wp_script_is( 'pods-qtip-init', 'queue' ) && ! wp_script_is( 'pods-qtip-init', 'to_do' ) && ! wp_script_is( 'pods-qtip-init', 'done' ) ) {
494
		wp_enqueue_script( 'pods-qtip-init' );
495
	}
496
497
	if ( is_array( $text ) ) {
498
		if ( isset( $text[1] ) ) {
499
			$url = $text[1];
500
		}
501
502
		$text = $text[0];
503
	}
504
505
	if ( 'help' === $text ) {
506
		return;
507
	}
508
509
	if ( 0 < strlen( $url ) ) {
510
		$text .= '<br /><br /><a href="' . $url . '" target="_blank">' . __( 'Find out more', 'pods' ) . ' &raquo;</a>';
511
	}
512
513
	echo '<img src="' . esc_url( PODS_URL ) . 'ui/images/help.png" alt="' . esc_attr( $text ) . '" class="pods-icon pods-qtip" />';
514
}
515
516
/**
517
 * Check whether or not something is a specific version minimum and/or maximum
518
 *
519
 * @param string $minimum_version Minimum version
520
 * @param string $comparison      Comparison operator
521
 * @param string $maximum_version Maximum version
0 ignored issues
show
Documentation introduced by
Should the type for parameter $maximum_version not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
522
 *
523
 * @return bool
524
 */
525
function pods_version_check( $what, $minimum_version, $comparison = '<=', $maximum_version = null ) {
526
527
	global $wp_version, $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...
528
529
	if ( 'php' === $what ) {
530
		$version = phpversion();
531
	} elseif ( 'mysql' === $what ) {
532
		$version = $wpdb->db_version();
533
	} else {
534
		$version = $wp_version;
535
	}
536
537
	if ( ! empty( $minimum_version ) && ! version_compare( $minimum_version, $version, $comparison ) ) {
538
		return false;
539
	}
540
541
	if ( ! empty( $maximum_version ) && ! version_compare( $version, $maximum_version, $comparison ) ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !(!empty($maximum...version, $comparison));.
Loading history...
542
		return false;
543
	}
544
545
	return true;
546
}
547
548
/**
549
 * Run a Pods Helper
550
 *
551
 * @param string $helper_name Helper Name
552
 * @param string $value       Value to run Helper on
0 ignored issues
show
Documentation introduced by
Should the type for parameter $value not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
553
 * @param string $name        Field name.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
554
 *
555
 * @return bool
556
 * @since 1.7.5
557
 */
558
function pods_helper( $helper_name, $value = null, $name = null ) {
559
560
	return pods()->helper( $helper_name, $value, $name );
561
}
562
563
/**
564
 * Get the full URL of the current page
565
 *
566
 * @return string Full URL of the current page
567
 * @since 2.3
568
 */
569
function pods_current_url() {
570
571
	$url = 'http';
572
573
	if ( isset( $_SERVER['HTTPS'] ) && 'off' !== $_SERVER['HTTPS'] && 0 !== $_SERVER['HTTPS'] ) {
574
		$url = 'https';
575
	}
576
577
	$url .= '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
578
579
	return apply_filters( 'pods_current_url', $url );
580
}
581
582
/**
583
 * Find out if the current page has a valid $pods
584
 *
585
 * @param object $object The Pod Object currently checking (optional)
0 ignored issues
show
Documentation introduced by
Should the type for parameter $object not be object|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
586
 *
587
 * @return bool
588
 * @since 2.0
589
 */
590
function is_pod( $object = null ) {
591
592
	global $pods, $post;
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...
593
594
	if ( is_object( $object ) && isset( $object->pod ) && ! empty( $object->pod ) ) {
595
		return true;
596
	} elseif ( is_object( $pods ) && isset( $pods->pod ) && ! empty( $pods->pod ) ) {
597
		return true;
598
	} elseif ( is_object( $post ) && isset( $post->post_type ) && pods_api()->pod_exists( $post->post_type, 'post_type' ) ) {
599
		return true;
600
	}
601
602
	return false;
603
}
604
605
/**
606
 * See if the current user has a certain privilege
607
 *
608
 * @param mixed  $privs  The privilege name or names (array if multiple)
609
 * @param string $method The access method ("AND", "OR")
610
 *
611
 * @return bool
612
 * @since 1.2.0
613
 */
614
function pods_access( $privs, $method = 'OR' ) {
615
616
	// Convert $privs to an array
617
	$privs = (array) $privs;
618
619
	// Convert $method to uppercase
620
	$method = strtoupper( $method );
621
622
	$check = apply_filters( 'pods_access', null, $privs, $method );
623
	if ( null !== $check && is_bool( $check ) ) {
624
		return $check;
625
	}
626
627
	if ( ! is_user_logged_in() ) {
628
		return false;
629
	}
630
631
	if ( pods_is_admin( array( 'pods', 'pods_content' ) ) ) {
632
		return true;
633
	}
634
635
	// Store approved privs when using "AND"
636
	$approved_privs = array();
637
638
	// Loop through the user's roles
639
	foreach ( $privs as $priv ) {
640
		if ( 0 === strpos( $priv, 'pod_' ) ) {
641
			$priv = pods_str_replace( 'pod_', 'pods_edit_', $priv, 1 );
642
		}
643
644
		if ( 0 === strpos( $priv, 'manage_' ) ) {
645
			$priv = pods_str_replace( 'manage_', 'pods_', $priv, 1 );
646
		}
647
648
		if ( current_user_can( $priv ) ) {
649
			if ( 'OR' === $method ) {
650
				return true;
651
			}
652
653
			$approved_privs[ $priv ] = true;
654
		}
655
	}
656
	if ( 'AND' === strtoupper( $method ) ) {
657
		foreach ( $privs as $priv ) {
658
			if ( 0 === strpos( $priv, 'pod_' ) ) {
659
				$priv = pods_str_replace( 'pod_', 'pods_edit_', $priv, 1 );
660
			}
661
662
			if ( 0 === strpos( $priv, 'manage_' ) ) {
663
				$priv = pods_str_replace( 'manage_', 'pods_', $priv, 1 );
664
			}
665
666
			if ( ! isset( $approved_privs[ $priv ] ) ) {
667
				return false;
668
			}
669
		}
670
671
		return true;
672
	}
673
674
	return false;
675
}
676
677
/**
678
 * Shortcode support for use anywhere that support WP Shortcodes
679
 *
680
 * @param array  $tags    An associative array of shortcode properties
681
 * @param string $content A string that represents a template override
0 ignored issues
show
Documentation introduced by
Should the type for parameter $content not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
682
 *
683
 * @return string
684
 * @since 1.6.7
685
 */
686
function pods_shortcode( $tags, $content = null ) {
687
688
	if ( defined( 'PODS_DISABLE_SHORTCODE' ) && PODS_DISABLE_SHORTCODE ) {
689
		return '';
690
	}
691
692
	// For enforcing pagination parameters when not displaying pagination
693
	$page   = 1;
694
	$offset = 0;
695
696
	if ( isset( $tags['page'] ) ) {
697
		$page = (int) $tags['page'];
698
		$page = max( $page, 1 );
699
	}
700
701
	if ( isset( $tags['offset'] ) ) {
702
		$offset = (int) $tags['offset'];
703
		$offset = max( $offset, 0 );
704
	}
705
706
	$defaults = array(
707
		'use_current'         => false,
708
		'name'                => null,
709
		'id'                  => null,
710
		'slug'                => null,
711
		'select'              => null,
712
		'join'                => null,
713
		'order'               => null,
714
		'orderby'             => null,
715
		'limit'               => null,
716
		'where'               => null,
717
		'having'              => null,
718
		'groupby'             => null,
719
		'search'              => true,
720
		'pagination'          => false,
721
		'page'                => null,
722
		'offset'              => null,
723
		'filters'             => false,
724
		'filters_label'       => null,
725
		'filters_location'    => 'before',
726
		'pagination_label'    => null,
727
		'pagination_location' => 'after',
728
		'field'               => null,
729
		'col'                 => null,
730
		'template'            => null,
731
		'pods_page'           => null,
732
		'helper'              => null,
733
		'form'                => null,
734
		'fields'              => null,
735
		'label'               => null,
736
		'thank_you'           => null,
737
		'view'                => null,
738
		'cache_mode'          => 'none',
739
		'expires'             => 0,
740
		'shortcodes'          => false,
741
	);
742
743
	if ( ! empty( $tags ) ) {
744
		$tags = array_merge( $defaults, $tags );
745
	} else {
746
		$tags = $defaults;
747
	}
748
749
	$tags = apply_filters( 'pods_shortcode', $tags );
750
751
	$tags['pagination']  = filter_var( $tags['pagination'], FILTER_VALIDATE_BOOLEAN );
752
	$tags['search']      = filter_var( $tags['pagination'], FILTER_VALIDATE_BOOLEAN );
753
	$tags['use_current'] = filter_var( $tags['use_current'], FILTER_VALIDATE_BOOLEAN );
754
755
	if ( empty( $content ) ) {
756
		$content = null;
757
	}
758
759
	// Allow views only if not targeting a file path (must be within theme)
760
	if ( 0 < strlen( $tags['view'] ) ) {
761
		$return = '';
762
763
		if ( ! file_exists( $tags['view'] ) ) {
764
			$return = pods_view( $tags['view'], null, (int) $tags['expires'], $tags['cache_mode'], true );
765
766
			if ( $tags['shortcodes'] && defined( 'PODS_SHORTCODE_ALLOW_SUB_SHORTCODES' ) && PODS_SHORTCODE_ALLOW_SUB_SHORTCODES ) {
767
				$return = do_shortcode( $return );
768
			}
769
		}
770
771
		return $return;
772
	}
773
774
	if ( ! $tags['use_current'] && empty( $tags['name'] ) ) {
775
		if ( in_the_loop() || is_singular() ) {
776
			$pod = pods( get_post_type(), get_the_ID(), false );
777
778
			if ( ! empty( $pod ) ) {
779
				$tags['name'] = get_post_type();
780
				$id           = $tags['id'] = get_the_ID();
781
			}
782
		}
783
784
		if ( empty( $tags['name'] ) ) {
785
			return '<p>Please provide a Pod name</p>';
786
		}
787
	}
788
789
	if ( ! empty( $tags['col'] ) ) {
790
		$tags['field'] = $tags['col'];
791
792
		unset( $tags['col'] );
793
	}
794
795
	if ( ! empty( $tags['order'] ) ) {
796
		$tags['orderby'] = $tags['order'];
797
798
		unset( $tags['order'] );
799
	}
800
801
	if ( empty( $content ) && empty( $tags['pods_page'] ) && empty( $tags['template'] ) && empty( $tags['field'] ) && empty( $tags['form'] ) ) {
802
		return '<p>Please provide either a template or field name</p>';
803
	}
804
805
	if ( ! $tags['use_current'] && ! isset( $id ) ) {
806
		// id > slug (if both exist)
807
		$id = null;
808
809
		if ( ! empty( $tags['slug'] ) ) {
810
			$id = $tags['slug'];
811
812
			if ( defined( 'PODS_SHORTCODE_ALLOW_EVALUATE_TAGS' ) && PODS_SHORTCODE_ALLOW_EVALUATE_TAGS ) {
813
				$id = pods_evaluate_tags( $id );
814
			}
815
		}
816
817
		if ( ! empty( $tags['id'] ) ) {
818
			$id = $tags['id'];
819
820
			if ( defined( 'PODS_SHORTCODE_ALLOW_EVALUATE_TAGS' ) && PODS_SHORTCODE_ALLOW_EVALUATE_TAGS ) {
821
				$id = pods_evaluate_tags( $id );
822
			}
823
824
			if ( is_numeric( $id ) ) {
825
				$id = absint( $id );
826
			}
827
		}
828
	}//end if
829
830
	if ( ! isset( $pod ) ) {
831
		if ( ! $tags['use_current'] ) {
832
			$pod = pods( $tags['name'], $id );
0 ignored issues
show
Bug introduced by
The variable $id does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
833
		} else {
834
			$pod = pods();
835
			$id  = $pod->id();
836
		}
837
	}
838
839
	if ( empty( $pod ) || ! $pod->valid() ) {
840
		return '<p>Pod not found</p>';
841
	}
842
843
	$found = 0;
844
845
	$is_singular = ( ! empty( $id ) || $tags['use_current'] );
846
847
	if ( ! $is_singular ) {
848
		$params = array();
849
850
		if ( ! defined( 'PODS_DISABLE_SHORTCODE_SQL' ) || ! PODS_DISABLE_SHORTCODE_SQL ) {
851
			if ( 0 < strlen( $tags['orderby'] ) ) {
852
				$params['orderby'] = $tags['orderby'];
853
			}
854
855
			if ( 0 < strlen( $tags['where'] ) ) {
856
				$params['where'] = $tags['where'];
857
858
				if ( defined( 'PODS_SHORTCODE_ALLOW_EVALUATE_TAGS' ) && PODS_SHORTCODE_ALLOW_EVALUATE_TAGS ) {
859
					$params['where'] = pods_evaluate_tags( html_entity_decode( $params['where'] ) );
860
				}
861
			}
862
863
			if ( 0 < strlen( $tags['having'] ) ) {
864
				$params['having'] = $tags['having'];
865
866
				if ( defined( 'PODS_SHORTCODE_ALLOW_EVALUATE_TAGS' ) && PODS_SHORTCODE_ALLOW_EVALUATE_TAGS ) {
867
					$params['having'] = pods_evaluate_tags( html_entity_decode( $params['having'] ) );
868
				}
869
			}
870
871
			if ( 0 < strlen( $tags['groupby'] ) ) {
872
				$params['groupby'] = $tags['groupby'];
873
			}
874
875
			if ( 0 < strlen( $tags['select'] ) ) {
876
				$params['select'] = $tags['select'];
877
			}
878
			if ( 0 < strlen( $tags['join'] ) ) {
879
				$params['join'] = $tags['join'];
880
			}
881
		}//end if
882
883
		// Forms require params set
884
		if ( ! empty( $params ) || empty( $tags['form'] ) ) {
885
			if ( ! empty( $tags['limit'] ) ) {
886
				$params['limit'] = (int) $tags['limit'];
887
			}
888
889
			$params['search'] = $tags['search'];
890
891
			$params['pagination'] = $tags['pagination'];
892
893
			// If we aren't displaying pagination, we need to enforce page/offset
894
			if ( ! $params['pagination'] ) {
895
				$params['page']   = $page;
896
				$params['offset'] = $offset;
897
898
				// Force pagination on, we need it and we're enforcing page/offset
899
				$params['pagination'] = true;
900
			} else {
901
				// If we are displaying pagination, allow page/offset override only if *set*
902
				if ( isset( $tags['page'] ) ) {
903
					$params['page'] = (int) $tags['page'];
904
					$params['page'] = max( $params['page'], 1 );
905
				}
906
907
				if ( isset( $tags['offset'] ) ) {
908
					$params['offset'] = (int) $tags['offset'];
909
					$params['offset'] = max( $params['offset'], 0 );
910
				}
911
			}
912
913
			if ( ! empty( $tags['cache_mode'] ) && 'none' !== $tags['cache_mode'] ) {
914
				$params['cache_mode'] = $tags['cache_mode'];
915
				$params['expires']    = (int) $tags['expires'];
916
			}
917
918
			$params = apply_filters( 'pods_shortcode_findrecords_params', $params, $pod, $tags );
919
920
			$pod->find( $params );
921
922
			$found = $pod->total();
923
		}//end if
924
	}//end if
925
926
	if ( ! empty( $tags['form'] ) ) {
927
		if ( 'user' === $pod->pod ) {
928
			if ( false !== strpos( $tags['fields'], '_capabilities' ) || false !== strpos( $tags['fields'], '_user_level' ) ) {
929
				// Further hardening of User-based forms
930
				return '';
931
			} elseif ( $is_singular && ( ! defined( 'PODS_SHORTCODE_ALLOW_USER_EDIT' ) || ! PODS_SHORTCODE_ALLOW_USER_EDIT ) ) {
932
				// Only explicitly allow user edit forms
933
				return '';
934
			}
935
		}
936
937
		return $pod->form( $tags['fields'], $tags['label'], $tags['thank_you'] );
938
	} elseif ( ! empty( $tags['field'] ) ) {
939
		if ( empty( $tags['helper'] ) ) {
940
			$return = $pod->display( $tags['field'] );
941
		} else {
942
			$return = $pod->helper( $tags['helper'], $pod->field( $tags['field'] ), $tags['field'] );
943
		}
944
945
		if ( $tags['shortcodes'] && defined( 'PODS_SHORTCODE_ALLOW_SUB_SHORTCODES' ) && PODS_SHORTCODE_ALLOW_SUB_SHORTCODES ) {
946
			$return = do_shortcode( $return );
947
		}
948
949
		return $return;
950
	} elseif ( ! empty( $tags['pods_page'] ) && class_exists( 'Pods_Pages' ) ) {
951
		$pods_page = Pods_Pages::exists( $tags['pods_page'] );
952
953
		if ( empty( $pods_page ) ) {
954
			return '<p>Pods Page not found</p>';
955
		}
956
957
		$return = Pods_Pages::content( true, $pods_page );
958
959
		if ( $tags['shortcodes'] && defined( 'PODS_SHORTCODE_ALLOW_SUB_SHORTCODES' ) && PODS_SHORTCODE_ALLOW_SUB_SHORTCODES ) {
960
			$return = do_shortcode( $return );
961
		}
962
963
		return $return;
964
	}//end if
965
966
	ob_start();
967
968
	if ( ! $is_singular && false !== $tags['filters'] && 'before' === $tags['filters_location'] ) {
969
		echo $pod->filters( $tags['filters'], $tags['filters_label'] );
0 ignored issues
show
Unused Code introduced by
The call to Pods::filters() has too many arguments starting with $tags['filters_label'].

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

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

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

Loading history...
970
	}
971
972
	if ( ! $is_singular && 0 < $found && true === $tags['pagination'] && in_array(
973
		$tags['pagination_location'], array(
974
			'before',
975
			'both',
976
		), true
977
	) ) {
978
		echo $pod->pagination( $tags['pagination_label'] );
979
	}
980
981
	echo $pod->template( $tags['template'], $content );
982
983
	if ( ! $is_singular && 0 < $found && true === $tags['pagination'] && in_array(
984
		$tags['pagination_location'], array(
985
			'after',
986
			'both',
987
		), true
988
	) ) {
989
		echo $pod->pagination( $tags['pagination_label'] );
990
	}
991
992
	if ( ! $is_singular && false !== $tags['filters'] && 'after' === $tags['filters_location'] ) {
993
		echo $pod->filters( $tags['filters'], $tags['filters_label'] );
0 ignored issues
show
Unused Code introduced by
The call to Pods::filters() has too many arguments starting with $tags['filters_label'].

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

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

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

Loading history...
994
	}
995
996
	$return = ob_get_clean();
997
998
	if ( $tags['shortcodes'] && defined( 'PODS_SHORTCODE_ALLOW_SUB_SHORTCODES' ) && PODS_SHORTCODE_ALLOW_SUB_SHORTCODES ) {
999
		$return = do_shortcode( $return );
1000
	}
1001
1002
	return $return;
1003
}
1004
1005
/**
1006
 * Form Shortcode support for use anywhere that support WP Shortcodes
1007
 *
1008
 * @param array  $tags    An associative array of shortcode properties
1009
 * @param string $content Not currently used
0 ignored issues
show
Documentation introduced by
Should the type for parameter $content not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1010
 *
1011
 * @return string
1012
 * @since 2.3
1013
 */
1014
function pods_shortcode_form( $tags, $content = null ) {
1015
1016
	$tags['form'] = 1;
1017
1018
	return pods_shortcode( $tags );
1019
}
1020
1021
/**
1022
 * Fork of WordPress do_shortcode that allows specifying which shortcodes are ran.
1023
 *
1024
 * Search content for shortcodes and filter shortcodes through their hooks.
1025
 *
1026
 * If there are no shortcode tags defined, then the content will be returned
1027
 * without any filtering. This might cause issues when plugins are disabled but
1028
 * the shortcode will still show up in the post or content.
1029
 *
1030
 * @since 2.4.3
1031
 *
1032
 * @uses  $shortcode_tags
1033
 * @uses  get_shortcode_regex() Gets the search pattern for searching shortcodes.
1034
 *
1035
 * @param string $content    Content to search for shortcodes
1036
 * @param array  $shortcodes Array of shortcodes to run
1037
 *
1038
 * @return string Content with shortcodes filtered out.
1039
 */
1040
function pods_do_shortcode( $content, $shortcodes ) {
1041
1042
	global $shortcode_tags;
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...
1043
1044
	// No shortcodes in content
1045
	if ( false === strpos( $content, '[' ) ) {
1046
		return $content;
1047
	}
1048
1049
	// No shortcodes registered
1050
	if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) {
1051
		return $content;
1052
	}
1053
1054
	if ( ! empty( $shortcodes ) ) {
1055
		$temp_shortcode_filter = function ( $return, $tag, $attr, $m ) use ( $shortcodes ) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $m. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility Naming introduced by
The variable name $temp_shortcode_filter exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
1056
1057
			if ( in_array( $m[2], $shortcodes, true ) ) {
1058
				// If shortcode being called is in list, return false to allow it to run
1059
				return false;
1060
			}
1061
1062
			// Return original shortcode string if we aren't going to handle at this time
1063
			return $m[0];
1064
		};
1065
		add_filter( 'pre_do_shortcode_tag', $temp_shortcode_filter, 10, 4 );
1066
	}
1067
1068
	// Build Shortcode regex pattern just for the shortcodes we want
1069
	$pattern = get_shortcode_regex();
1070
1071
	// Call shortcode callbacks just for the shortcodes we want
1072
	$content = preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
1073
1074
	if ( isset( $temp_shortcode_filter ) ) {
1075
		remove_filter( 'pre_do_shortcode_tag', $temp_shortcode_filter );
1076
	}
1077
1078
	return $content;
1079
1080
}
1081
1082
/**
1083
 * Check if Pods is compatible with WP / PHP / MySQL or not
1084
 *
1085
 * @return bool
1086
 *
1087
 * @since 1.10
1088
 */
1089
function pods_compatibility_check() {
1090
1091
	$compatible = true;
1092
1093
	if ( ! pods_version_check( 'wp', PODS_WP_VERSION_MINIMUM ) ) {
1094
		$compatible = false;
1095
1096
		add_action( 'admin_notices', 'pods_version_notice_wp' );
1097
	}
1098
1099
	if ( ! pods_version_check( 'php', PODS_PHP_VERSION_MINIMUM ) ) {
1100
		$compatible = false;
1101
1102
		add_action( 'admin_notices', 'pods_version_notice_php' );
1103
	}
1104
1105
	if ( ! pods_version_check( 'mysql', PODS_MYSQL_VERSION_MINIMUM ) ) {
1106
		$compatible = false;
1107
1108
		add_action( 'admin_notices', 'pods_version_notice_mysql' );
1109
	}
1110
1111
	return $compatible;
1112
}
1113
1114
/**
1115
 * Show WP notice if WP version is incompatible
1116
 *
1117
 * @return void
1118
 *
1119
 * @since 1.10
1120
 */
1121
function pods_version_notice_wp() {
1122
1123
	global $wp_version;
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...
1124
	?>
1125
	<div class="error fade">
1126
		<p>
1127
			<strong><?php _e( 'NOTICE', 'pods' ); ?>:</strong> Pods <?php echo esc_html( PODS_VERSION ); ?> <?php _e( 'requires a minimum of', 'pods' ); ?>
1128
			<strong>WordPress <?php echo esc_html( PODS_WP_VERSION_MINIMUM ); ?>+</strong> <?php _e( 'to function. You are currently running', 'pods' ); ?>
1129
			<strong>WordPress <?php echo esc_html( $wp_version ); ?></strong> - <?php _e( 'Please upgrade your WordPress to continue.', 'pods' ); ?>
1130
		</p>
1131
	</div>
1132
	<?php
1133
}
1134
1135
/**
1136
 * Show WP notice if PHP version is incompatible
1137
 *
1138
 * @return void
1139
 *
1140
 * @since 1.10
1141
 */
1142
function pods_version_notice_php() {
1143
1144
	?>
1145
	<div class="error fade">
1146
		<p>
1147
			<strong><?php _e( 'NOTICE', 'pods' ); ?>:</strong> Pods <?php echo esc_html( PODS_VERSION ); ?> <?php _e( 'requires a minimum of', 'pods' ); ?>
1148
			<strong>PHP <?php echo esc_html( PODS_PHP_VERSION_MINIMUM ); ?>+</strong> <?php _e( 'to function. You are currently running', 'pods' ); ?>
1149
			<strong>PHP <?php echo esc_html( phpversion() ); ?></strong> - <?php _e( 'Please upgrade (or have your Hosting Provider upgrade it for you) your PHP version to continue.', 'pods' ); ?>
1150
		</p>
1151
	</div>
1152
	<?php
1153
}
1154
1155
/**
1156
 * Show WP notice if MySQL version is incompatible
1157
 *
1158
 * @return void
1159
 *
1160
 * @since 1.10
1161
 */
1162
function pods_version_notice_mysql() {
1163
1164
	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...
1165
	$mysql = $wpdb->db_version();
1166
	?>
1167
	<div class="error fade">
1168
		<p>
1169
			<strong><?php _e( 'NOTICE', 'pods' ); ?>:</strong> Pods <?php echo esc_html( PODS_VERSION ); ?> <?php _e( 'requires a minimum of', 'pods' ); ?>
1170
			<strong>MySQL <?php echo esc_html( PODS_MYSQL_VERSION_MINIMUM ); ?>+</strong> <?php _e( 'to function. You are currently running', 'pods' ); ?>
1171
			<strong>MySQL <?php echo esc_html( $mysql ); ?></strong> - <?php _e( 'Please upgrade (or have your Hosting Provider upgrade it for you) your MySQL version to continue.', 'pods' ); ?>
1172
		</p>
1173
	</div>
1174
	<?php
1175
}
1176
1177
/**
1178
 * Check if a Function exists or File exists in Theme / Child Theme
1179
 *
1180
 * @param string $function_or_file Function or file name to look for.
1181
 * @param string $function_name    (optional) Function name to look for.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $function_name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1182
 * @param string $file_dir         (optional) Drectory to look into
0 ignored issues
show
Documentation introduced by
Should the type for parameter $file_dir not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1183
 * @param string $file_name        (optional) Filename to look for
0 ignored issues
show
Documentation introduced by
Should the type for parameter $file_name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1184
 *
1185
 * @return mixed
1186
 *
1187
 * @since 1.12
1188
 */
1189
function pods_function_or_file( $function_or_file, $function_name = null, $file_dir = null, $file_name = null ) {
1190
1191
	$found            = false;
1192
	$function_or_file = (string) $function_or_file;
1193
	if ( false !== $function_name ) {
1194
		if ( null === $function_name ) {
1195
			$function_name = $function_or_file;
1196
		}
1197
		$function_name = str_replace(
1198
			array(
1199
				'__',
1200
				'__',
1201
				'__',
1202
			), '_', preg_replace( '/[^a-z^A-Z^_][^a-z^A-Z^0-9^_]*/', '_', (string) $function_name )
1203
		);
1204
		if ( function_exists( 'pods_custom_' . $function_name ) ) {
1205
			$found = array( 'function' => 'pods_custom_' . $function_name );
1206
		} elseif ( function_exists( $function_name ) ) {
1207
			$found = array( 'function' => $function_name );
1208
		}
1209
	}
1210
	if ( false !== $file_name && false === $found ) {
1211
		if ( null === $file_name ) {
1212
			$file_name = $function_or_file;
1213
		}
1214
		$file_name       = str_replace(
1215
			array(
1216
				'__',
1217
				'__',
1218
				'__',
1219
			), '_', preg_replace( '/[^a-z^A-Z^0-9^_]*/', '_', (string) $file_name )
1220
		) . '.php';
1221
		$custom_location = apply_filters( 'pods_file_directory', null, $function_or_file, $function_name, $file_dir, $file_name );
1222
		if ( defined( 'PODS_FILE_DIRECTORY' ) && false !== PODS_FILE_DIRECTORY ) {
1223
			$custom_location = PODS_FILE_DIRECTORY;
1224
		}
1225
		if ( ! empty( $custom_location ) && locate_template( trim( $custom_location, '/' ) . '/' . ( ! empty( $file_dir ) ? $file_dir . '/' : '' ) . $file_name ) ) {
1226
			$found = array( 'file' => trim( $custom_location, '/' ) . '/' . ( ! empty( $file_dir ) ? $file_dir . '/' : '' ) . $file_name );
1227
		} elseif ( locate_template( 'pods/' . ( ! empty( $file_dir ) ? $file_dir . '/' : '' ) . $file_name ) ) {
1228
			$found = array( 'file' => 'pods/' . ( ! empty( $file_dir ) ? $file_dir . '/' : '' ) . $file_name );
1229
		} elseif ( locate_template( 'pods-' . ( ! empty( $file_dir ) ? $file_dir . '-' : '' ) . $file_name ) ) {
1230
			$found = array( 'file' => 'pods-' . ( ! empty( $file_dir ) ? $file_dir . '-' : '' ) . $file_name );
1231
		} elseif ( locate_template( 'pods/' . ( ! empty( $file_dir ) ? $file_dir . '-' : '' ) . $file_name ) ) {
1232
			$found = array( 'file' => 'pods/' . ( ! empty( $file_dir ) ? $file_dir . '-' : '' ) . $file_name );
1233
		}
1234
	}//end if
1235
1236
	return apply_filters( 'pods_function_or_file', $found, $function_or_file, $function_name, $file_name );
1237
}
1238
1239
/**
1240
 * Redirects to another page.
1241
 *
1242
 * @param string  $location The path to redirect to
1243
 * @param int     $status   Status code to use
1244
 * @param boolean $die      If true, PHP code exection will stop
1245
 *
1246
 * @return void
1247
 *
1248
 * @since 2.0
1249
 */
1250
function pods_redirect( $location, $status = 302, $die = true ) {
1251
1252
	if ( ! headers_sent() ) {
1253
		wp_redirect( $location, $status );
1254
		if ( $die ) {
1255
			die();
1256
		}
1257
	} else {
1258
		echo '<script type="text/javascript">' . 'document.location = "' . str_replace( '&amp;', '&', esc_js( $location ) ) . '";' . '</script>';
1259
		if ( $die ) {
1260
			die();
1261
		}
1262
	}
1263
}
1264
1265
/**
1266
 * Check if a user has permission to be doing something based on standard permission options
1267
 *
1268
 * @param array $options
1269
 *
1270
 * @return bool Whether the user has permissions
1271
 *
1272
 * @since 2.0.5
1273
 */
1274
function pods_permission( $options ) {
1275
1276
	global $current_user;
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...
1277
1278
	wp_get_current_user();
1279
1280
	$permission = false;
1281
1282
	if ( isset( $options['options'] ) ) {
1283
		$options = $options['options'];
1284
	}
1285
1286
	if ( pods_is_admin() ) {
1287
		$permission = true;
1288
	} elseif ( 0 === (int) pods_v( 'restrict_role', $options, 0 ) && 0 === (int) pods_v( 'restrict_capability', $options, 0 ) && 0 === (int) pods_v( 'admin_only', $options, 0 ) ) {
1289
		$permission = true;
1290
	}
1291
1292
	if ( ! $permission && 1 === (int) pods_v( 'restrict_role', $options, 0 ) ) {
1293
		$roles = pods_v( 'roles_allowed', $options );
1294
1295
		if ( ! is_array( $roles ) ) {
1296
			$roles = explode( ',', $roles );
1297
		}
1298
1299
		$roles = array_unique( array_filter( $roles ) );
1300
1301
		foreach ( $roles as $role ) {
1302
			if ( is_user_logged_in() && in_array( $role, $current_user->roles, true ) ) {
1303
				$permission = true;
1304
1305
				break;
1306
			}
1307
		}
1308
	}
1309
1310
	if ( ! $permission && 1 === (int) pods_v( 'restrict_capability', $options, 0 ) ) {
1311
		$capabilities = pods_v( 'capability_allowed', $options );
1312
1313
		if ( ! is_array( $capabilities ) ) {
1314
			$capabilities = explode( ',', $capabilities );
1315
		}
1316
1317
		$capabilities = array_unique( array_filter( $capabilities ) );
1318
1319
		foreach ( $capabilities as $capability ) {
1320
			$must_have_capabilities = explode( '&&', $capability );
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $must_have_capabilities exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
1321
			$must_have_capabilities = array_unique( array_filter( $must_have_capabilities ) );
1322
1323
			$must_have_permission = true;
1324
1325
			foreach ( $must_have_capabilities as $must_have_capability ) {
1326
				if ( ! current_user_can( $must_have_capability ) ) {
1327
					$must_have_permission = false;
1328
1329
					break;
1330
				}
1331
			}
1332
1333
			if ( $must_have_permission && is_user_logged_in() ) {
1334
				$permission = true;
1335
1336
				break;
1337
			}
1338
		}
1339
	}//end if
1340
1341
	return $permission;
1342
}
1343
1344
/**
1345
 * Check if permissions are restricted
1346
 *
1347
 * @param array $options
1348
 *
1349
 * @return bool Whether the permissions are restricted
1350
 *
1351
 * @since 2.3.4
1352
 */
1353
function pods_has_permissions( $options ) {
1354
1355
	$permission = false;
1356
1357
	if ( isset( $options['options'] ) ) {
1358
		$options = $options['options'];
1359
	}
1360
1361
	if ( 1 === (int) pods_v( 'restrict_role', $options, 0 ) || 1 === (int) pods_v( 'restrict_capability', $options, 0 ) || 1 === (int) pods_v( 'admin_only', $options, 0 ) ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return 1 === (int) pods_...in_only', $options, 0);.
Loading history...
1362
		return true;
1363
	}
1364
1365
	return false;
1366
}
1367
1368
/**
1369
 * A fork of get_page_by_title that excludes items unavailable via access rights (by status)
1370
 *
1371
 * @see   get_page_by_title
1372
 *
1373
 * @param string       $title  Title of item to get
1374
 * @param string       $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT.
1375
 * @param string       $type   Post Type
1376
 * @param string|array $status Post statuses to include (default is what user has access to)
0 ignored issues
show
Documentation introduced by
Should the type for parameter $status not be string|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1377
 *
1378
 * @return WP_Post|null WP_Post on success or null on failure
1379
 *
1380
 * @since 2.3.4
1381
 */
1382
function pods_by_title( $title, $output = OBJECT, $type = 'page', $status = null ) {
1383
1384
	// @todo support Pod item lookups, not just Post Types
1385
	/**
1386
	 * @var $wpdb WPDB
1387
	 */
1388
	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...
1389
1390
	if ( empty( $status ) ) {
1391
		$status = array(
1392
			'publish',
1393
		);
1394
1395
		if ( current_user_can( 'read_private_' . $type . 's' ) ) {
1396
			$status[] = 'private';
1397
		}
1398
1399
		if ( current_user_can( 'edit_' . $type . 's' ) ) {
1400
			$status[] = 'draft';
1401
		}
1402
	}
1403
1404
	$status = (array) $status;
1405
1406
	$status_sql = ' AND `post_status` IN ( %s' . str_repeat( ', %s', count( $status ) - 1 ) . ' )';
1407
1408
	$orderby_sql = ' ORDER BY ( `post_status` = %s ) DESC' . str_repeat( ', ( `post_status` = %s ) DESC', count( $status ) - 1 ) . ', `ID` DESC';
1409
1410
	// Once for WHERE, once for ORDER BY
1411
	$prepared = array_merge( array( $title, $type ), $status, $status );
1412
1413
	$page = $wpdb->get_var( $wpdb->prepare( "SELECT `ID` FROM `{$wpdb->posts}` WHERE `post_title` = %s AND `post_type` = %s" . $status_sql . $orderby_sql, $prepared ) );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1414
1415
	if ( $page ) {
1416
		return get_post( pods_v( $page, 'post_id' ), $output );
1417
	}
1418
1419
	return null;
1420
}
1421
1422
/**
1423
 * Get a field value from a Pod.
1424
 *
1425
 * @param string|null  $pod    The pod name.
1426
 * @param mixed|null   $id     The ID or slug of the item.
1427
 * @param string|array $name   The field name, or an associative array of parameters.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1428
 * @param boolean      $single For tableless fields, to return the whole array or the just the first item.
1429
 *
1430
 * @return mixed Field value.
1431
 *
1432
 * @since 2.1
1433
 */
1434
function pods_field( $pod, $id = null, $name = null, $single = false ) {
1435
1436
	// allow for pods_field( 'field_name' );
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1437
	if ( null === $name ) {
1438
		$name   = $pod;
1439
		$single = (boolean) $id;
1440
1441
		$pod = null;
1442
		$id  = null;
1443
	}
1444
1445
	if ( null === $pod && null === $id ) {
1446
		$pod = get_post_type();
1447
		$id  = get_the_ID();
1448
	}
1449
1450
	$pod_object = pods( $pod, $id );
1451
1452
	if ( is_object( $pod_object ) && $pod_object->exists() ) {
1453
		return $pod_object->field( $name, $single );
1454
	}
1455
1456
	return null;
1457
}
1458
1459
/**
1460
 * Get a field display value from a Pod.
1461
 *
1462
 * @param string|null  $pod    The pod name.
1463
 * @param mixed|null   $id     The ID or slug of the item.
1464
 * @param string|array $name   The field name, or an associative array of parameters.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1465
 * @param boolean      $single For tableless fields, to return the whole array or the just the first item.
1466
 *
1467
 * @return mixed Field value.
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use object|integer|double|string|null|boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1468
 *
1469
 * @since 2.1
1470
 */
1471
function pods_field_display( $pod, $id = null, $name = null, $single = false ) {
1472
1473
	// allow for pods_field_display( 'field_name' );
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1474
	if ( null === $name ) {
1475
		$name   = $pod;
1476
		$single = (boolean) $id;
1477
1478
		$pod = null;
1479
		$id  = null;
1480
	}
1481
1482
	if ( null === $pod && null === $id ) {
1483
		$pod = get_post_type();
1484
		$id  = get_the_ID();
1485
	}
1486
1487
	$pod_object = pods( $pod, $id );
1488
1489
	if ( is_object( $pod_object ) && $pod_object->exists() ) {
1490
		return $pod_object->display( $name, $single );
1491
	}
1492
1493
	return null;
1494
}
1495
1496
/**
1497
 * Get a field raw value from a Pod.
1498
 *
1499
 * @param string|null  $pod    The pod name.
1500
 * @param mixed|null   $id     The ID or slug of the item.
1501
 * @param string|array $name   The field name, or an associative array of parameters.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1502
 * @param boolean      $single For tableless fields, to return the whole array or the just the first item.
1503
 *
1504
 * @return mixed Field value.
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string|null|false.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1505
 *
1506
 * @since 2.1
1507
 */
1508
function pods_field_raw( $pod, $id = null, $name = null, $single = false ) {
1509
1510
	// allow for pods_field_raw( 'field_name' );
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1511
	if ( null === $name ) {
1512
		$name   = $pod;
1513
		$single = (boolean) $id;
1514
1515
		$pod = null;
1516
		$id  = null;
1517
	}
1518
1519
	if ( null === $pod && null === $id ) {
1520
		$pod = get_post_type();
1521
		$id  = get_the_ID();
1522
	}
1523
1524
	$pod_object = pods( $pod, $id );
1525
1526
	if ( is_object( $pod_object ) && $pod_object->exists() ) {
1527
		return $pod_object->raw( $name, $single );
1528
	}
1529
1530
	return null;
1531
1532
}
1533
1534
/**
1535
 * Update a field value for a Pod.
1536
 *
1537
 * @param string|null  $pod   The pod name.
1538
 * @param mixed|null   $id    The ID or slug of the item.
1539
 * @param string|array $name  The field name, or an associative array of parameters.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1540
 * @param boolean      $value Value to save.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $value not be boolean|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1541
 *
1542
 * @return int|false The item ID or false if not saved.
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|array|false? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
1543
 *
1544
 * @since 2.7.2
1545
 */
1546
function pods_field_update( $pod, $id = null, $name = null, $value = null ) {
1547
1548
	// allow for pods_field( 'field_name' );
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1549
	if ( null === $name ) {
1550
		$name  = $pod;
1551
		$value = $id;
1552
1553
		$pod = null;
1554
		$id  = null;
1555
	}
1556
1557
	if ( null === $pod && null === $id ) {
1558
		$pod = get_post_type();
1559
		$id  = get_the_ID();
1560
	}
1561
1562
	$pod_object = pods( $pod, $id );
1563
1564
	if ( is_object( $pod_object ) && $pod_object->exists() ) {
1565
		return $pod_object->save( $name, $value );
1566
	}
1567
1568
	return false;
1569
}
1570
1571
/**
1572
 * Set a cached value
1573
 *
1574
 * @see   PodsView::set
1575
 *
1576
 * @param string $key        Key for the cache
1577
 * @param mixed  $value      Value to add to the cache
1578
 * @param int    $expires    (optional) Time in seconds for the cache to expire, if 0 no expiration.
1579
 * @param string $cache_mode (optional) Decides the caching method to use for the view.
1580
 * @param string $group      (optional) Key for the group
1581
 *
1582
 * @return bool|mixed|null|string|void
1583
 *
1584
 * @since 2.0
1585
 */
1586
function pods_view_set( $key, $value, $expires = 0, $cache_mode = 'cache', $group = '' ) {
1587
1588
	require_once PODS_DIR . 'classes/PodsView.php';
1589
1590
	return PodsView::set( $key, $value, $expires, $cache_mode, $group );
1591
}
1592
1593
/**
1594
 * Get a cached value
1595
 *
1596
 * @see   PodsView::get
1597
 *
1598
 * @param string $key        Key for the cache
1599
 * @param string $cache_mode (optional) Decides the caching method to use for the view.
1600
 * @param string $group      (optional) Key for the group
1601
 * @param string $callback   (optional) Callback function to run to set the value if not cached
0 ignored issues
show
Documentation introduced by
Should the type for parameter $callback not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1602
 *
1603
 * @return bool|mixed|null|void
1604
 *
1605
 * @since 2.0
1606
 */
1607
function pods_view_get( $key, $cache_mode = 'cache', $group = '', $callback = null ) {
1608
1609
	require_once PODS_DIR . 'classes/PodsView.php';
1610
1611
	return PodsView::get( $key, $cache_mode, $group, $callback );
1612
}
1613
1614
/**
1615
 * Clear a cached value
1616
 *
1617
 * @see   PodsView::clear
1618
 *
1619
 * @param string|bool $key        Key for the cache
1620
 * @param string      $cache_mode (optional) Decides the caching method to use for the view.
1621
 * @param string      $group      (optional) Key for the group
1622
 *
1623
 * @return bool
1624
 *
1625
 * @since 2.0
1626
 */
1627
function pods_view_clear( $key = true, $cache_mode = 'cache', $group = '' ) {
1628
1629
	require_once PODS_DIR . 'classes/PodsView.php';
1630
1631
	return PodsView::clear( $key, $cache_mode, $group );
1632
}
1633
1634
/**
1635
 * Set a cached value
1636
 *
1637
 * @see   PodsView::set
1638
 *
1639
 * @param string $key     Key for the cache
1640
 * @param mixed  $value   Value to add to the cache
1641
 * @param string $group   (optional) Key for the group
1642
 * @param int    $expires (optional) Time in seconds for the cache to expire, if 0 no expiration.
1643
 *
1644
 * @return bool|mixed|null|string|void
1645
 *
1646
 * @since 2.0
1647
 */
1648
function pods_cache_set( $key, $value, $group = '', $expires = 0 ) {
1649
1650
	return pods_view_set( $key, $value, $expires, 'cache', $group );
1651
}
1652
1653
/**
1654
 * Get a cached value
1655
 *
1656
 * @see   PodsView::get
1657
 *
1658
 * @param string $key      Key for the cache
1659
 * @param string $group    (optional) Key for the group
1660
 * @param string $callback (optional) Callback function to run to set the value if not cached
0 ignored issues
show
Documentation introduced by
Should the type for parameter $callback not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1661
 *
1662
 * @return bool
1663
 *
1664
 * @since 2.0
1665
 */
1666
function pods_cache_get( $key, $group = '', $callback = null ) {
1667
1668
	return pods_view_get( $key, 'cache', $group, $callback );
1669
}
1670
1671
/**
1672
 * Clear a cached value
1673
 *
1674
 * @see   PodsView::clear
1675
 *
1676
 * @param string|bool $key   Key for the cache
1677
 * @param string      $group (optional) Key for the group
1678
 *
1679
 * @return bool|mixed|null|void
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1680
 *
1681
 * @since 2.0
1682
 */
1683
function pods_cache_clear( $key = true, $group = '' ) {
1684
1685
	return pods_view_clear( $key, 'cache', $group );
1686
}
1687
1688
/**
1689
 * Set a cached value
1690
 *
1691
 * @see   PodsView::set
1692
 *
1693
 * @param string $key     Key for the cache
1694
 * @param mixed  $value   Value to add to the cache
1695
 * @param int    $expires (optional) Time in seconds for the cache to expire, if 0 no expiration.
1696
 *
1697
 * @return bool|mixed|null|string|void
1698
 *
1699
 * @since 2.0
1700
 */
1701
function pods_transient_set( $key, $value, $expires = 0 ) {
1702
1703
	return pods_view_set( $key, $value, $expires, 'transient' );
1704
}
1705
1706
/**
1707
 * Get a cached value
1708
 *
1709
 * @see   PodsView::get
1710
 *
1711
 * @param string $key      Key for the cache
1712
 * @param string $callback (optional) Callback function to run to set the value if not cached
0 ignored issues
show
Documentation introduced by
Should the type for parameter $callback not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1713
 *
1714
 * @return bool|mixed|null|void
1715
 *
1716
 * @since 2.0
1717
 */
1718
function pods_transient_get( $key, $callback = null ) {
1719
1720
	return pods_view_get( $key, 'transient', '', $callback );
1721
}
1722
1723
/**
1724
 * Clear a cached value
1725
 *
1726
 * @see   PodsView::clear
1727
 *
1728
 * @param string|bool $key Key for the cache
1729
 *
1730
 * @return bool
1731
 *
1732
 * @since 2.0
1733
 */
1734
function pods_transient_clear( $key = true ) {
1735
1736
	return pods_view_clear( $key, 'transient' );
1737
}
1738
1739
/**
1740
 * Set a cached value
1741
 *
1742
 * @see   PodsView::set
1743
 *
1744
 * @param string $key     Key for the cache
1745
 * @param mixed  $value   Value to add to the cache
1746
 * @param int    $expires (optional) Time in seconds for the cache to expire, if 0 no expiration.
1747
 *
1748
 * @return bool|mixed|null|string|void
1749
 *
1750
 * @since 2.3.10
1751
 */
1752
function pods_site_transient_set( $key, $value, $expires = 0 ) {
1753
1754
	return pods_view_set( $key, $value, $expires, 'site-transient' );
1755
}
1756
1757
/**
1758
 * Get a cached value
1759
 *
1760
 * @see   PodsView::get
1761
 *
1762
 * @param string $key      Key for the cache
1763
 * @param string $callback (optional) Callback function to run to set the value if not cached
0 ignored issues
show
Documentation introduced by
Should the type for parameter $callback not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1764
 *
1765
 * @return bool|mixed|null|void
1766
 *
1767
 * @since 2.3.10
1768
 */
1769
function pods_site_transient_get( $key, $callback = null ) {
1770
1771
	return pods_view_get( $key, 'site-transient', '', $callback );
1772
}
1773
1774
/**
1775
 * Clear a cached value
1776
 *
1777
 * @see   PodsView::clear
1778
 *
1779
 * @param string|bool $key Key for the cache
1780
 *
1781
 * @return bool
1782
 *
1783
 * @since 2.3.10
1784
 */
1785
function pods_site_transient_clear( $key = true ) {
1786
1787
	return pods_view_clear( $key, 'site-transient' );
1788
}
1789
1790
/**
1791
 * Set a cached value
1792
 *
1793
 * @see   PodsView::set
1794
 *
1795
 * @param string $key     Key for the cache
1796
 * @param mixed  $value   Value to add to the cache
1797
 * @param int    $expires (optional) Time in seconds for the cache to expire, if 0 no expiration.
1798
 * @param string $group   (optional) Key for the group
1799
 *
1800
 * @return bool|mixed|null|string|void
1801
 *
1802
 * @since 2.3.10
1803
 */
1804
function pods_option_cache_set( $key, $value, $expires = 0, $group = '' ) {
1805
1806
	return pods_view_set( $key, $value, $expires, 'option-cache', $group );
1807
}
1808
1809
/**
1810
 * Get a cached value
1811
 *
1812
 * @see   PodsView::get
1813
 *
1814
 * @param string $key      Key for the cache
1815
 * @param string $group    (optional) Key for the group
1816
 * @param string $callback (optional) Callback function to run to set the value if not cached
0 ignored issues
show
Documentation introduced by
Should the type for parameter $callback not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1817
 *
1818
 * @return bool|mixed|null|void
1819
 *
1820
 * @since 2.3.10
1821
 */
1822
function pods_option_cache_get( $key, $group = '', $callback = null ) {
1823
1824
	return pods_view_get( $key, 'option-cache', $group, $callback );
1825
}
1826
1827
/**
1828
 * Clear a cached value
1829
 *
1830
 * @see   PodsView::clear
1831
 *
1832
 * @param string|bool $key   Key for the cache
1833
 * @param string      $group (optional) Key for the group
1834
 *
1835
 * @return bool
1836
 *
1837
 * @since 2.3.10
1838
 */
1839
function pods_option_cache_clear( $key = true, $group = '' ) {
1840
1841
	return pods_view_clear( $key, 'option-cache', $group );
1842
}
1843
1844
/**
1845
 * Scope variables and include a template like get_template_part that's child-theme aware
1846
 *
1847
 * @see   get_template_part
1848
 *
1849
 * @param string|array $template Template names (see get_template_part)
1850
 * @param array        $data     Data to scope to the include
0 ignored issues
show
Documentation introduced by
Should the type for parameter $data not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1851
 * @param bool         $return   Whether to return the output (echo by default)
1852
 *
1853
 * @return string|null Template output
1854
 *
1855
 * @since 2.3.9
1856
 */
1857
function pods_template_part( $template, $data = null, $return = false ) {
1858
1859
	$part = PodsView::get_template_part( $template, $data );
1860
1861
	if ( ! $return ) {
1862
		echo $part;
1863
1864
		return null;
1865
	}
1866
1867
	return $part;
1868
}
1869
1870
/**
1871
 * Add a new Pod outside of the DB
1872
 *
1873
 * @see   PodsMeta::register
1874
 *
1875
 * @param string $type   The pod type ('post_type', 'taxonomy', 'media', 'user', 'comment')
1876
 * @param string $name   The pod name
1877
 * @param array  $object (optional) Pod array, including any 'fields' arrays
0 ignored issues
show
Documentation introduced by
Should the type for parameter $object not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1878
 *
1879
 * @return array|boolean Pod data or false if unsuccessful
0 ignored issues
show
Documentation introduced by
Should the return type not be array|integer|false? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
1880
 * @since 2.1
1881
 */
1882
function pods_register_type( $type, $name, $object = null ) {
1883
1884
	if ( empty( $object ) ) {
1885
		$object = array();
1886
	}
1887
1888
	if ( ! empty( $name ) ) {
1889
		$object['name'] = $name;
1890
	}
1891
1892
	return pods_meta()->register( $type, $object );
1893
}
1894
1895
/**
1896
 * Add a new Pod field outside of the DB
1897
 *
1898
 * @see   PodsMeta::register_field
1899
 *
1900
 * @param string|array $pod    The pod name or array of pod names
1901
 * @param string       $name   The name of the Pod
1902
 * @param array        $object (optional) Pod array, including any 'fields' arrays
0 ignored issues
show
Bug introduced by
There is no parameter named $object. 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...
1903
 *
1904
 * @return array|boolean Field data or false if unsuccessful
0 ignored issues
show
Documentation introduced by
Should the return type not be array|integer|false? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
1905
 * @since 2.1
1906
 */
1907
function pods_register_field( $pod, $name, $field = null ) {
1908
1909
	if ( empty( $field ) ) {
1910
		$field = array();
1911
	}
1912
1913
	if ( ! empty( $name ) ) {
1914
		$field['name'] = $name;
1915
	}
1916
1917
	return pods_meta()->register_field( $pod, $field );
1918
}
1919
1920
/**
1921
 * Add a new Pod field type
1922
 *
1923
 * @see   PodsForm::register_field_type
1924
 *
1925
 * @param string $type The new field type identifier
1926
 * @param string $file The new field type class file location
0 ignored issues
show
Documentation introduced by
Should the type for parameter $file not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1927
 *
1928
 * @return array Field type array
1929
 * @since 2.3
1930
 */
1931
function pods_register_field_type( $type, $file = null ) {
1932
1933
	return PodsForm::register_field_type( $type, $file );
1934
}
1935
1936
/**
1937
 * Register a related object
1938
 *
1939
 * @param string $name    Object name
1940
 * @param string $label   Object label
1941
 * @param array  $options Object options
0 ignored issues
show
Documentation introduced by
Should the type for parameter $options not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1942
 *
1943
 * @return array|boolean Object array or false if unsuccessful
1944
 * @since 2.3
1945
 */
1946
function pods_register_related_object( $name, $label, $options = null ) {
1947
1948
	return PodsForm::field_method( 'pick', 'register_related_object', $name, $label, $options );
1949
}
1950
1951
/**
1952
 * Require a component (always-on)
1953
 *
1954
 * @param string $component Component ID
1955
 *
1956
 * @return void
1957
 *
1958
 * @since 2.3
1959
 */
1960
function pods_require_component( $component ) {
1961
1962
	add_filter( 'pods_component_require_' . $component, '__return_true' );
1963
}
1964
1965
/**
1966
 * Add a meta group of fields to add/edit forms
1967
 *
1968
 * @see   PodsMeta::group_add
1969
 *
1970
 * @param string|array $pod      The pod or type of element to attach the group to.
1971
 * @param string       $label    Title of the edit screen section, visible to user.
1972
 * @param string|array $fields   Either a comma separated list of text fields or an associative array containing field
1973
 *                               information.
1974
 * @param string       $context  (optional) The part of the page where the edit screen section should be shown
1975
 *                               ('normal', 'advanced', or 'side').
1976
 * @param string       $priority (optional) The priority within the context where the boxes should show ('high',
1977
 *                               'core', 'default' or 'low').
1978
 * @param string       $type     (optional) Type of the post to attach to.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $type not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1979
 *
1980
 * @return void
1981
 *
1982
 * @since 2.0
1983
 * @link  https://pods.io/docs/pods-group-add/
1984
 */
1985
function pods_group_add( $pod, $label, $fields, $context = 'normal', $priority = 'default', $type = null ) {
1986
1987
	if ( ! is_array( $pod ) && null !== $type ) {
1988
		$pod = array(
1989
			'name' => $pod,
1990
			'type' => $type,
1991
		);
1992
	}
1993
1994
	pods_meta()->group_add( $pod, $label, $fields, $context, $priority );
1995
}
1996
1997
/**
1998
 * Check if a plugin is active on non-admin pages (is_plugin_active() only available in admin)
1999
 *
2000
 * @param string $plugin Plugin name.
2001
 *
2002
 * @return bool
2003
 *
2004
 * @since 2.0
2005
 */
2006
function pods_is_plugin_active( $plugin ) {
2007
2008
	$active = false;
2009
2010
	if ( function_exists( 'is_plugin_active' ) ) {
2011
		$active = is_plugin_active( $plugin );
2012
	}
2013
2014
	if ( ! $active ) {
2015
		$active_plugins = (array) get_option( 'active_plugins', array() );
2016
2017
		if ( in_array( $plugin, $active_plugins, true ) ) {
2018
			$active = true;
2019
		}
2020
2021
		if ( ! $active && is_multisite() ) {
2022
			$plugins = get_site_option( 'active_sitewide_plugins' );
2023
2024
			if ( isset( $plugins[ $plugin ] ) ) {
2025
				$active = true;
2026
			}
2027
		}
2028
	}
2029
2030
	return $active;
2031
}
2032
2033
/**
2034
 * Check if Pods no conflict is on or not
2035
 *
2036
 * @param string $object_type
2037
 *
2038
 * @return bool
2039
 *
2040
 * @since 2.3
2041
 */
2042
function pods_no_conflict_check( $object_type = 'post' ) {
2043
2044
	if ( 'post_type' === $object_type ) {
2045
		$object_type = 'post';
2046
	} elseif ( 'term' === $object_type ) {
2047
		$object_type = 'taxonomy';
2048
	}
2049
2050
	if ( ! class_exists( 'PodsInit' ) ) {
2051
		pods_init();
2052
	}
2053
2054
	if ( ! empty( PodsInit::$no_conflict ) && isset( PodsInit::$no_conflict[ $object_type ] ) && ! empty( PodsInit::$no_conflict[ $object_type ] ) ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !empty(\PodsInit:...onflict[$object_type]);.
Loading history...
2055
		return true;
2056
	}
2057
2058
	return false;
2059
}
2060
2061
/**
2062
 * Turn off conflicting / recursive actions for an object type that Pods hooks into
2063
 *
2064
 * @param string $object_type
0 ignored issues
show
Documentation introduced by
Should the type for parameter $object not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
2065
 * @param string $object
2066
 *
2067
 * @return bool
2068
 *
2069
 * @since 2.0
2070
 */
2071
function pods_no_conflict_on( $object_type = 'post', $object = null ) {
2072
2073
	if ( 'post_type' === $object_type ) {
2074
		$object_type = 'post';
2075
	} elseif ( 'term' === $object_type ) {
2076
		$object_type = 'taxonomy';
2077
	}
2078
2079
	if ( ! class_exists( 'PodsInit' ) ) {
2080
		pods_init();
2081
	}
2082
2083
	if ( ! empty( PodsInit::$no_conflict ) && isset( PodsInit::$no_conflict[ $object_type ] ) && ! empty( PodsInit::$no_conflict[ $object_type ] ) ) {
2084
		return true;
2085
	}
2086
2087
	if ( ! is_object( PodsInit::$meta ) ) {
2088
		return false;
2089
	}
2090
2091
	$no_conflict = array(
2092
		'filter' => array(),
2093
	);
2094
2095
	// Filters = Usually get/update/delete meta functions
2096
	// Actions = Usually insert/update/save/delete object functions
2097
	if ( 'post' === $object_type ) {
2098
		if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) {
2099
			// Handle *_post_meta
2100
			if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) {
2101
				$no_conflict['filter'] = array(
2102
					array( 'get_post_metadata', array( PodsInit::$meta, 'get_post_meta' ), 10, 4 ),
2103
				);
2104
			}
2105
2106
			if ( ! pods_tableless() ) {
2107
				$no_conflict['filter'] = array_merge(
2108
					$no_conflict['filter'], array(
2109
						array( 'add_post_metadata', array( PodsInit::$meta, 'add_post_meta' ), 10, 5 ),
2110
						array( 'update_post_metadata', array( PodsInit::$meta, 'update_post_meta' ), 10, 5 ),
2111
						array( 'delete_post_metadata', array( PodsInit::$meta, 'delete_post_meta' ), 10, 5 ),
2112
					)
2113
				);
2114
			}
2115
		}
2116
2117
		$no_conflict['action'] = array(
2118
			array( 'transition_post_status', array( PodsInit::$meta, 'save_post_detect_new' ), 10, 3 ),
2119
			array( 'save_post', array( PodsInit::$meta, 'save_post' ), 10, 2 ),
2120
			array( 'wp_insert_post_data', array( PodsInit::$meta, 'save_post_track_changed_fields' ), 10, 2 ),
2121
		);
2122
	} elseif ( 'taxonomy' === $object_type ) {
2123
		if ( apply_filters( 'pods_meta_handler', true, 'term' ) ) {
2124
			// Handle *_term_meta
2125
			if ( apply_filters( 'pods_meta_handler_get', true, 'term' ) ) {
2126
				$no_conflict['filter'] = array_merge(
2127
					$no_conflict['filter'], array(
2128
						array( 'get_term_metadata', array( PodsInit::$meta, 'get_term_meta' ), 10, 4 ),
2129
					)
2130
				);
2131
			}
2132
2133
			if ( ! pods_tableless() ) {
2134
				$no_conflict['filter'] = array_merge(
2135
					$no_conflict['filter'], array(
2136
						array( 'add_term_metadata', array( PodsInit::$meta, 'add_term_meta' ), 10, 5 ),
2137
						array( 'update_term_metadata', array( PodsInit::$meta, 'update_term_meta' ), 10, 5 ),
2138
						array( 'delete_term_metadata', array( PodsInit::$meta, 'delete_term_meta' ), 10, 5 ),
2139
					)
2140
				);
2141
			}
2142
2143
			$no_conflict['action'] = array(
2144
				array( 'edited_term', array( PodsInit::$meta, 'save_taxonomy' ), 10, 3 ),
2145
				array( 'create_term', array( PodsInit::$meta, 'save_taxonomy' ), 10, 3 ),
2146
				array( 'edit_terms', array( PodsInit::$meta, 'save_taxonomy_track_changed_fields' ), 10, 2 ),
2147
			);
2148
		}//end if
2149
	} elseif ( 'media' === $object_type ) {
2150
		$no_conflict['filter'] = array(
2151
			array( 'attachment_fields_to_save', array( PodsInit::$meta, 'save_media' ), 10, 2 ),
2152
			array( 'wp_update_attachment_metadata', array( PodsInit::$meta, 'save_media' ), 10, 2 ),
2153
			array( 'wp_insert_attachment_data', array( PodsInit::$meta, 'save_post_track_changed_fields' ), 10, 2 ),
2154
		);
2155
2156
		if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) {
2157
			// Handle *_post_meta
2158
			if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) {
2159
				$no_conflict['filter'] = array_merge(
2160
					$no_conflict['filter'], array(
2161
						array( 'get_post_metadata', array( PodsInit::$meta, 'get_post_meta' ), 10, 4 ),
2162
					)
2163
				);
2164
			}
2165
2166
			if ( ! pods_tableless() ) {
2167
				$no_conflict['filter'] = array_merge(
2168
					$no_conflict['filter'], array(
2169
						array( 'add_post_metadata', array( PodsInit::$meta, 'add_post_meta' ), 10, 5 ),
2170
						array( 'update_post_metadata', array( PodsInit::$meta, 'update_post_meta' ), 10, 5 ),
2171
						array( 'delete_post_metadata', array( PodsInit::$meta, 'delete_post_meta' ), 10, 5 ),
2172
					)
2173
				);
2174
			}
2175
2176
			$no_conflict['action'] = array();
2177
		}//end if
2178
	} elseif ( 'user' === $object_type ) {
2179
		if ( apply_filters( 'pods_meta_handler', true, 'user' ) ) {
2180
			// Handle *_term_meta
2181
			if ( apply_filters( 'pods_meta_handler_get', true, 'user' ) ) {
2182
				$no_conflict['filter'] = array(
2183
					array( 'get_user_metadata', array( PodsInit::$meta, 'get_user_meta' ), 10, 4 ),
2184
				);
2185
			}
2186
2187
			if ( ! pods_tableless() ) {
2188
				$no_conflict['filter'] = array_merge(
2189
					$no_conflict['filter'], array(
2190
						array( 'add_user_metadata', array( PodsInit::$meta, 'add_user_meta' ), 10, 5 ),
2191
						array( 'update_user_metadata', array( PodsInit::$meta, 'update_user_meta' ), 10, 5 ),
2192
						array( 'delete_user_metadata', array( PodsInit::$meta, 'delete_user_meta' ), 10, 5 ),
2193
					)
2194
				);
2195
			}
2196
		}
2197
2198
		$no_conflict['action'] = array(
2199
			array( 'user_register', array( PodsInit::$meta, 'save_user' ) ),
2200
			array( 'profile_update', array( PodsInit::$meta, 'save_user' ), 10, 2 ),
2201
			array( 'pre_user_login', array( PodsInit::$meta, 'save_user_track_changed_fields' ) ),
2202
		);
2203
	} elseif ( 'comment' === $object_type ) {
2204
		if ( apply_filters( 'pods_meta_handler', true, 'comment' ) ) {
2205
			// Handle *_term_meta
2206
			if ( apply_filters( 'pods_meta_handler_get', true, 'comment' ) ) {
2207
				$no_conflict['filter'] = array(
2208
					array( 'get_comment_metadata', array( PodsInit::$meta, 'get_comment_meta' ), 10, 4 ),
2209
				);
2210
			}
2211
2212
			if ( ! pods_tableless() ) {
2213
				$no_conflict['filter'] = array_merge(
2214
					$no_conflict['filter'], array(
2215
						array( 'add_comment_metadata', array( PodsInit::$meta, 'add_comment_meta' ), 10, 5 ),
2216
						array( 'update_comment_metadata', array( PodsInit::$meta, 'update_comment_meta' ), 10, 5 ),
2217
						array( 'delete_comment_metadata', array( PodsInit::$meta, 'delete_comment_meta' ), 10, 5 ),
2218
					)
2219
				);
2220
			}
2221
		}
2222
2223
		$no_conflict['action'] = array(
2224
			array( 'pre_comment_approved', array( PodsInit::$meta, 'validate_comment' ), 10, 2 ),
2225
			array( 'comment_post', array( PodsInit::$meta, 'save_comment' ) ),
2226
			array( 'edit_comment', array( PodsInit::$meta, 'save_comment' ) ),
2227
			array( 'wp_update_comment_data', array( PodsInit::$meta, 'save_comment_track_changed_fields' ), 10, 3 ),
2228
		);
2229
	} elseif ( 'settings' === $object_type ) {
2230
		$no_conflict['filter'] = array();
2231
2232
		// @todo Better handle settings conflicts apart from each other
2233
	}//end if
2234
2235
	$conflicted = false;
2236
2237
	foreach ( $no_conflict as $action_filter => $conflicts ) {
2238
		foreach ( $conflicts as $k => $args ) {
2239
			if ( call_user_func_array( 'has_' . $action_filter, array_slice( $args, 0, 2 ) ) ) {
2240
				call_user_func_array( 'remove_' . $action_filter, array_slice( $args, 0, 3 ) );
2241
2242
				$conflicted = true;
2243
			} else {
2244
				unset( $no_conflict[ $action_filter ][ $k ] );
2245
			}
2246
		}
2247
	}
2248
2249
	if ( $conflicted ) {
2250
		PodsInit::$no_conflict[ $object_type ] = $no_conflict;
2251
2252
		return true;
2253
	}
2254
2255
	return false;
2256
2257
}
2258
2259
/**
2260
 * Turn on actions after running code during pods_conflict
2261
 *
2262
 * @param string $object_type
2263
 *
2264
 * @return bool
2265
 *
2266
 * @since 2.0
2267
 */
2268
function pods_no_conflict_off( $object_type = 'post' ) {
2269
2270
	if ( 'post_type' === $object_type ) {
2271
		$object_type = 'post';
2272
	} elseif ( 'term' === $object_type ) {
2273
		$object_type = 'taxonomy';
2274
	}
2275
2276
	if ( ! class_exists( 'PodsInit' ) ) {
2277
		pods_init();
2278
	}
2279
2280
	if ( empty( PodsInit::$no_conflict ) || ! isset( PodsInit::$no_conflict[ $object_type ] ) || empty( PodsInit::$no_conflict[ $object_type ] ) ) {
2281
		return false;
2282
	}
2283
2284
	if ( ! is_object( PodsInit::$meta ) ) {
2285
		return false;
2286
	}
2287
2288
	$no_conflict = PodsInit::$no_conflict[ $object_type ];
2289
2290
	$conflicted = false;
2291
2292
	foreach ( $no_conflict as $action_filter => $conflicts ) {
2293
		foreach ( $conflicts as $args ) {
2294
			if ( ! call_user_func_array( 'has_' . $action_filter, array_slice( $args, 0, 2 ) ) ) {
2295
				call_user_func_array( 'add_' . $action_filter, $args );
2296
2297
				$conflicted = true;
2298
			}
2299
		}
2300
	}
2301
2302
	if ( $conflicted ) {
2303
		unset( PodsInit::$no_conflict[ $object_type ] );
2304
2305
		return true;
2306
	}
2307
2308
	return false;
2309
}
2310
2311
/**
2312
 * Safely start a new session (without whitescreening on certain hosts,
2313
 * which have no session path or isn't writable)
2314
 *
2315
 * @since 2.3.10
2316
 */
2317
function pods_session_start() {
2318
2319
	$save_path = session_save_path();
0 ignored issues
show
introduced by
The use of PHP session function session_save_path() is prohibited.
Loading history...
2320
2321
	if ( false !== headers_sent() ) {
2322
		// Check if headers were sent.
2323
		return false;
2324
	} elseif ( defined( 'PODS_SESSION_AUTO_START' ) && ! PODS_SESSION_AUTO_START ) {
2325
		// Allow for bypassing Pods session autostarting.
2326
		return false;
2327
	} elseif ( 0 === strpos( $save_path, 'tcp://' ) ) {
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...
2328
		// Allow for non-file based sessions, like Memcache.
2329
		// This is OK, but we don't want to check if file_exists on next statement.
2330
	} elseif ( empty( $save_path ) || ! @file_exists( $save_path ) || ! is_writable( $save_path ) ) {
0 ignored issues
show
Coding Style introduced by
Silencing errors is discouraged
Loading history...
introduced by
Filesystem writes are forbidden, you should not be using is_writable()
Loading history...
2331
		// Check if session path exists and can be written to, avoiding PHP fatal errors.
2332
		return false;
2333
	} elseif ( '' !== session_id() ) {
0 ignored issues
show
introduced by
The use of PHP session function session_id() is prohibited.
Loading history...
2334
		// Check if session ID is already set.
2335
		return false;
2336
	}
2337
2338
	// Start session
2339
	@session_start();
0 ignored issues
show
Coding Style introduced by
Silencing errors is discouraged
Loading history...
introduced by
The use of PHP session function session_start() is prohibited.
Loading history...
2340
2341
	return true;
2342
2343
}
2344
2345
/**
2346
 * @todo  : replace string literal with a defined constant
2347
 *
2348
 * @return bool
2349
 *
2350
 * @since 2.7
2351
 */
2352
function pods_is_modal_window() {
2353
2354
	$is_modal_window = false;
2355
2356
	if ( ! empty( $_GET['pods_modal'] ) || ! empty( $_POST['pods_modal'] ) ) {
2357
		$is_modal_window = true;
2358
	}
2359
2360
	return $is_modal_window;
2361
}
2362
2363
/**
2364
 * Check if the pod object is valid and the pod exists.
2365
 *
2366
 * @param Pods|mixed $pod The pod object or something that isn't a pod object
2367
 *
2368
 * @return bool Whether the pod object is valid and exists
2369
 *
2370
 * @since 2.7
2371
 */
2372
function pod_is_valid( $pod ) {
2373
2374
	$is_valid = false;
2375
2376
	if ( $pod && is_a( $pod, 'Pods' ) && $pod->valid() ) {
2377
		$is_valid = true;
2378
	}
2379
2380
	return $is_valid;
2381
}
2382
2383
/**
2384
 * Check if the pod object has item(s).
2385
 *
2386
 * @param Pods|mixed $pod The pod object or something that isn't a pod object
2387
 *
2388
 * @return bool Whether the pod object has items
2389
 *
2390
 * @since 2.7
2391
 */
2392
function pod_has_items( $pod ) {
2393
2394
	$has_items = false;
2395
2396
	if ( pod_is_valid( $pod ) && ( $pod->id && $pod->exists() ) || ( ! empty( $pod->params ) && 0 < $pod->total() ) ) {
2397
		$has_items = true;
2398
	}
2399
2400
	return $has_items;
2401
}
2402