Issues (2873)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

classes/PodsMeta.php (38 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * @package Pods
5
 */
6
class PodsMeta {
7
8
	/**
9
	 * @var PodsMeta
10
	 */
11
	static $instance = null;
0 ignored issues
show
The visibility should be declared for property $instance.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
12
13
	/**
14
	 * @var PodsAPI
15
	 */
16
	private $api;
0 ignored issues
show
The property $api is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
17
18
	/**
19
	 * @var Pods
20
	 */
21
	private static $current_pod;
22
23
	/**
24
	 * @var array
25
	 */
26
	private static $current_pod_data;
27
28
	/**
29
	 * @var Pods
30
	 */
31
	private static $current_field_pod;
32
33
	/**
34
	 * @var int
35
	 */
36
	public static $object_identifier = - 1;
37
38
	/**
39
	 * @var array
40
	 */
41
	public static $advanced_content_types = array();
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $advanced_content_types exceeds the maximum configured length of 20.

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

Loading history...
42
43
	/**
44
	 * @var array
45
	 */
46
	public static $post_types = array();
47
48
	/**
49
	 * @var array
50
	 */
51
	public static $taxonomies = array();
52
53
	/**
54
	 * @var array
55
	 */
56
	public static $media = array();
57
58
	/**
59
	 * @var array
60
	 */
61
	public static $user = array();
62
63
	/**
64
	 * @var array
65
	 */
66
	public static $comment = array();
67
68
	/**
69
	 * @var array
70
	 */
71
	public static $settings = array();
72
73
	/**
74
	 * @var array
75
	 */
76
	public static $queue = array();
77
78
	/**
79
	 * @var array
80
	 */
81
	public static $groups = array();
82
83
	/**
84
	 * @var array
85
	 */
86
	public static $old_post_status = array();
87
88
	/**
89
	 * Singleton handling for a basic pods_meta() request
90
	 *
91
	 * @return \PodsMeta
92
	 *
93
	 * @since 2.3.5
94
	 */
95
	public static function init() {
96
97
		if ( ! is_object( self::$instance ) ) {
98
			self::$instance = new PodsMeta();
99
		}
100
101
		return self::$instance;
102
	}
103
104
	/**
105
	 * @return \PodsMeta
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
106
	 *
107
	 * @since 2.0
108
	 */
109
	public function __construct() {
110
111
	}
112
113
	/**
114
	 * @return \PodsMeta
115
	 */
116
	public function core() {
117
118
		self::$advanced_content_types = pods_api()->load_pods( array( 'type' => 'pod' ) );
119
		self::$post_types             = pods_api()->load_pods( array( 'type' => 'post_type' ) );
120
		self::$taxonomies             = pods_api()->load_pods( array( 'type' => 'taxonomy' ) );
121
		self::$media                  = pods_api()->load_pods( array( 'type' => 'media' ) );
122
		self::$user                   = pods_api()->load_pods( array( 'type' => 'user' ) );
123
		self::$comment                = pods_api()->load_pods( array( 'type' => 'comment' ) );
124
		self::$settings               = pods_api()->load_pods( array( 'type' => 'settings' ) );
125
126
		// Handle Post Type Editor (needed for Pods core)
127
128
		// Loop through and add meta boxes for individual types (can't use this, Tabify doesn't pick it up)
129
		/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
130
        foreach ( self::$post_types as $post_type ) {
131
            $post_type_name = $post_type[ 'name' ];
132
133
            if ( !empty( $post_type[ 'object' ] ) )
134
                $post_type_name = $post_type[ 'object' ];
135
136
            add_action( 'add_meta_boxes_' . $post_type_name, array( $this, 'meta_post_add' ) );
137
        }
138
        */
139
140
		add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
141
		add_action( 'transition_post_status', array( $this, 'save_post_detect_new' ), 10, 3 );
142
		add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );
143
		add_filter( 'wp_insert_post_data', array( $this, 'save_post_track_changed_fields' ), 10, 2 );
144
145
		if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) {
146
			// Handle *_post_meta
147
			if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) {
148
				add_filter( 'get_post_metadata', array( $this, 'get_post_meta' ), 10, 4 );
149
			}
150
151
			if ( ! pods_tableless() ) {
152
				add_filter( 'add_post_metadata', array( $this, 'add_post_meta' ), 10, 5 );
153
				add_filter( 'update_post_metadata', array( $this, 'update_post_meta' ), 10, 5 );
154
				add_filter( 'delete_post_metadata', array( $this, 'delete_post_meta' ), 10, 5 );
155
			}
156
		}
157
158
		add_action( 'delete_post', array( $this, 'delete_post' ), 10, 1 );
159
160
		if ( ! empty( self::$taxonomies ) ) {
161
			$has_fields = false;
162
163
			// Handle Taxonomy Editor
164
			foreach ( self::$taxonomies as $taxonomy ) {
0 ignored issues
show
The expression self::$taxonomies of type array|object|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

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

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

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

Loading history...
165
				if ( empty( $taxonomy['fields'] ) ) {
166
					continue;
167
				}
168
169
				$has_fields = true;
170
171
				$taxonomy_name = $taxonomy['name'];
172
173
				if ( ! empty( $taxonomy['object'] ) ) {
174
					$taxonomy_name = $taxonomy['object'];
175
				}
176
177
				add_action( $taxonomy_name . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 );
178
				add_action( $taxonomy_name . '_add_form_fields', array( $this, 'meta_taxonomy' ), 10, 1 );
179
			}
180
181
			if ( $has_fields ) {
182
				// Handle Term Editor
183
				add_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 );
184
				add_action( 'create_term', array( $this, 'save_taxonomy' ), 10, 3 );
185
				add_action( 'edit_terms', array( $this, 'save_taxonomy_track_changed_fields' ), 10, 2 );
186
187
				if ( apply_filters( 'pods_meta_handler', true, 'term' ) ) {
188
					// Handle *_term_meta
189
					if ( apply_filters( 'pods_meta_handler_get', true, 'term' ) ) {
190
						add_filter( 'get_term_metadata', array( $this, 'get_term_meta' ), 10, 4 );
191
					}
192
193
					if ( ! pods_tableless() ) {
194
						add_filter( 'add_term_metadata', array( $this, 'add_term_meta' ), 10, 5 );
195
						add_filter( 'update_term_metadata', array( $this, 'update_term_meta' ), 10, 5 );
196
						add_filter( 'delete_term_metadata', array( $this, 'delete_term_meta' ), 10, 5 );
197
					}
198
				}
199
			}
200
		}
201
202
		/**
203
		 * Fires after a previously shared taxonomy term is split into two separate terms.
204
		 *
205
		 * @since 4.2.0
206
		 *
207
		 * @param int    $term_id          ID of the formerly shared term.
208
		 * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
209
		 * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
210
		 * @param string $taxonomy         Taxonomy for the split term.
211
		 */
212
		add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 );
213
214
		// Handle Delete
215
		add_action( 'delete_term_taxonomy', array( $this, 'delete_taxonomy' ), 10, 1 );
216
217
		if ( ! empty( self::$media ) ) {
218
			add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
219
			add_action( 'wp_ajax_save-attachment-compat', array( $this, 'save_media_ajax' ), 0 );
220
221
			add_filter( 'attachment_fields_to_edit', array( $this, 'meta_media' ), 10, 2 );
222
223
			add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 );
224
			add_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 );
225
			add_filter( 'wp_insert_attachment_data', array( $this, 'save_post_track_changed_fields' ), 10, 2 );
226
227
			if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) {
228
				// Handle *_post_meta
229
				if ( ! has_filter( 'get_post_metadata', array( $this, 'get_post_meta' ) ) ) {
230
					if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) {
231
						add_filter( 'get_post_metadata', array( $this, 'get_post_meta' ), 10, 4 );
232
					}
233
234
					if ( ! pods_tableless() ) {
235
						add_filter( 'add_post_metadata', array( $this, 'add_post_meta' ), 10, 5 );
236
						add_filter( 'update_post_metadata', array( $this, 'update_post_meta' ), 10, 5 );
237
						add_filter( 'delete_post_metadata', array( $this, 'delete_post_meta' ), 10, 5 );
238
					}
239
				}
240
			}
241
		}
242
243
		// Handle Delete
244
		add_action( 'delete_attachment', array( $this, 'delete_media' ), 10, 1 );
245
246
		if ( ! empty( self::$user ) ) {
247
			// Handle User Editor
248
			add_action( 'show_user_profile', array( $this, 'meta_user' ) );
249
			add_action( 'edit_user_profile', array( $this, 'meta_user' ) );
250
			add_action( 'user_register', array( $this, 'save_user' ) );
251
			add_action( 'profile_update', array( $this, 'save_user' ), 10, 2 );
252
			add_filter( 'pre_user_login', array( $this, 'save_user_track_changed_fields' ) );
253
254
			if ( apply_filters( 'pods_meta_handler', true, 'user' ) ) {
255
				// Handle *_user_meta
256
				if ( apply_filters( 'pods_meta_handler_get', true, 'user' ) ) {
257
					add_filter( 'get_user_metadata', array( $this, 'get_user_meta' ), 10, 4 );
258
				}
259
260
				if ( ! pods_tableless() ) {
261
					add_filter( 'add_user_metadata', array( $this, 'add_user_meta' ), 10, 5 );
262
					add_filter( 'update_user_metadata', array( $this, 'update_user_meta' ), 10, 5 );
263
					add_filter( 'delete_user_metadata', array( $this, 'delete_user_meta' ), 10, 5 );
264
				}
265
			}
266
		}
267
268
		// Handle Delete
269
		add_action( 'delete_user', array( $this, 'delete_user' ), 10, 1 );
270
271
		if ( ! empty( self::$comment ) ) {
272
			// Handle Comment Form / Editor
273
			add_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 );
274
			add_filter( 'comment_form_default_fields', array( $this, 'meta_comment_new' ) );
275
			add_action( 'add_meta_boxes_comment', array( $this, 'meta_comment_add' ) );
276
			add_filter( 'pre_comment_approved', array( $this, 'validate_comment' ), 10, 2 );
277
			add_action( 'comment_post', array( $this, 'save_comment' ) );
278
			add_action( 'edit_comment', array( $this, 'save_comment' ) );
279
			add_action( 'wp_update_comment_data', array( $this, 'save_comment_track_changed_fields' ), 10, 3 );
280
281
			if ( apply_filters( 'pods_meta_handler', true, 'comment' ) ) {
282
				// Handle *_comment_meta
283
				add_filter( 'get_comment_metadata', array( $this, 'get_comment_meta' ), 10, 4 );
284
285
				if ( ! pods_tableless() ) {
286
					add_filter( 'add_comment_metadata', array( $this, 'add_comment_meta' ), 10, 5 );
287
					add_filter( 'update_comment_metadata', array( $this, 'update_comment_meta' ), 10, 5 );
288
					add_filter( 'delete_comment_metadata', array( $this, 'delete_comment_meta' ), 10, 5 );
289
				}
290
			}
291
		}
292
293
		// Handle Delete
294
		add_action( 'delete_comment', array( $this, 'delete_comment' ), 10, 1 );
295
296
		// @todo Patch core to provide $option back in filters, patch core to add filter pre_add_option to add_option
297
		/*if ( !empty( self::$settings ) ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
298
            foreach ( self::$settings as $setting_pod ) {
299
                foreach ( $setting_pod[ 'fields' ] as $option ) {
300
                    add_filter( 'pre_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'get_option' ), 10, 1 );
301
                    add_action( 'add_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'add_option' ), 10, 2 );
302
                    add_filter( 'pre_update_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'update_option' ), 10, 2 );
303
                }
304
            }
305
        }*/
306
307
		if ( is_admin() ) {
308
			$this->integrations();
309
		}
310
311
		add_action( 'init', array( $this, 'enqueue' ), 9 );
312
313
		if ( function_exists( 'pll_current_language' ) ) {
314
			add_action( 'init', array( $this, 'cache_pods' ), 101 );
315
		}
316
317
		do_action( 'pods_meta_init' );
318
319
		return $this;
320
	}
321
322
	/**
323
	 *
324
	 */
325
	public static function enqueue() {
326
327
		foreach ( self::$queue as $type => $objects ) {
328
			foreach ( $objects as $pod_name => $pod ) {
329
				pods_transient_set( 'pods_pod_' . $pod_name, $pod );
330
			}
331
332
			self::$$type = array_merge( self::$$type, $objects );
333
		}
334
	}
335
336
	/**
337
	 * Go back through and cache the Pods now that Polylang has loaded
338
	 */
339
	public function cache_pods() {
340
341
		self::$advanced_content_types = pods_api()->load_pods( array( 'type' => 'pod', 'refresh' => true ) );
342
		self::$post_types             = pods_api()->load_pods( array( 'type' => 'post_type', 'refresh' => true ) );
343
		self::$taxonomies             = pods_api()->load_pods( array( 'type' => 'taxonomy', 'refresh' => true ) );
344
		self::$media                  = pods_api()->load_pods( array( 'type' => 'media', 'refresh' => true ) );
345
		self::$user                   = pods_api()->load_pods( array( 'type' => 'user', 'refresh' => true ) );
346
		self::$comment                = pods_api()->load_pods( array( 'type' => 'comment', 'refresh' => true ) );
347
		self::$settings               = pods_api()->load_pods( array( 'type' => 'settings', 'refresh' => true ) );
348
	}
349
350
	/**
351
	 * @param $type
352
	 * @param $pod
353
	 *
354
	 * @return array|bool|int
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array|integer|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...
355
	 */
356
	public function register( $type, $pod ) {
357
358
		$pod_type = $type;
359
360
		if ( 'post_type' == $type ) {
361
			$type = 'post_types';
362
		} elseif ( 'taxonomy' == $type ) {
363
			$type = 'taxonomies';
364
		} elseif ( 'pod' == $type ) {
365
			$type = 'advanced_content_types';
366
		}
367
368
		if ( ! isset( self::$queue[ $type ] ) ) {
369
			self::$queue[ $type ] = array();
370
		}
371
372
		if ( is_array( $pod ) && ! empty( $pod ) && ! isset( $pod['name'] ) ) {
373
			$data = array();
374
375
			foreach ( $pod as $p ) {
376
				$data[] = $this->register( $type, $p );
377
			}
378
379
			return $data;
380
		}
381
382
		$pod['type'] = $pod_type;
383
		$pod         = pods_api()->save_pod( $pod, false, false );
384
385
		if ( ! empty( $pod ) ) {
386
			self::$object_identifier --;
387
388
			self::$queue[ $type ][ $pod['name'] ] = $pod;
389
390
			return $pod;
391
		}
392
393
		return false;
394
	}
395
396
	/**
397
	 * @param $pod
398
	 * @param $field
399
	 *
400
	 * @return array|bool|int
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array|integer|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...
401
	 */
402
	public function register_field( $pod, $field ) {
403
404
		if ( is_array( $pod ) && ! empty( $pod ) && ! isset( $pod['name'] ) ) {
405
			$data = array();
406
407
			foreach ( $pod as $p ) {
408
				$data[] = $this->register_field( $p, $field );
409
			}
410
411
			return $data;
412
		}
413
414
		if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $pod ) {
415
			self::$current_pod_data = pods_api()->load_pod( array( 'name' => $pod ), false );
416
		}
417
418
		$pod = self::$current_pod_data;
419
420
		if ( ! empty( $pod ) ) {
421
			$type = $pod['type'];
422
423
			if ( 'post_type' == $pod['type'] ) {
424
				$type = 'post_types';
425
			} elseif ( 'taxonomy' == $pod['type'] ) {
426
				$type = 'taxonomies';
427
			} elseif ( 'pod' == $pod['type'] ) {
428
				$type = 'advanced_content_types';
429
			}
430
431
			if ( ! isset( self::$queue[ $pod['type'] ] ) ) {
432
				self::$queue[ $type ] = array();
433
			}
434
435
			$field = pods_api()->save_field( $field, false, false, $pod['id'] );
436
437
			if ( ! empty( $field ) ) {
438
				$pod['fields'][ $field['name'] ] = $field;
439
440
				self::$queue[ $type ][ $pod['name'] ] = $pod;
441
442
				return $field;
443
			}
444
		}
445
446
		return false;
447
	}
448
449
	/**
450
	 *
451
	 */
452
	public function integrations() {
453
454
		// `ac_is_version_gte` is since AC 3.0+
455
		if ( ! function_exists( 'ac_is_version_gte' ) ) {
456
			// Codepress Admin Columns < 2.x
457
			add_filter( 'cac/storage_model/meta_keys', array( $this, 'cpac_meta_keys' ), 10, 2 );
458
			add_filter( 'cac/post_types', array( $this, 'cpac_post_types' ), 10, 1 );
459
			add_filter( 'cac/column/meta/value', array( $this, 'cpac_meta_value' ), 10, 3 );
460
		} else {
461
			// Codepress Admin Columns 3.x +
462
			add_filter( 'ac/column/custom_field/meta_keys', array( $this, 'cpac_meta_keys' ), 10, 2 );
463
			add_filter( 'ac/post_types', array( $this, 'cpac_post_types' ), 10, 1 );
464
			add_filter( 'ac/column/value', array( $this, 'cpac_meta_value' ), 10, 3 );
465
		}
466
	}
467
468
	/**
469
	 * Admin Columns: Remove internal meta keys + add existing (public) Pod field keys.
470
	 *
471
	 * @param array                           $meta_fields
472
	 * @param \AC_Settings_Column_CustomField $storage_model
473
	 *
474
	 * @return array
475
	 */
476
	public function cpac_meta_keys( $meta_fields, $storage_model ) {
477
478
		$object_type = 'post_type';
479
		$object      = null;
480
		$obj         = null;
481
482
		if ( ! method_exists( $storage_model, 'get_column' ) ) {
483
			// Codepress Admin Columns < 2.x
484
			$object = $storage_model->key;
485
			$type   = $storage_model->type;
486
		} else {
487
			// Codepress Admin Columns 3.x +
488
			$obj    = $storage_model->get_column();
489
			$object = $obj->get_list_screen()->get_key();
490
			$type   = $obj->get_list_screen()->get_meta_type();
491
		}
492
493
		if ( in_array( $type, array( 'wp-links', 'link' ), true ) ) {
494
			$object_type = $object = 'link';
495
		} elseif ( in_array( $type, array( 'wp-media', 'media' ), true ) ) {
496
			$object_type = $object = 'media';
497
		} elseif ( in_array( $type, array( 'wp-users', 'user' ), true ) ) {
498
			$object_type = $object = 'user';
499
		} elseif ( in_array( $type, array( 'wp-comments', 'comment' ), true ) ) {
500
			$object_type = $object = 'comment';
501
		} elseif ( 'taxonomy' === $type ) {
502
			$object_type = 'taxonomy';
503
			if ( ! $obj ) {
504
				// Codepress Admin Columns < 2.x
505
				$object = $storage_model->taxonomy;
506
			} else {
507
				// Codepress Admin Columns 3.x +
508
				$object = $obj->get_taxonomy();
509
			}
510
		}
511
512
		if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $object ) {
513
			self::$current_pod_data = pods_api()->load_pod( array( 'name' => $object ), false );
514
		}
515
516
		$pod = self::$current_pod_data;
517
518
		// Add Pods fields
519
		if ( ! empty( $pod ) && $object_type == $pod['type'] ) {
520
			foreach ( $pod['fields'] as $field => $field_data ) {
521
				if ( ! is_array( $meta_fields ) ) {
522
					$meta_fields = array();
523
				}
524
525
				if ( ! in_array( $field, $meta_fields ) ) {
526
					$meta_fields[] = $field;
527
				}
528
			}
529
		}
530
531
		// Remove internal Pods fields
532
		if ( is_array( $meta_fields ) ) {
533
			foreach ( $meta_fields as $k => $meta_field ) {
534
				if ( 0 === strpos( $meta_field, '_pods_' ) ) {
535
					unset( $meta_fields[ $k ] );
536
				}
537
			}
538
		}
539
540
		return $meta_fields;
541
	}
542
543
	/**
544
	 * Admin Columns: Remove internal Pods post types.
545
	 *
546
	 * @param  array $post_types
547
	 *
548
	 * @return array
549
	 */
550
	public function cpac_post_types( $post_types ) {
551
552
		foreach ( $post_types as $post_type => $post_type_name ) {
553
			if ( 0 === strpos( $post_type, '_pods_' ) || 0 === strpos( $post_type_name, '_pods_' ) ) {
554
				unset( $post_types[ $post_type ] );
555
			}
556
		}
557
558
		return $post_types;
559
	}
560
561
	/**
562
	 * Admin Columns: For custom field column types.
563
	 *
564
	 * @param mixed      $meta
565
	 * @param int        $id
566
	 * @param \AC_Column $obj
567
	 *
568
	 * @return mixed
569
	 */
570
	public function cpac_meta_value( $meta, $id, $obj ) {
571
572
		$tableless_field_types = PodsForm::tableless_field_types();
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $tableless_field_types exceeds the maximum configured length of 20.

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

Loading history...
573
574
		$object_type = 'post_type';
575
		$object      = null;
576
		$type        = null;
577
578
		if ( ! method_exists( $obj, 'get_list_screen' ) ) {
579
			// Codepress Admin Columns < 2.x
580
			$object = $obj->storage_model->key;
581
			$type   = $obj->storage_model->type;
582
		} else {
583
			// Codepress Admin Columns 3.x +
584
			$object = $obj->get_list_screen()->get_key();
585
			$type   = $obj->get_list_screen()->get_meta_type();
586
		}
587
588
		if ( in_array( $type, array( 'wp-links', 'link' ), true ) ) {
589
			$object_type = $object = 'link';
590
		} elseif ( in_array( $type, array( 'wp-media', 'media' ), true ) ) {
591
			$object_type = $object = 'media';
592
		} elseif ( in_array( $type, array( 'wp-users', 'user' ), true ) ) {
593
			$object_type = $object = 'user';
594
		} elseif ( in_array( $type, array( 'wp-comments', 'comment' ), true ) ) {
595
			$object_type = $object = 'comment';
596
		} elseif ( 'taxonomy' === $type ) {
597
			$object_type = 'taxonomy';
598
			if ( ! method_exists( $obj, 'get_taxonomy' ) ) {
599
				// Codepress Admin Columns < 2.x
600
				$object = $obj->storage_model->taxonomy;
601
			} else {
602
				// Codepress Admin Columns 3.x +
603
				$object = $obj->get_taxonomy();
604
			}
605
		}
606
607
		$field      = ( "cpachidden" === substr( $obj->get_option( 'field' ), 0, 10 ) ) ? str_replace( 'cpachidden', '', $obj->get_option( 'field' ) ) : $obj->get_option( 'field' );
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal cpachidden does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
608
		$field_type = $obj->get_option( 'field_type' );
609
610
		if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] !== $object ) {
611
			self::$current_pod_data = pods_api()->load_pod( array( 'name' => $object ), false );
612
		}
613
614
		$pod = self::$current_pod_data;
615
616
		// Add Pods fields
617
		if ( ! empty( $pod ) && isset( $pod['fields'][ $field ] ) ) {
618
			if ( in_array( $pod['type'], array(
619
					'post_type',
620
					'media',
621
					'taxonomy',
622
					'user',
623
					'comment',
624
					'media'
625
				), true ) && ( ! empty( $field_type ) || in_array( $pod['fields'][ $field ]['type'], $tableless_field_types, true ) ) ) {
0 ignored issues
show
This line of the multi-line function call does not seem to be indented correctly. Expected 12 spaces, but found 16.
Loading history...
626
				$metadata_type = $pod['type'];
627
628
				if ( in_array( $metadata_type, array( 'post_type', 'media' ), true ) ) {
629
					$metadata_type = 'post';
630
				} elseif ( 'taxonomy' === $metadata_type ) {
631
					$metadata_type = 'term';
632
				}
633
634
				if ( 'term' === $metadata_type && ! function_exists( 'get_term_meta' ) ) {
635
					$podterms = pods( $pod['name'], $id );
636
637
					$meta = $podterms->field( $field );
638
				} else {
639
					$meta = get_metadata( $metadata_type, $id, $field, ( 'array' !== $field_type ) );
640
				}
641
			} elseif ( 'taxonomy' === $pod['type'] ) {
642
				$podterms = pods( $pod['name'], $id );
643
644
				$meta = $podterms->field( $field );
645
			}
646
647
			$meta = PodsForm::field_method( $pod['fields'][ $field ]['type'], 'ui', $id, $meta, $field, array_merge( $pod['fields'][ $field ], $pod['fields'][ $field ]['options'] ), $pod['fields'], $pod );
648
		}
649
650
		return $meta;
651
	}
652
653
	/**
654
	 * Add a meta group of fields to add/edit forms
655
	 *
656
	 * @param string|array $pod      The pod or type of element to attach the group to.
657
	 * @param string       $label    Title of the edit screen section, visible to user.
658
	 * @param string|array $fields   Either a comma separated list of text fields or an associative array containing
659
	 *                               field infomration.
660
	 * @param string       $context  (optional) The part of the page where the edit screen section should be shown
661
	 *                               ('normal', 'advanced', or 'side').
662
	 * @param string       $priority (optional) The priority within the context where the boxes should show ('high',
663
	 *                               'core', 'default' or 'low').
664
	 *
665
	 * @since 2.0
666
	 *
667
	 * @return mixed|void
668
	 */
669
	public function group_add( $pod, $label, $fields, $context = 'normal', $priority = 'default' ) {
670
671
		if ( is_array( $pod ) && ! empty( $pod ) && ! isset( $pod['name'] ) ) {
672
			foreach ( $pod as $p ) {
673
				$this->group_add( $p, $label, $fields, $context, $priority );
674
			}
675
676
			return true;
677
		}
678
679
		if ( ! is_array( $pod ) ) {
680
			if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $pod ) {
681
				self::$current_pod_data = pods_api()->load_pod( array( 'name' => $pod ), false );
682
			}
683
684
			if ( ! empty( self::$current_pod_data ) ) {
685
				$pod = self::$current_pod_data;
686
			} else {
687
				$type = 'post_type';
688
689
				if ( in_array( $pod, array( 'media', 'user', 'comment' ) ) ) {
690
					$type = $pod;
691
				}
692
693
				$pod = array(
694
					'name' => $pod,
695
					'type' => $type
696
				);
697
			}
698
		}
699
700
		if ( is_array( $pod ) && ! isset( $pod['id'] ) ) {
701
			$defaults = array(
702
				'name' => '',
703
				'type' => 'post_type'
704
			);
705
706
			$pod = array_merge( $defaults, $pod );
707
		}
708
709
		if ( 'post' == $pod['type'] ) {
710
			$pod['type'] = 'post_type';
711
		}
712
713
		if ( empty( $pod['name'] ) && isset( $pod['object'] ) && ! empty( $pod['object'] ) ) {
714
			$pod['name'] = $pod['object'];
715
		} elseif ( ! isset( $pod['object'] ) || empty( $pod['object'] ) ) {
716
			$pod['object'] = $pod['name'];
717
		}
718
719
		if ( empty( $pod['object'] ) ) {
720
			return pods_error( __( 'Object required to add a Pods meta group', 'pods' ) );
721
		}
722
723
		$object_name = $pod['object'];
724
725
		if ( 'pod' == $pod['type'] ) {
726
			$object_name = $pod['name'];
727
		}
728
729
		if ( ! isset( self::$groups[ $pod['type'] ] ) ) {
730
			self::$groups[ $pod['type'] ] = array();
731
		}
732
733
		if ( ! isset( self::$groups[ $pod['type'] ][ $object_name ] ) ) {
734
			self::$groups[ $pod['type'] ][ $object_name ] = array();
735
		}
736
737
		$_fields = array();
738
739
		if ( ! is_array( $fields ) ) {
740
			$fields = explode( ',', $fields );
741
		}
742
743
		foreach ( $fields as $k => $field ) {
744
			$name = $k;
745
746
			$defaults = array(
747
				'name'  => $name,
748
				'label' => $name,
749
				'type'  => 'text'
750
			);
751
752
			if ( ! is_array( $field ) ) {
753
				$name = trim( $field );
754
755
				$field = array(
756
					'name'  => $name,
757
					'label' => $name
758
				);
759
			}
760
761
			$field = array_merge( $defaults, $field );
762
763
			$field['name'] = trim( $field['name'] );
764
765
			if ( isset( $pod['fields'] ) && isset( $pod['fields'][ $field['name'] ] ) ) {
766
				$field = array_merge( $field, $pod['fields'][ $field['name'] ] );
767
			}
768
769
			$_fields[ $k ] = $field;
770
		}
771
772
		// Setup field options
773
		$fields = PodsForm::fields_setup( $_fields );
774
775
		$group = array(
776
			'pod'      => $pod,
777
			'label'    => $label,
778
			'fields'   => $fields,
779
			'context'  => $context,
780
			'priority' => $priority
781
		);
782
783
		// Filter group data, pass vars separately for reference down the line (in case array changed by other filter)
784
		$group = apply_filters( 'pods_meta_group_add_' . $pod['type'] . '_' . $object_name, $group, $pod, $label, $fields );
785
		$group = apply_filters( 'pods_meta_group_add_' . $pod['type'], $group, $pod, $label, $fields );
786
		$group = apply_filters( 'pods_meta_group_add', $group, $pod, $label, $fields );
787
788
		self::$groups[ $pod['type'] ][ $object_name ][] = $group;
789
790
		// Hook it up!
791
		if ( 'post_type' == $pod['type'] ) {
792
			if ( ! has_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ) ) {
793
				add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
794
			}
795
796
			/*if ( !has_action( 'save_post', array( $this, 'save_post' ), 10, 3 ) )
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
797
                add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );*/
798
		} elseif ( 'taxonomy' == $pod['type'] ) {
799
			if ( ! has_action( $pod['object'] . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 ) ) {
800
				add_action( $pod['object'] . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 );
801
				add_action( $pod['object'] . '_add_form_fields', array( $this, 'meta_taxonomy' ), 10, 1 );
802
			}
803
804
			if ( ! has_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 ) ) {
805
				add_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 );
806
				add_action( 'create_term', array( $this, 'save_taxonomy' ), 10, 3 );
807
			}
808
		} elseif ( 'media' == $pod['type'] ) {
809
			if ( ! has_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 ) ) {
810
				add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
811
				add_action( 'wp_ajax_save-attachment-compat', array( $this, 'save_media_ajax' ), 0 );
812
813
				add_filter( 'attachment_fields_to_edit', array( $this, 'meta_media' ), 10, 2 );
814
815
				add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 );
816
				add_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 );
817
			}
818
		} elseif ( 'user' == $pod['type'] ) {
819
			if ( ! has_action( 'show_user_profile', array( $this, 'meta_user' ) ) ) {
820
				add_action( 'show_user_profile', array( $this, 'meta_user' ) );
821
				add_action( 'edit_user_profile', array( $this, 'meta_user' ) );
822
				add_action( 'user_register', array( $this, 'save_user' ) );
823
				add_action( 'profile_update', array( $this, 'save_user' ), 10, 2 );
824
			}
825
		} elseif ( 'comment' == $pod['type'] ) {
826
			if ( ! has_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 ) ) {
827
				add_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 );
828
				add_filter( 'comment_form_default_fields', array( $this, 'meta_comment_new' ) );
829
				add_action( 'add_meta_boxes_comment', array( $this, 'meta_comment_add' ) );
830
				add_action( 'wp_insert_comment', array( $this, 'save_comment' ) );
831
				add_action( 'edit_comment', array( $this, 'save_comment' ) );
832
			}
833
		}
834
	}
835
836
	/**
837
	 * @param $type
838
	 * @param $name
839
	 *
840
	 * @return array|bool|mixed|void
841
	 */
842
	public function object_get( $type, $name ) {
843
844
		$object = self::$post_types;
845
846
		if ( 'term' == $type ) {
847
			$type = 'taxonomy';
848
		}
849
850
		if ( 'taxonomy' == $type ) {
851
			$object = self::$taxonomies;
852
		} elseif ( 'media' == $type ) {
853
			$object = self::$media;
854
		} elseif ( 'user' == $type ) {
855
			$object = self::$user;
856
		} elseif ( 'comment' == $type ) {
857
			$object = self::$comment;
858
		}
859
860
		if ( 'pod' != $type && ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) {
861
			$pod = $object[ $name ];
862
		} else {
863
			if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $name ) {
864
				self::$current_pod_data = pods_api()->load_pod( array( 'name' => $name ), false );
865
			}
866
867
			$pod = self::$current_pod_data;
868
		}
869
870
		if ( empty( $pod ) ) {
871
			return array();
872
		}
873
874
		$defaults = array(
875
			'name'   => 'post',
876
			'object' => 'post',
877
			'type'   => 'post_type'
878
		);
879
880
		$pod = array_merge( $defaults, (array) $pod );
881
882
		if ( empty( $pod['name'] ) ) {
883
			$pod['name'] = $pod['object'];
884
		} elseif ( empty( $pod['object'] ) ) {
885
			$pod['object'] = $pod['name'];
886
		}
887
888
		if ( $pod['type'] != $type ) {
889
			return array();
890
		}
891
892
		return $pod;
893
	}
894
895
	/**
896
	 * @param $type
897
	 * @param $name
898
	 * @param $default_fields
899
	 *
900
	 * @return array
901
	 */
902
	public function groups_get( $type, $name, $default_fields = null ) {
903
904
		if ( 'post_type' == $type && 'attachment' == $name ) {
905
			$type = 'media';
906
			$name = 'media';
907
		} elseif ( 'term' == $type ) {
908
			$type = 'taxonomy';
909
		}
910
911
		do_action( 'pods_meta_groups', $type, $name );
912
913
		$pod    = array();
914
		$fields = array();
915
916
		$object = self::$post_types;
917
918
		if ( 'taxonomy' == $type ) {
919
			$object = self::$taxonomies;
920
		} elseif ( 'media' == $type ) {
921
			$object = self::$media;
922
		} elseif ( 'user' == $type ) {
923
			$object = self::$user;
924
		} elseif ( 'comment' == $type ) {
925
			$object = self::$comment;
926
		} elseif ( 'pod' == $type ) {
927
			$object = self::$advanced_content_types;
928
		}
929
930
		if ( ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) {
931
			$fields = $object[ $name ]['fields'];
932
		} else {
933
			if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $name ) {
934
				self::$current_pod_data = pods_api()->load_pod( array( 'name' => $name ), false );
935
			}
936
937
			$pod = self::$current_pod_data;
938
939
			if ( ! empty( $pod ) ) {
940
				$fields = $pod['fields'];
941
			}
942
		}
943
944
		if ( null !== $default_fields ) {
945
			$fields = $default_fields;
946
		}
947
948
		$defaults = array(
949
			'name'   => 'post',
950
			'object' => 'post',
951
			'type'   => 'post_type'
952
		);
953
954
		$pod = array_merge( $defaults, (array) $pod );
955
956
		if ( empty( $pod['name'] ) ) {
957
			$pod['name'] = $pod['object'];
958
		} elseif ( empty( $pod['object'] ) ) {
959
			$pod['object'] = $pod['name'];
960
		}
961
962
		if ( $pod['type'] != $type ) {
963
			return array();
964
		}
965
966
		$groups = array(
967
			array(
968
				'pod'      => $pod,
969
				/**
970
				 * Filter the title of the Pods Metabox In The Post Editor
971
				 *
972
				 * @param string  $title  The title to use, default is 'More Fields'
973
				 * @param obj|Pod $pod    Current Pods Object
974
				 * @param array   $fields Array of fields that will go in the metabox
975
				 * @param string  $type   The type of Pod
976
				 * @param string  $name   Name of the Pod
977
				 *
978
				 * @return string The title for the metabox.
979
				 *
980
				 * @since unknown
981
				 */
982
				'label'    => apply_filters( 'pods_meta_default_box_title', __( 'More Fields', 'pods' ), $pod, $fields, $type, $name ),
983
				'fields'   => $fields,
984
				'context'  => 'normal',
985
				'priority' => 'default'
986
			)
987
		);
988
989
		if ( isset( self::$groups[ $type ] ) && isset( self::$groups[ $type ][ $name ] ) ) {
990
			$groups = self::$groups[ $type ][ $name ];
991
		}
992
993
		/**
994
		 * Filter the array of field groups
995
		 *
996
		 * @param array  $groups Array of groups
997
		 * @param string $type   The type of Pod
998
		 * @param string $name   Name of the Pod
999
		 *
1000
		 * @since 2.6.6
1001
		 */
1002
		return apply_filters( 'pods_meta_groups_get', $groups, $type, $name );
1003
	}
1004
1005
	/**
1006
	 * @param      $post_type
1007
	 * @param null $post
1008
	 */
1009
	public function meta_post_add( $post_type, $post = null ) {
1010
1011
		if ( 'comment' == $post_type ) {
1012
			return;
1013
		}
1014
1015
		if ( is_object( $post ) ) {
1016
			$post_type = $post->post_type;
1017
		}
1018
1019
		$groups           = $this->groups_get( 'post_type', $post_type );
1020
		$pods_field_found = false;
1021
1022
		foreach ( $groups as $group ) {
1023
			if ( empty( $group['fields'] ) ) {
1024
				continue;
1025
			}
1026
1027
			$field_found  = false;
1028
			$group_hidden = true;
1029
1030
			foreach ( $group['fields'] as $field ) {
1031
				if ( false !== PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'] ) ) {
1032
					$field_found = true;
1033
				}
1034
				if ( ! isset( $field['options']['hidden'] ) || 1 != (int) $field['options']['hidden'] ) {
1035
					$group_hidden = false;
1036
				}
1037
			}
1038
1039
			if ( $group_hidden ) {
1040
				continue;
1041
			}
1042
1043
			if ( empty( $group['label'] ) ) {
1044
				$group['label'] = get_post_type_object( $post_type )->labels->label;
1045
			}
1046
1047
			if ( $field_found ) {
1048
				$pods_field_found = true;
1049
				add_meta_box( 'pods-meta-' . sanitize_title( $group['label'] ), $group['label'], array(
1050
						$this,
1051
						'meta_post'
1052
					), $post_type, $group['context'], $group['priority'], array( 'group' => $group ) );
0 ignored issues
show
This line of the multi-line function call does not seem to be indented correctly. Expected 16 spaces, but found 20.
Loading history...
1053
1054
			}
1055
		}
1056
1057
		if ( $pods_field_found ) {
1058
			// Only add the classes to forms that actually have pods fields
1059
			add_action( 'post_edit_form_tag', array( $this, 'add_class_submittable' ) );
1060
		}
1061
	}
1062
1063
	/**
1064
	 *
1065
	 * Called by 'post_edit_form_tag' action to include the classes in the <form> tag
1066
	 *
1067
	 */
1068
	public function add_class_submittable() {
1069
1070
		echo ' class="pods-submittable pods-form"';
1071
	}
1072
1073
	/**
1074
	 * @param $post
1075
	 * @param $metabox
1076
	 */
1077
	public function meta_post( $post, $metabox ) {
1078
1079
		wp_enqueue_style( 'pods-form' );
1080
		wp_enqueue_script( 'pods' );
1081
1082
		$pod_type = 'post';
1083
1084
		if ( 'attachment' == $post->post_type ) {
1085
			$pod_type = 'media';
1086
		}
1087
1088
		do_action( 'pods_meta_' . __FUNCTION__, $post );
1089
1090
		$hidden_fields = array();
1091
1092
		$id = null;
1093
1094
		if ( is_object( $post ) && false === strpos( $_SERVER['REQUEST_URI'], '/post-new.php' ) ) {
1095
			$id = $post->ID;
1096
		}
1097
1098
		if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod ) || self::$current_pod->pod != $metabox['args']['group']['pod']['name'] ) {
1099
			self::$current_pod = pods( $metabox['args']['group']['pod']['name'], $id, true );
1100
		} elseif ( self::$current_pod->id() != $id ) {
1101
			self::$current_pod->fetch( $id );
1102
		}
1103
1104
		$pod = self::$current_pod;
1105
1106
		$fields = $metabox['args']['group']['fields'];
1107
1108
		/**
1109
		 * Filter the fields used for the Pods metabox group
1110
		 *
1111
		 * @since 2.6.6
1112
		 *
1113
		 * @param array   $fields  Fields from the current Pod metabox group
1114
		 * @param int     $id      Post ID
1115
		 * @param WP_Post $post    Post object
1116
		 * @param array   $metabox Metabox args from the current Pod metabox group
1117
		 * @param Pods    $pod     Pod object
1118
		 */
1119
		$fields = apply_filters( 'pods_meta_post_fields', $fields, $id, $post, $metabox, $pod );
1120
1121
		if ( empty( $fields ) ) {
1122
			_e( 'There are no fields to display', 'pods' );
1123
1124
			return;
1125
		}
1126
		?>
1127
		<table class="form-table pods-metabox pods-admin pods-dependency">
1128
			<?php
1129
			echo PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_' . $pod_type ), 'hidden' );
1130
1131
			foreach ( $fields as $field ) {
1132
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field['options'], $fields, $pod, $id ) ) {
1133
					if ( pods_var( 'hidden', $field['options'], false ) ) {
1134
						$field['type'] = 'hidden';
1135
					} else {
1136
						continue;
1137
					}
1138
				} elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
1139
					$field['type'] = 'hidden';
1140
				}
1141
1142
				$value = '';
1143
1144
				if ( ! empty( $pod ) ) {
1145
					pods_no_conflict_on( 'post' );
1146
1147
					$value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
1148
1149
					pods_no_conflict_off( 'post' );
1150
				} elseif ( ! empty( $id ) ) {
1151
					$value = get_post_meta( $id, $field['name'], true );
1152
				}
1153
1154
				if ( 'hidden' == $field['type'] ) {
1155
					$hidden_fields[] = array(
1156
						'field' => $field,
1157
						'value' => $value
1158
					);
1159
				} else {
1160
					$dep_options = PodsForm::dependencies( $field, 'pods-meta-' );
1161
					$dep_classes = $dep_options['classes'];
1162
					$dep_data    = $dep_options['data'];
1163
1164
					do_action( 'pods_meta_' . __FUNCTION__ . '_' . $field['name'], $post, $field, $pod );
1165
					?>
1166
					<tr class="form-field pods-field pods-field-input <?php echo esc_attr( 'pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ) ); ?> <?php echo esc_attr( $dep_classes ); ?>" <?php PodsForm::data( $dep_data ); ?>">
1167
					<th scope="row" valign="top"><?php echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field ); ?></th>
1168
					<td>
1169
						<?php
1170
						// Remove any extra ? help icons
1171
						if ( isset( $field['help'] ) ) {
1172
							unset( $field['help'] );
1173
						}
1174
						?>
1175
						<div class="pods-submittable-fields">
1176
							<?php echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ); ?>
1177
							<?php echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field ); ?>
1178
						</div>
1179
					</td>
1180
					</tr>
1181
					<?php
1182
					do_action( 'pods_meta_' . __FUNCTION__ . '_' . $field['name'] . '_post', $post, $field, $pod );
1183
				}
1184
			}
1185
			?>
1186
		</table>
1187
1188
		<?php
1189
		do_action( 'pods_meta_' . __FUNCTION__ . '_post', $post );
1190
1191
		foreach ( $hidden_fields as $hidden_field ) {
1192
			$field_data = $hidden_field['field'];
1193
1194
			echo PodsForm::field( 'pods_meta_' . $field_data['name'], $hidden_field['value'], 'hidden', $field_data );
1195
		}
1196
		?>
1197
1198
		<script type="text/javascript">
1199
			jQuery( function ( $ ) {
1200
				$( document ).Pods( 'validate' );
1201
				$( document ).Pods( 'submit_meta' );
1202
				$( document ).Pods( 'dependency', true );
1203
			} );
1204
		</script>
1205
		<?php
1206
	}
1207
1208
	/**
1209
	 * Handle integration with the transition_post_status hook
1210
	 *
1211
	 * @see wp_transition_post_status
1212
	 *
1213
	 * @param string  $new_status
1214
	 * @param string  $old_status
1215
	 * @param WP_Post $post
1216
	 */
1217
	public function save_post_detect_new( $new_status, $old_status, $post ) {
1218
1219
		if ( $post ) {
1220
			self::$old_post_status[ $post->post_type ] = $old_status;
1221
		}
1222
1223
	}
1224
1225
	/**
1226
	 * Handle integration with the save_post hook
1227
	 *
1228
	 * @see wp_insert_post
1229
	 *
1230
	 * @param int       $post_id
1231
	 * @param WP_Post   $post
1232
	 * @param bool|null $update
1233
	 */
1234
	public function save_post( $post_id, $post, $update = null ) {
1235
1236
		if ( empty( $post ) ) {
1237
			return;
1238
		}
1239
1240
		$is_new_item = false;
1241
1242
		if ( is_bool( $update ) ) {
1243
			$is_new_item = ! $update;
1244
		} // false is new item
1245
		elseif ( isset( self::$old_post_status[ $post->post_type ] ) && in_array( self::$old_post_status[ $post->post_type ], array(
1246
				'new',
1247
				'auto-draft'
1248
			), true ) ) {
0 ignored issues
show
This line of the multi-line function call does not seem to be indented correctly. Expected 8 spaces, but found 12.
Loading history...
1249
			$is_new_item = true;
1250
		}
1251
1252
		$nonced = wp_verify_nonce( pods_v( 'pods_meta', 'post' ), 'pods_meta_post' );
1253
1254
		if ( ! $is_new_item && false === $nonced ) {
1255
			return;
1256
		}
1257
1258
		// Unset to avoid manual new post issues
1259
		if ( isset( self::$old_post_status[ $post->post_type ] ) ) {
1260
			unset( self::$old_post_status[ $post->post_type ] );
1261
		}
1262
1263
		$blacklisted_types = array(
1264
			'revision',
1265
			'_pods_pod',
1266
			'_pods_field'
1267
		);
1268
1269
		$blacklisted_types = apply_filters( 'pods_meta_save_post_blacklist_types', $blacklisted_types, $post_id, $post );
1270
1271
		// @todo Figure out how to hook into autosave for saving meta
1272
1273
		// Block Autosave and Revisions
1274
		if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || in_array( $post->post_type, $blacklisted_types ) ) {
1275
			return;
1276
		}
1277
1278
		// Block Quick Edits / Bulk Edits
1279
		if ( 'edit.php' === pods_v( 'pagenow', 'global' ) && ( 'inline-save' === pods_v( 'action', 'post' ) || null !== pods_v( 'bulk_edit' ) || is_array( pods_v( 'post' ) ) ) ) {
1280
			return;
1281
		}
1282
1283
		// Block Trash
1284
		if ( in_array( pods_v( 'action' ), array( 'untrash', 'trash' ), true ) ) {
1285
			return;
1286
		}
1287
1288
		// Block Auto-drafting and Trash (not via Admin action)
1289
		$blacklisted_status = array(
1290
			'auto-draft',
1291
			'trash',
1292
		);
1293
1294
		$blacklisted_status = apply_filters( 'pods_meta_save_post_blacklist_status', $blacklisted_status, $post_id, $post );
1295
1296
		if ( in_array( $post->post_status, $blacklisted_status ) ) {
1297
			return;
1298
		}
1299
1300
		$groups = $this->groups_get( 'post_type', $post->post_type );
1301
1302
		$id = $post_id;
1303
1304
		if ( ! is_object( self::$current_pod ) || self::$current_pod->pod !== $post->post_type ) {
1305
			self::$current_pod = pods( $post->post_type, $id, true );
1306
		} elseif ( is_object( self::$current_pod ) && (int) self::$current_pod->id() !== (int) $id ) {
1307
			self::$current_pod->fetch( $id );
1308
		}
1309
1310
		$pod  = self::$current_pod;
1311
		$data = array();
1312
1313
		if ( $pod ) {
1314
			$rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
1315
1316
			// Block REST API saves, we handle those separately in PodsRESTHandlers
1317
			if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
1318
				return;
1319
			}
1320
		}
1321
		// The following code will run for all post_types (not just Pods)
1322
1323
		if ( false !== $nonced && ! empty( $groups ) ) {
1324
			foreach ( $groups as $group ) {
1325
				if ( empty( $group['fields'] ) ) {
1326
					continue;
1327
				}
1328
1329
				foreach ( $group['fields'] as $field ) {
1330
					if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1331
						if ( ! pods_v( 'hidden', $field['options'], false ) ) {
1332
							continue;
1333
						}
1334
					}
1335
1336
					$data[ $field['name'] ] = '';
1337
1338
					if ( isset( $_POST[ 'pods_meta_' . $field['name'] ] ) ) {
1339
						$data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ];
1340
					}
1341
				}
1342
			}
1343
1344
			if ( $is_new_item ) {
1345
				do_action( 'pods_meta_create_pre_post', $data, $pod, $id, $groups, $post, $post->post_type );
1346
				do_action( "pods_meta_create_pre_post_{$post->post_type}", $data, $pod, $id, $groups, $post );
1347
			}
1348
1349
			do_action( 'pods_meta_save_pre_post', $data, $pod, $id, $groups, $post, $post->post_type, $is_new_item );
1350
			do_action( "pods_meta_save_pre_post_{$post->post_type}", $data, $pod, $id, $groups, $post, $is_new_item );
1351
		}
1352
1353
		if ( $is_new_item || false !== $nonced ) {
1354
			pods_no_conflict_on( 'post' );
1355
1356
			if ( ! empty( $pod ) ) {
1357
				// Fix for Pods doing it's own sanitizing
1358
				$data = pods_unslash( (array) $data );
1359
1360
				$pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) );
1361
			} elseif ( ! empty( $id ) ) {
1362
				foreach ( $data as $field => $value ) {
1363
					update_post_meta( $id, $field, $value );
1364
				}
1365
			}
1366
1367
			pods_no_conflict_off( 'post' );
1368
		}
1369
1370
		if ( false !== $nonced && ! empty( $groups ) ) {
1371
			if ( $is_new_item ) {
1372
				do_action( 'pods_meta_create_post', $data, $pod, $id, $groups, $post, $post->post_type );
1373
				do_action( "pods_meta_create_post_{$post->post_type}", $data, $pod, $id, $groups, $post );
1374
			}
1375
1376
			do_action( 'pods_meta_save_post', $data, $pod, $id, $groups, $post, $post->post_type, $is_new_item );
1377
			do_action( "pods_meta_save_post_{$post->post_type}", $data, $pod, $id, $groups, $post, $is_new_item );
1378
		}
1379
1380
	}
1381
1382
	/**
1383
	 * Track changed fields before save for posts.
1384
	 *
1385
	 * @param array $data
1386
	 * @param array $postarr
1387
	 *
1388
	 * @return array
1389
	 */
1390
	public function save_post_track_changed_fields( $data, $postarr ) {
1391
1392
		$no_conflict = pods_no_conflict_check( 'post' );
1393
1394
		if ( ! $no_conflict && ! empty( $data['post_type'] ) && ! empty( $postarr['ID'] ) ) {
1395
			$pod = $data['post_type'];
1396
			$id  = $postarr['ID'];
1397
1398
			PodsAPI::handle_changed_fields( $pod, $id, 'reset' );
1399
		}
1400
1401
		return $data;
1402
1403
	}
1404
1405
	/**
1406
	 * @param $form_fields
1407
	 * @param $post
1408
	 *
1409
	 * @return array
1410
	 */
1411
	public function meta_media( $form_fields, $post ) {
1412
1413
		$groups = $this->groups_get( 'media', 'media' );
1414
1415
		if ( empty( $groups ) || 'attachment' == pods_var( 'typenow', 'global' ) ) {
1416
			return $form_fields;
1417
		}
1418
1419
		wp_enqueue_style( 'pods-form' );
1420
		wp_enqueue_script( 'pods' );
1421
1422
		$id = null;
1423
1424
		if ( is_object( $post ) ) {
1425
			$id = $post->ID;
1426
		}
1427
1428
		$pod = null;
1429
1430
		$meta_nonce = PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_media' ), 'hidden' );
1431
1432
		foreach ( $groups as $group ) {
1433
			if ( empty( $group['fields'] ) ) {
1434
				continue;
1435
			}
1436
1437
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1438
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1439
					self::$current_pod = pods( $group['pod']['name'], $id, true );
1440
				} elseif ( self::$current_pod->id() != $id ) {
1441
					self::$current_pod->fetch( $id );
1442
				}
1443
1444
				$pod = self::$current_pod;
1445
			}
1446
1447
			foreach ( $group['fields'] as $field ) {
1448
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1449
					if ( ! pods_var( 'hidden', $field['options'], false ) ) {
1450
						continue;
1451
					}
1452
				}
1453
1454
				$value = '';
1455
1456
				if ( ! empty( $pod ) ) {
1457
					$value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
1458
				} elseif ( ! empty( $id ) ) {
1459
					pods_no_conflict_on( 'post' );
1460
1461
					$value = get_post_meta( $id, $field['name'], true );
1462
1463
					pods_no_conflict_off( 'post' );
1464
				}
1465
1466
				// Manually force DFV initialization.  This is needed for attachments in "grid mode" in the
1467
				// media library.  Note that this should only occur for attachment_fields_to_edit (see #4785)
1468
				$dfv_init_script = "<script>PodsDFV.init();</script>";
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal <script>PodsDFV.init();</script> does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
1469
1470
				$form_fields[ 'pods_meta_' . $field['name'] ] = array(
1471
					'label' => $field['label'],
1472
					'input' => 'html',
1473
					'html'  => PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ) . $meta_nonce . $dfv_init_script,
1474
					'helps' => PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field )
1475
				);
1476
			}
1477
		}
1478
1479
		$form_fields = apply_filters( 'pods_meta_' . __FUNCTION__, $form_fields );
1480
1481
		return $form_fields;
1482
	}
1483
1484
	/**
1485
	 * @param $post
1486
	 * @param $attachment
1487
	 *
1488
	 * @return mixed
1489
	 */
1490
	public function save_media( $post, $attachment ) {
1491
1492
		$groups = $this->groups_get( 'media', 'media' );
1493
1494
		if ( empty( $groups ) ) {
1495
			return $post;
1496
		}
1497
1498
		$post_id = $attachment;
1499
1500
		if ( empty( $_POST ) || ! wp_verify_nonce( pods_v( 'pods_meta', 'post' ), 'pods_meta_media' ) ) {
1501
			return $post;
1502
		}
1503
1504
		if ( is_array( $post ) && ! empty( $post ) && isset( $post['ID'] ) && 'attachment' == $post['post_type'] ) {
1505
			$post_id = $post['ID'];
1506
		}
1507
1508
		if ( is_array( $post_id ) || empty( $post_id ) ) {
1509
			return $post;
1510
		}
1511
1512
		$data = array();
1513
1514
		$id  = $post_id;
1515
		$pod = null;
1516
1517
		foreach ( $groups as $group ) {
1518
			if ( empty( $group['fields'] ) ) {
1519
				continue;
1520
			}
1521
1522
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1523
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1524
					self::$current_pod = pods( $group['pod']['name'], $id, true );
1525
				} elseif ( self::$current_pod->id() != $id ) {
1526
					self::$current_pod->fetch( $id );
1527
				}
1528
1529
				$pod = self::$current_pod;
1530
			}
1531
1532
			foreach ( $group['fields'] as $field ) {
1533
1534
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1535
					if ( ! pods_var( 'hidden', $field['options'], false ) ) {
1536
						continue;
1537
					}
1538
				}
1539
1540
				$data[ $field['name'] ] = '';
1541
1542
				if ( isset( $_POST[ 'pods_meta_' . $field['name'] ] ) ) {
1543
					$data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ];
1544
				}
1545
			}
1546
		}
1547
1548
		if ( $pod ) {
1549
			$rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
1550
1551
			// Block REST API saves, we handle those separately in PodsRESTHandlers
1552
			if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
1553
				return $post;
1554
			}
1555
		}
1556
1557
		do_action( 'pods_meta_save_pre_media', $data, $pod, $id, $groups, $post, $attachment );
1558
1559
		if ( ! empty( $pod ) ) {
1560
			// Fix for Pods doing it's own sanitization
1561
			$data = pods_unslash( (array) $data );
1562
1563
			$pod->save( $data, null, null, array( 'podsmeta' => true ) );
1564
		} elseif ( ! empty( $id ) ) {
1565
			pods_no_conflict_on( 'post' );
1566
1567
			foreach ( $data as $field => $value ) {
1568
				update_post_meta( $id, $field, $value );
1569
			}
1570
1571
			pods_no_conflict_off( 'post' );
1572
		}
1573
1574
		do_action( 'pods_meta_save_media', $data, $pod, $id, $groups, $post, $attachment );
1575
1576
		return $post;
1577
	}
1578
1579
	/**
1580
	 *
1581
	 */
1582
	public function save_media_ajax() {
1583
1584
		if ( ! isset( $_POST['id'] ) || empty( $_POST['id'] ) || absint( $_POST['id'] ) < 1 ) {
1585
			return;
1586
		}
1587
1588
		$id = absint( $_POST['id'] );
1589
1590
		if ( ! isset( $_POST['nonce'] ) || empty( $_POST['nonce'] ) ) {
1591
			return;
1592
		}
1593
1594
		check_ajax_referer( 'update-post_' . $id, 'nonce' );
1595
1596
		if ( ! current_user_can( 'edit_post', $id ) ) {
1597
			return;
1598
		}
1599
1600
		$post = get_post( $id, ARRAY_A );
1601
1602
		if ( 'attachment' != $post['post_type'] ) {
1603
			return;
1604
		}
1605
1606
		// fix ALL THE THINGS
1607
1608
		if ( ! isset( $_REQUEST['attachments'] ) ) {
1609
			$_REQUEST['attachments'] = array();
1610
		}
1611
1612
		if ( ! isset( $_REQUEST['attachments'][ $id ] ) ) {
1613
			$_REQUEST['attachments'][ $id ] = array();
1614
		}
1615
1616
		if ( empty( $_REQUEST['attachments'][ $id ] ) ) {
1617
			$_REQUEST['attachments'][ $id ]['_fix_wp'] = 1;
1618
		}
1619
	}
1620
1621
	/**
1622
	 * @param      $tag
1623
	 * @param null $taxonomy
1624
	 */
1625
	public function meta_taxonomy( $tag, $taxonomy = null ) {
1626
1627
		wp_enqueue_style( 'pods-form' );
1628
		wp_enqueue_script( 'pods' );
1629
1630
		do_action( 'pods_meta_' . __FUNCTION__, $tag, $taxonomy );
1631
1632
		$taxonomy_name = $taxonomy;
1633
1634
		if ( ! is_object( $tag ) ) {
1635
			$taxonomy_name = $tag;
1636
		}
1637
1638
		$groups = $this->groups_get( 'taxonomy', $taxonomy_name );
1639
1640
		$id = null;
1641
1642
		if ( is_object( $tag ) ) {
1643
			$id = $tag->term_id;
1644
		}
1645
1646
		$pod = null;
1647
1648
		echo PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_taxonomy' ), 'hidden' );
1649
1650
		foreach ( $groups as $group ) {
1651
			if ( empty( $group['fields'] ) ) {
1652
				continue;
1653
			}
1654
1655
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1656
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1657
					self::$current_pod = pods( $group['pod']['name'], $id, true );
1658
				} elseif ( self::$current_pod->id() != $id ) {
1659
					self::$current_pod->fetch( $id );
1660
				}
1661
1662
				$pod = self::$current_pod;
1663
			}
1664
1665
			foreach ( $group['fields'] as $field ) {
1666
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1667
					if ( pods_var( 'hidden', $field['options'], false ) ) {
1668
						$field['type'] = 'hidden';
1669
					} else {
1670
						continue;
1671
					}
1672
				} elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
1673
					$field['type'] = 'hidden';
1674
				}
1675
1676
				$value = '';
1677
1678
				if ( ! empty( $pod ) ) {
1679
					$value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
1680
				}
1681
1682
				if ( ! is_object( $tag ) ) {
1683
					?>
1684
					<div class="form-field pods-field" style="<?php echo esc_attr( 'hidden' == $field['type'] ? 'display:none;' : '' ); ?>">
1685
						<?php
1686
						echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field );
1687
						echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id );
1688
						echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field );
1689
						?>
1690
					</div>
1691
					<?php
1692
				} else {
1693
					?>
1694
					<tr class="form-field pods-field <?php echo esc_attr( 'pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ) ); ?>" style="<?php echo esc_attr( 'hidden' == $field['type'] ? 'display:none;' : '' ); ?>">
1695
						<th scope="row" valign="top"><?php echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field ); ?></th>
1696
						<td>
1697
							<?php
1698
							echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id );
1699
							echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field );
1700
							?>
1701
						</td>
1702
					</tr>
1703
					<?php
1704
				}
1705
			}
1706
		}
1707
1708
		do_action( 'pods_meta_' . __FUNCTION__ . '_post', $tag, $taxonomy );
1709
	}
1710
1711
	/**
1712
	 * @param $term_id
1713
	 * @param $term_taxonomy_id
1714
	 * @param $taxonomy
1715
	 */
1716
	public function save_taxonomy( $term_id, $term_taxonomy_id, $taxonomy ) {
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1717
1718
		$is_new_item = false;
1719
1720
		if ( 'create_term' == current_filter() ) {
1721
			$is_new_item = true;
1722
		}
1723
1724
		if ( empty( $_POST ) || ! wp_verify_nonce( pods_v( 'pods_meta', 'post' ), 'pods_meta_taxonomy' ) ) {
1725
			return $term_id;
1726
		}
1727
1728
		// Block Quick Edits / Bulk Edits
1729
		if ( 'inline-save-tax' == pods_var( 'action', 'post' ) || null != pods_var( 'delete_tags', 'post' ) ) {
1730
			return $term_id;
1731
		}
1732
1733
		$groups = $this->groups_get( 'taxonomy', $taxonomy );
1734
1735
		if ( empty( $groups ) ) {
1736
			return $term_id;
1737
		}
1738
1739
		$term = null;
1740
1741
		$id  = $term_id;
1742
		$pod = null;
1743
1744
		$has_fields = false;
1745
1746
		foreach ( $groups as $group ) {
1747
			if ( empty( $group['fields'] ) ) {
1748
				continue;
1749
			}
1750
1751
			if ( null === $term ) {
1752
				$term = get_term( $term_id, $taxonomy );
1753
1754
				$data = array(
1755
					'name' => $term->name
1756
				);
1757
			}
1758
1759
			$has_fields = true;
1760
1761
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1762
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1763
					self::$current_pod = pods( $group['pod']['name'], $id, true );
1764
				} elseif ( self::$current_pod->id() != $id ) {
1765
					self::$current_pod->fetch( $id );
1766
				}
1767
1768
				$pod = self::$current_pod;
1769
			}
1770
1771
			foreach ( $group['fields'] as $field ) {
1772
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1773
					if ( ! pods_var( 'hidden', $field['options'], false ) ) {
1774
						continue;
1775
					}
1776
				}
1777
1778
				$data[ $field['name'] ] = '';
0 ignored issues
show
The variable $data 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...
1779
1780
				if ( isset( $_POST[ 'pods_meta_' . $field['name'] ] ) ) {
1781
					$data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ];
1782
				}
1783
			}
1784
		}
1785
1786
		if ( $pod ) {
1787
			$rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
1788
1789
			// Block REST API saves, we handle those separately in PodsRESTHandlers
1790
			if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
1791
				return $term_id;
1792
			}
1793
		}
1794
1795
		if ( ! $has_fields ) {
1796
			return $term_id;
1797
		}
1798
1799
		if ( $is_new_item ) {
1800
			do_action( 'pods_meta_create_pre_taxonomy', $data, $pod, $id, $groups, $term_id, $term_taxonomy_id, $taxonomy );
1801
			do_action( "pods_meta_create_pre_taxonomy_{$taxonomy}", $data, $pod, $id, $groups, $term_id, $term_taxonomy_id, $taxonomy );
1802
		}
1803
1804
		do_action( 'pods_meta_save_pre_taxonomy', $data, $pod, $id, $groups, $term_id, $term_taxonomy_id, $taxonomy, $is_new_item );
1805
		do_action( "pods_meta_save_pre_taxonomy_{$taxonomy}", $data, $pod, $id, $groups, $term_id, $term_taxonomy_id, $taxonomy, $is_new_item );
1806
1807
		pods_no_conflict_on( 'taxonomy' );
1808
1809
		if ( ! empty( $pod ) ) {
1810
			// Fix for Pods doing it's own sanitization
1811
			$data = pods_unslash( (array) $data );
1812
1813
			$pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) );
1814
		}
1815
1816
		pods_no_conflict_off( 'taxonomy' );
1817
1818
		if ( $is_new_item ) {
1819
			do_action( 'pods_meta_create_taxonomy', $data, $pod, $id, $groups, $term_id, $term_taxonomy_id, $taxonomy );
1820
			do_action( "pods_meta_create_taxonomy_{$taxonomy}", $data, $pod, $id, $groups, $term_id, $term_taxonomy_id, $taxonomy );
1821
		}
1822
1823
		do_action( 'pods_meta_save_taxonomy', $data, $pod, $id, $groups, $term_id, $term_taxonomy_id, $taxonomy, $is_new_item );
1824
		do_action( "pods_meta_save_taxonomy_{$taxonomy}", $data, $pod, $id, $groups, $term_id, $term_taxonomy_id, $taxonomy, $is_new_item );
1825
1826
		return $term_id;
1827
	}
1828
1829
	/**
1830
	 * Track changed fields before save for terms.
1831
	 *
1832
	 * @param int    $term_id
1833
	 * @param string $taxonomy
1834
	 */
1835
	public function save_taxonomy_track_changed_fields( $term_id, $taxonomy ) {
1836
1837
		$no_conflict = pods_no_conflict_check( 'term' );
1838
1839
		if ( ! $no_conflict ) {
1840
			$pod = $taxonomy;
1841
			$id  = $term_id;
1842
1843
			PodsAPI::handle_changed_fields( $pod, $id, 'reset' );
1844
		}
1845
1846
	}
1847
1848
	/**
1849
	 * @param $user_id
1850
	 */
1851
	public function meta_user( $user_id ) {
1852
1853
		wp_enqueue_style( 'pods-form' );
1854
		wp_enqueue_script( 'pods' );
1855
1856
		do_action( 'pods_meta_' . __FUNCTION__, $user_id );
1857
1858
		$groups = $this->groups_get( 'user', 'user' );
1859
1860
		if ( is_object( $user_id ) ) {
1861
			$user_id = $user_id->ID;
1862
		}
1863
1864
		$id  = $user_id;
1865
		$pod = null;
1866
1867
		foreach ( $groups as $group ) {
1868
			if ( empty( $group['fields'] ) ) {
1869
				continue;
1870
			}
1871
1872
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1873
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1874
					self::$current_pod = pods( $group['pod']['name'], $id, true );
1875
				} elseif ( self::$current_pod->id() != $id ) {
1876
					self::$current_pod->fetch( $id );
1877
				}
1878
1879
				$pod = self::$current_pod;
1880
			}
1881
1882
			$hidden_fields = array();
1883
			?>
1884
			<h3><?php echo $group['label']; ?></h3>
1885
1886
			<?php echo PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_user' ), 'hidden' ); ?>
1887
1888
			<table class="form-table pods-meta">
1889
				<tbody>
1890
				<?php
1891
				foreach ( $group['fields'] as $field ) {
1892
1893
					if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1894
						if ( pods_var( 'hidden', $field['options'], false ) ) {
1895
							$field['type'] = 'hidden';
1896
						} else {
1897
							continue;
1898
						}
1899
					} elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
1900
						$field['type'] = 'hidden';
1901
					}
1902
1903
					$value = '';
1904
1905
					if ( ! empty( $pod ) ) {
1906
						$value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
1907
					} elseif ( ! empty( $id ) ) {
1908
						pods_no_conflict_on( 'user' );
1909
1910
						$value = get_user_meta( $id, $field['name'], true );
0 ignored issues
show
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1911
1912
						pods_no_conflict_off( 'user' );
1913
					}
1914
1915
					if ( 'hidden' == $field['type'] ) {
1916
						$hidden_fields[] = array(
1917
							'field' => $field,
1918
							'value' => $value
1919
						);
1920
					} else {
1921
						?>
1922
						<tr class="form-field pods-field <?php echo esc_attr( 'pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ) ); ?>">
1923
							<th scope="row" valign="top"><?php echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field ); ?></th>
1924
							<td>
1925
								<?php echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ); ?>
1926
								<?php echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field ); ?>
1927
							</td>
1928
						</tr>
1929
						<?php
1930
					}
1931
				}
1932
				?>
1933
				</tbody>
1934
			</table>
1935
			<?php
1936
			foreach ( $hidden_fields as $hidden_field ) {
1937
				$field_data = $hidden_field['field'];
1938
1939
				echo PodsForm::field( 'pods_meta_' . $field_data['name'], $hidden_field['value'], 'hidden', $field_data );
1940
			}
1941
		}
1942
1943
		do_action( 'pods_meta_' . __FUNCTION__ . '_post', $user_id );
1944
	}
1945
1946
	/**
1947
	 * Handle integration with the user_register and profile_update hooks.
1948
	 *
1949
	 * @see wp_insert_user
1950
	 *
1951
	 * @param int         $user_id       User ID.
1952
	 * @param object|null $old_user_data Object containing user's data prior to update.
1953
	 */
1954
	public function save_user( $user_id, $old_user_data = null ) {
1955
1956
		$is_new_item = false;
1957
1958
		if ( 'user_register' == current_filter() ) {
1959
			$is_new_item = true;
1960
		}
1961
1962
		$nonced = wp_verify_nonce( pods_v( 'pods_meta', 'post' ), 'pods_meta_user' );
1963
1964
		if ( ! $is_new_item && false === $nonced ) {
1965
			return;
1966
		}
1967
1968
		if ( is_object( $user_id ) ) {
1969
			$user_id = $user_id->ID;
1970
		}
1971
1972
		$groups = $this->groups_get( 'user', 'user' );
1973
1974
		$id = $user_id;
1975
1976
		if ( ! is_object( self::$current_pod ) || self::$current_pod->pod !== 'user' ) {
0 ignored issues
show
Found "!== '". Use Yoda Condition checks, you must
Loading history...
1977
			self::$current_pod = pods( 'user', $id, true );
1978
		} elseif ( is_object( self::$current_pod ) && (int) self::$current_pod->id() !== (int) $id ) {
1979
			self::$current_pod->fetch( $id );
1980
		}
1981
1982
		$pod  = self::$current_pod;
1983
		$data = array();
1984
1985
		if ( $pod ) {
1986
			$rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
1987
1988
			// Block REST API saves, we handle those separately in PodsRESTHandlers
1989
			if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
1990
				return;
1991
			}
1992
		}
1993
1994
		if ( false !== $nonced && ! empty( $groups ) ) {
1995
			foreach ( $groups as $group ) {
1996
				if ( empty( $group['fields'] ) ) {
1997
					continue;
1998
				}
1999
2000
				foreach ( $group['fields'] as $field ) {
2001
					if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2002
						if ( ! pods_v( 'hidden', $field['options'], false ) ) {
2003
							continue;
2004
						}
2005
					}
2006
2007
					$data[ $field['name'] ] = '';
2008
2009
					if ( isset( $_POST[ 'pods_meta_' . $field['name'] ] ) ) {
2010
						$data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ];
2011
					}
2012
				}
2013
			}
2014
2015
			if ( $is_new_item ) {
2016
				do_action( 'pods_meta_create_pre_user', $data, $pod, $id, $groups );
2017
			}
2018
2019
			do_action( 'pods_meta_save_pre_user', $data, $pod, $id, $groups, $is_new_item );
2020
		}
2021
2022
		if ( $is_new_item || false !== $nonced ) {
2023
			pods_no_conflict_on( 'user' );
2024
2025
			if ( ! empty( $pod ) ) {
2026
				// Fix for Pods doing it's own sanitizing
2027
				$data = pods_unslash( (array) $data );
2028
2029
				$pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) );
2030
			} elseif ( ! empty( $id ) ) {
2031
				foreach ( $data as $field => $value ) {
2032
					update_user_meta( $id, $field, $value );
0 ignored issues
show
update_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
2033
				}
2034
			}
2035
2036
			pods_no_conflict_off( 'user' );
2037
		}
2038
2039
		if ( false !== $nonced && ! empty( $groups ) ) {
2040
			if ( $is_new_item ) {
2041
				do_action( 'pods_meta_create_user', $data, $pod, $id, $groups );
2042
			}
2043
2044
			do_action( 'pods_meta_save_user', $data, $pod, $id, $groups, $is_new_item );
2045
		}
2046
2047
	}
2048
2049
	/**
2050
	 * Track changed fields before save for users.
2051
	 *
2052
	 * @param string $user_login
2053
	 *
2054
	 * @return string
2055
	 */
2056
	public function save_user_track_changed_fields( $user_login ) {
2057
2058
		$no_conflict = pods_no_conflict_check( 'user' );
2059
2060
		if ( ! $no_conflict ) {
2061
			$user = get_user_by( 'login', $user_login );
2062
2063
			if ( $user && ! is_wp_error( $user ) ) {
2064
				$pod = 'user';
2065
				$id  = $user->ID;
2066
2067
				PodsAPI::handle_changed_fields( $pod, $id, 'reset' );
2068
			}
2069
		}
2070
2071
		return $user_login;
2072
2073
	}
2074
2075
	/**
2076
	 * @param $commenter
2077
	 * @param $user_identity
2078
	 */
2079
	public function meta_comment_new_logged_in( $commenter, $user_identity ) {
2080
2081
		wp_enqueue_style( 'pods-form' );
2082
		wp_enqueue_script( 'pods' );
2083
2084
		do_action( 'pods_meta_' . __FUNCTION__, $commenter, $user_identity );
2085
2086
		$groups = $this->groups_get( 'comment', 'comment' );
2087
2088
		$id  = null;
2089
		$pod = null;
2090
2091
		echo PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_comment' ), 'hidden' );
2092
2093
		foreach ( $groups as $group ) {
2094
			if ( empty( $group['fields'] ) ) {
2095
				continue;
2096
			}
2097
2098
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
2099
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
2100
					self::$current_pod = pods( $group['pod']['name'], $id, true );
2101
				} elseif ( self::$current_pod->id() != $id ) {
2102
					self::$current_pod->fetch( $id );
2103
				}
2104
2105
				$pod = self::$current_pod;
2106
			}
2107
2108
			foreach ( $group['fields'] as $field ) {
2109
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2110
					if ( pods_var( 'hidden', $field['options'], false ) ) {
2111
						$field['type'] = 'hidden';
2112
					} else {
2113
						continue;
2114
					}
2115
				} elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
2116
					$field['type'] = 'hidden';
2117
				}
2118
2119
				$value = '';
2120
2121
				if ( ! empty( $pod ) ) {
2122
					$value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
2123
				} elseif ( ! empty( $id ) ) {
2124
					pods_no_conflict_on( 'comment' );
2125
2126
					$value = get_comment_meta( $id, $field['name'], true );
2127
2128
					pods_no_conflict_off( 'comment' );
2129
				}
2130
				?>
2131
				<p class="comment-form-author comment-form-pods-meta-<?php echo esc_attr( $field['name'] ); ?>  pods-field" style="<?php echo esc_attr( 'hidden' == $field['type'] ? 'display:none;' : '' ); ?>">
2132
					<?php
2133
					echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field );
2134
					echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id );
2135
					echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field );
2136
					?>
2137
				</p>
2138
				<?php
2139
			}
2140
		}
2141
2142
		do_action( 'pods_meta_' . __FUNCTION__ . '_post', $commenter, $user_identity );
2143
	}
2144
2145
	/**
2146
	 * @param $form_fields
2147
	 *
2148
	 * @return array
2149
	 */
2150
	public function meta_comment_new( $form_fields ) {
2151
2152
		wp_enqueue_style( 'pods-form' );
2153
		wp_enqueue_script( 'pods' );
2154
2155
		$groups = $this->groups_get( 'comment', 'comment' );
2156
2157
		$id  = null;
2158
		$pod = null;
2159
2160
		$form_fields['pods_meta'] = PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_comment' ), 'hidden' );
2161
2162
		foreach ( $groups as $group ) {
2163
			if ( empty( $group['fields'] ) ) {
2164
				continue;
2165
			}
2166
2167
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
2168
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
2169
					self::$current_pod = pods( $group['pod']['name'], $id, true );
2170
				} elseif ( self::$current_pod->id() != $id ) {
2171
					self::$current_pod->fetch( $id );
2172
				}
2173
2174
				$pod = self::$current_pod;
2175
			}
2176
2177
			foreach ( $group['fields'] as $field ) {
2178
2179
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2180
					if ( pods_var( 'hidden', $field['options'], false ) ) {
2181
						$field['type'] = 'hidden';
2182
					} else {
2183
						continue;
2184
					}
2185
				} elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
2186
					$field['type'] = 'hidden';
2187
				}
2188
2189
				$value = '';
2190
2191
				if ( ! empty( $pod ) ) {
2192
					$value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
2193
				} elseif ( ! empty( $id ) ) {
2194
					pods_no_conflict_on( 'comment' );
2195
2196
					$value = get_comment_meta( $id, $field['name'], true );
2197
2198
					pods_no_conflict_off( 'comment' );
2199
				}
2200
2201
				ob_start();
2202
				?>
2203
				<p class="comment-form-author comment-form-pods-meta-<?php echo esc_attr( $field['name'] ); ?> pods-field" style="<?php echo esc_attr( 'hidden' == $field['type'] ? 'display:none;' : '' ); ?>">
2204
					<?php
2205
					echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field );
2206
					echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id );
2207
					echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field );
2208
					?>
2209
				</p>
2210
				<?php
2211
				$form_fields[ 'pods_meta_' . $field['name'] ] = ob_get_clean();
2212
			}
2213
		}
2214
2215
		$form_fields = apply_filters( 'pods_meta_' . __FUNCTION__, $form_fields );
2216
2217
		return $form_fields;
2218
	}
2219
2220
	/**
2221
	 * @param      $comment_type
2222
	 * @param null $comment
2223
	 */
2224
	public function meta_comment_add( $comment_type, $comment = null ) {
2225
2226
		if ( is_object( $comment ) && isset( $comment_type->comment_type ) ) {
2227
			$comment_type = $comment->comment_type;
2228
		}
2229
2230
		if ( is_object( $comment_type ) && isset( $comment_type->comment_type ) ) {
2231
			$comment      = $comment_type;
2232
			$comment_type = $comment_type->comment_type;
2233
		}
2234
2235
		if ( is_object( $comment_type ) ) {
2236
			return;
2237
		} elseif ( empty( $comment_type ) ) {
2238
			$comment_type = 'comment';
2239
		}
2240
2241
		$groups = $this->groups_get( 'comment', $comment_type );
2242
2243
		foreach ( $groups as $group ) {
2244
			if ( empty( $group['fields'] ) ) {
2245
				continue;
2246
			}
2247
2248
			$field_found = false;
2249
2250
			foreach ( $group['fields'] as $field ) {
2251
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], null, null ) ) {
2252
					if ( pods_var( 'hidden', $field['options'], false ) ) {
2253
						$field_found = true;
2254
						break;
2255
					} else {
2256
						continue;
2257
					}
2258
				} else {
2259
					$field_found = true;
2260
					break;
2261
				}
2262
			}
2263
2264
			if ( $field_found ) {
2265
				add_meta_box( 'pods-meta-' . sanitize_title( $group['label'] ), $group['label'], array(
2266
						$this,
2267
						'meta_comment'
2268
					), $comment_type, $group['context'], $group['priority'], array( 'group' => $group ) );
0 ignored issues
show
This line of the multi-line function call does not seem to be indented correctly. Expected 16 spaces, but found 20.
Loading history...
2269
			}
2270
		}
2271
	}
2272
2273
	/**
2274
	 * @param $comment
2275
	 * @param $metabox
2276
	 */
2277
	public function meta_comment( $comment, $metabox ) {
2278
2279
		wp_enqueue_style( 'pods-form' );
2280
		wp_enqueue_script( 'pods' );
2281
2282
		do_action( 'pods_meta_' . __FUNCTION__, $comment, $metabox );
2283
2284
		$hidden_fields = array();
2285
2286
		echo PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_comment' ), 'hidden' );
2287
		?>
2288
		<table class="form-table editcomment pods-metabox">
2289
			<?php
2290
			$id = null;
2291
2292
			if ( is_object( $comment ) ) {
2293
				$id = $comment->comment_ID;
2294
			}
2295
2296
			if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $metabox['args']['group']['pod']['name'] ) {
2297
				self::$current_pod = pods( $metabox['args']['group']['pod']['name'], $id, true );
2298
			} elseif ( self::$current_pod->id() != $id ) {
2299
				self::$current_pod->fetch( $id );
2300
			}
2301
2302
			$pod = self::$current_pod;
2303
2304
			foreach ( $metabox['args']['group']['fields'] as $field ) {
2305
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $metabox['args']['group']['fields'], $pod, $id ) ) {
2306
					if ( pods_var( 'hidden', $field['options'], false ) ) {
2307
						$field['type'] = 'hidden';
2308
					} else {
2309
						continue;
2310
					}
2311
				} elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
2312
					$field['type'] = 'hidden';
2313
				}
2314
2315
				$value = '';
2316
2317
				if ( ! empty( $pod ) ) {
2318
					$value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
2319
				}
2320
2321
				if ( 'hidden' == $field['type'] ) {
2322
					$hidden_fields[] = array(
2323
						'field' => $field,
2324
						'value' => $value
2325
					);
2326
				} else {
2327
					?>
2328
					<tr class="form-field pods-field <?php echo esc_attr( 'pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ) ); ?>">
2329
						<th scope="row" valign="top"><?php echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field ); ?></th>
2330
						<td>
2331
							<?php echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ); ?>
2332
							<?php echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field ); ?>
2333
						</td>
2334
					</tr>
2335
					<?php
2336
				}
2337
			}
2338
			?>
2339
		</table>
2340
		<?php
2341
		foreach ( $hidden_fields as $hidden_field ) {
2342
			$field_data = $hidden_field['field'];
2343
2344
			echo PodsForm::field( 'pods_meta_' . $field_data['name'], $hidden_field['value'], 'hidden', $field_data );
2345
		}
2346
2347
		do_action( 'pods_meta_' . __FUNCTION__ . '_post', $comment, $metabox );
2348
	}
2349
2350
	/**
2351
	 * @param $approved
2352
	 * @param $commentdata
2353
	 */
2354
	public function validate_comment( $approved, $commentdata ) {
2355
2356
		$groups = $this->groups_get( 'comment', 'comment' );
2357
2358
		if ( empty( $groups ) ) {
2359
			return $approved;
2360
		}
2361
2362
		$data = array();
2363
2364
		$pod = null;
2365
		$id  = null;
2366
2367
		foreach ( $groups as $group ) {
2368
			if ( empty( $group['fields'] ) ) {
2369
				continue;
2370
			}
2371
2372
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
2373
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
2374
					self::$current_pod = pods( $group['pod']['name'], $id, true );
2375
				} elseif ( self::$current_pod->id() != $id ) {
2376
					self::$current_pod->fetch( $id );
2377
				}
2378
2379
				$pod = self::$current_pod;
2380
			}
2381
2382
			foreach ( $group['fields'] as $field ) {
2383
2384
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2385
					if ( ! pods_var( 'hidden', $field['options'], false ) ) {
2386
						continue;
2387
					}
2388
				}
2389
2390
				$data[ $field['name'] ] = '';
2391
2392
				if ( isset( $_POST[ 'pods_meta_' . $field['name'] ] ) ) {
2393
					$data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ];
2394
				}
2395
2396
				$validate = pods_api()->handle_field_validation( $data[ $field['name'] ], $field['name'], pods_api()->get_wp_object_fields( 'comment' ), $pod->fields(), $pod, array() );
2397
2398
				if ( false === $validate ) {
2399
					$validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field['label'] );
2400
				}
2401
2402
				if ( ! is_bool( $validate ) && ! empty( $validate ) ) {
2403
					return pods_error( $validate, $this );
2404
				}
2405
			}
2406
		}
2407
2408
		return $approved;
2409
	}
2410
2411
	/**
2412
	 * @param $comment_id
2413
	 */
2414
	public function save_comment( $comment_id ) {
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2415
2416
		$groups = $this->groups_get( 'comment', 'comment' );
2417
2418
		if ( empty( $groups ) ) {
2419
			return $comment_id;
2420
		} elseif ( empty( $_POST ) ) {
2421
			return $comment_id;
2422
		} elseif ( ! wp_verify_nonce( pods_v( 'pods_meta', 'post' ), 'pods_meta_comment' ) ) {
2423
			return $comment_id;
2424
		}
2425
2426
		$data = array();
2427
2428
		$id  = $comment_id;
2429
		$pod = null;
2430
2431
		foreach ( $groups as $group ) {
2432
			if ( empty( $group['fields'] ) ) {
2433
				continue;
2434
			}
2435
2436
			if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
2437
				if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
2438
					self::$current_pod = pods( $group['pod']['name'], $id, true );
2439
				} elseif ( self::$current_pod->id() != $id ) {
2440
					self::$current_pod->fetch( $id );
2441
				}
2442
2443
				$pod = self::$current_pod;
2444
			}
2445
2446
			foreach ( $group['fields'] as $field ) {
2447
				if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2448
					if ( ! pods_var( 'hidden', $field['options'], false ) ) {
2449
						continue;
2450
					}
2451
				}
2452
2453
				$data[ $field['name'] ] = '';
2454
2455
				if ( isset( $_POST[ 'pods_meta_' . $field['name'] ] ) ) {
2456
					$data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ];
2457
				}
2458
			}
2459
		}
2460
2461
		if ( $pod ) {
2462
			$rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
2463
2464
			// Block REST API saves, we handle those separately in PodsRESTHandlers
2465
			if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
2466
				return $comment_id;
2467
			}
2468
		}
2469
2470
		do_action( 'pods_meta_save_pre_comment', $data, $pod, $id, $groups );
2471
2472
		if ( ! empty( $pod ) ) {
2473
			// Fix for Pods doing it's own sanitization
2474
			$data = pods_unslash( (array) $data );
2475
2476
			$pod->save( $data, null, null, array( 'podsmeta' => true ) );
2477
		} elseif ( ! empty( $id ) ) {
2478
			pods_no_conflict_on( 'comment' );
2479
2480
			foreach ( $data as $field => $value ) {
2481
				update_comment_meta( $id, $field, $value );
2482
			}
2483
2484
			pods_no_conflict_off( 'comment' );
2485
		}
2486
2487
		do_action( 'pods_meta_save_comment', $data, $pod, $id, $groups );
2488
2489
		return $comment_id;
2490
	}
2491
2492
	/**
2493
	 * Track changed fields before save for comments.
2494
	 *
2495
	 * @param array $data       The new, processed comment data.
2496
	 * @param array $comment    The old, unslashed comment data.
2497
	 * @param array $commentarr The new, raw comment data.
2498
	 *
2499
	 * @return array
2500
	 */
2501
	public function save_comment_track_changed_fields( $data, $comment, $commentarr ) {
2502
2503
		$no_conflict = pods_no_conflict_check( 'user' );
2504
2505
		if ( ! $no_conflict && ! empty( $comment['comment_type'] ) && ! empty( $comment['comment_ID'] ) ) {
2506
			$pod = $comment['comment_type'];
2507
			$id  = $comment['comment_ID'];
2508
2509
			PodsAPI::handle_changed_fields( $pod, $id, 'reset' );
2510
		}
2511
2512
		return $data;
2513
2514
	}
2515
2516
	/**
2517
	 * All *_*_meta filter handler aliases
2518
	 *
2519
	 * @return mixed
2520
	 */
2521
	public function get_post_meta() {
2522
2523
		$args = func_get_args();
2524
2525
		array_unshift( $args, 'post_type' );
2526
2527
		$_null = apply_filters( 'pods_meta_get_post_meta', null, $args );
2528
2529
		if ( null !== $_null ) {
2530
			return $_null;
2531
		}
2532
2533
		return call_user_func_array( array( $this, 'get_meta' ), $args );
2534
	}
2535
2536
	/**
2537
	 * @return mixed
2538
	 */
2539
	public function get_user_meta() {
2540
2541
		$args = func_get_args();
2542
2543
		array_unshift( $args, 'user' );
2544
2545
		$_null = apply_filters( 'pods_meta_get_user_meta', null, $args );
2546
2547
		if ( null !== $_null ) {
2548
			return $_null;
2549
		}
2550
2551
		return call_user_func_array( array( $this, 'get_meta' ), $args );
2552
	}
2553
2554
	/**
2555
	 * @return mixed
2556
	 */
2557
	public function get_comment_meta() {
2558
2559
		$args = func_get_args();
2560
2561
		array_unshift( $args, 'comment' );
2562
2563
		$_null = apply_filters( 'pods_meta_get_comment_meta', null, $args );
2564
2565
		if ( null !== $_null ) {
2566
			return $_null;
2567
		}
2568
2569
		return call_user_func_array( array( $this, 'get_meta' ), $args );
2570
	}
2571
2572
	/**
2573
	 * @return mixed
2574
	 */
2575
	public function get_term_meta() {
2576
2577
		$args = func_get_args();
2578
2579
		array_unshift( $args, 'term' );
2580
2581
		$_null = apply_filters( 'pods_meta_get_term_meta', null, $args );
2582
2583
		if ( null !== $_null ) {
2584
			return $_null;
2585
		}
2586
2587
		return call_user_func_array( array( $this, 'get_meta' ), $args );
2588
	}
2589
2590
	/**
2591
	 * All *_*_meta filter handler aliases
2592
	 *
2593
	 * @return mixed
2594
	 */
2595
	public function get_option() {
2596
2597
		$args = func_get_args();
2598
2599
		array_unshift( $args, 'settings' );
2600
2601
		$_null = apply_filters( 'pods_meta_get_option', null, $args );
2602
2603
		if ( null !== $_null ) {
2604
			return $_null;
2605
		}
2606
2607
		return call_user_func_array( array( $this, 'get_meta' ), $args );
2608
	}
2609
2610
	/**
2611
	 * @return mixed
2612
	 */
2613
	public function add_post_meta() {
2614
2615
		$args = func_get_args();
2616
2617
		array_unshift( $args, 'post_type' );
2618
2619
		$_null = apply_filters( 'pods_meta_add_post_meta', null, $args );
2620
2621
		if ( null !== $_null ) {
2622
			return $_null;
2623
		}
2624
2625
		return call_user_func_array( array( $this, 'add_meta' ), $args );
2626
	}
2627
2628
	/**
2629
	 * @return mixed
2630
	 */
2631
	public function add_user_meta() {
2632
2633
		$args = func_get_args();
2634
2635
		array_unshift( $args, 'user' );
2636
2637
		$_null = apply_filters( 'pods_meta_add_user_meta', null, $args );
2638
2639
		if ( null !== $_null ) {
2640
			return $_null;
2641
		}
2642
2643
		return call_user_func_array( array( $this, 'add_meta' ), $args );
2644
	}
2645
2646
	/**
2647
	 * @return mixed
2648
	 */
2649
	public function add_comment_meta() {
2650
2651
		$args = func_get_args();
2652
2653
		array_unshift( $args, 'comment' );
2654
2655
		$_null = apply_filters( 'pods_meta_add_comment_meta', null, $args );
2656
2657
		if ( null !== $_null ) {
2658
			return $_null;
2659
		}
2660
2661
		return call_user_func_array( array( $this, 'add_meta' ), $args );
2662
	}
2663
2664
	/**
2665
	 * @return mixed
2666
	 */
2667
	public function add_term_meta() {
2668
2669
		$args = func_get_args();
2670
2671
		array_unshift( $args, 'term' );
2672
2673
		$_null = apply_filters( 'pods_meta_add_term_meta', null, $args );
2674
2675
		if ( null !== $_null ) {
2676
			return $_null;
2677
		}
2678
2679
		return call_user_func_array( array( $this, 'add_meta' ), $args );
2680
	}
2681
2682
	/**
2683
	 * @return mixed
2684
	 */
2685
	public function add_option() {
2686
2687
		$args = func_get_args();
2688
2689
		array_unshift( $args, 'settings' );
2690
2691
		$_null = apply_filters( 'pods_meta_add_option', null, $args );
2692
2693
		if ( null !== $_null ) {
2694
			return $_null;
2695
		}
2696
2697
		return call_user_func_array( array( $this, 'add_meta' ), $args );
2698
	}
2699
2700
	/**
2701
	 * @return mixed
2702
	 */
2703
	public function update_post_meta() {
2704
2705
		$args = func_get_args();
2706
2707
		array_unshift( $args, 'post_type' );
2708
2709
		$_null = apply_filters( 'pods_meta_update_post_meta', null, $args );
2710
2711
		if ( null !== $_null ) {
2712
			return $_null;
2713
		}
2714
2715
		return call_user_func_array( array( $this, 'update_meta' ), $args );
2716
	}
2717
2718
	/**
2719
	 * @return mixed
2720
	 */
2721
	public function update_user_meta() {
2722
2723
		$args = func_get_args();
2724
2725
		array_unshift( $args, 'user' );
2726
2727
		$_null = apply_filters( 'pods_meta_update_user_meta', null, $args );
2728
2729
		if ( null !== $_null ) {
2730
			return $_null;
2731
		}
2732
2733
		return call_user_func_array( array( $this, 'update_meta' ), $args );
2734
	}
2735
2736
	/**
2737
	 * @return mixed
2738
	 */
2739
	public function update_comment_meta() {
2740
2741
		$args = func_get_args();
2742
2743
		array_unshift( $args, 'comment' );
2744
2745
		$_null = apply_filters( 'pods_meta_update_comment_meta', null, $args );
2746
2747
		if ( null !== $_null ) {
2748
			return $_null;
2749
		}
2750
2751
		return call_user_func_array( array( $this, 'update_meta' ), $args );
2752
	}
2753
2754
	/**
2755
	 * @return mixed
2756
	 */
2757
	public function update_term_meta() {
2758
2759
		$args = func_get_args();
2760
2761
		array_unshift( $args, 'term' );
2762
2763
		$_null = apply_filters( 'pods_meta_update_term_meta', null, $args );
2764
2765
		if ( null !== $_null ) {
2766
			return $_null;
2767
		}
2768
2769
		return call_user_func_array( array( $this, 'update_meta' ), $args );
2770
	}
2771
2772
	/**
2773
	 * @return mixed
2774
	 */
2775
	public function update_option() {
2776
2777
		$args = func_get_args();
2778
2779
		array_unshift( $args, 'settings' );
2780
2781
		$_null = apply_filters( 'pods_meta_update_option', null, $args );
2782
2783
		if ( null !== $_null ) {
2784
			return $_null;
2785
		}
2786
2787
		return call_user_func_array( array( $this, 'update_meta' ), $args );
2788
	}
2789
2790
	/**
2791
	 * @return mixed
2792
	 */
2793
	public function delete_post_meta() {
2794
2795
		$args = func_get_args();
2796
2797
		array_unshift( $args, 'post_type' );
2798
2799
		$_null = apply_filters( 'pods_meta_delete_post_meta', null, $args );
2800
2801
		if ( null !== $_null ) {
2802
			return $_null;
2803
		}
2804
2805
		return call_user_func_array( array( $this, 'delete_meta' ), $args );
2806
	}
2807
2808
	/**
2809
	 * @return mixed
2810
	 */
2811
	public function delete_user_meta() {
2812
2813
		$args = func_get_args();
2814
2815
		array_unshift( $args, 'user' );
2816
2817
		$_null = apply_filters( 'pods_meta_delete_user_meta', null, $args );
2818
2819
		if ( null !== $_null ) {
2820
			return $_null;
2821
		}
2822
2823
		return call_user_func_array( array( $this, 'delete_meta' ), $args );
2824
	}
2825
2826
	/**
2827
	 * @return mixed
2828
	 */
2829
	public function delete_comment_meta() {
2830
2831
		$args = func_get_args();
2832
2833
		array_unshift( $args, 'comment' );
2834
2835
		$_null = apply_filters( 'pods_meta_delete_comment_meta', null, $args );
2836
2837
		if ( null !== $_null ) {
2838
			return $_null;
2839
		}
2840
2841
		return call_user_func_array( array( $this, 'delete_meta' ), $args );
2842
	}
2843
2844
	/**
2845
	 * @return mixed
2846
	 */
2847
	public function delete_term_meta() {
2848
2849
		$args = func_get_args();
2850
2851
		array_unshift( $args, 'term' );
2852
2853
		$_null = apply_filters( 'pods_meta_delete_term_meta', null, $args );
2854
2855
		if ( null !== $_null ) {
2856
			return $_null;
2857
		}
2858
2859
		return call_user_func_array( array( $this, 'delete_meta' ), $args );
2860
	}
2861
2862
	/**
2863
	 * @return mixed
2864
	 */
2865
	public function delete_option() {
2866
2867
		$args = func_get_args();
2868
2869
		array_unshift( $args, 'settings' );
2870
2871
		$_null = apply_filters( 'pods_meta_delete_option', null, $args );
2872
2873
		if ( null !== $_null ) {
2874
			return $_null;
2875
		}
2876
2877
		return call_user_func_array( array( $this, 'delete_meta' ), $args );
2878
	}
2879
2880
	/*
2881
     * The real meta functions
2882
     */
2883
	/**
2884
	 * @param        $object_type
2885
	 * @param        $object_id
2886
	 * @param string $aux
2887
	 *
2888
	 * @return bool|mixed
2889
	 */
2890
	public function get_object( $object_type, $object_id, $aux = '' ) {
2891
2892
		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...
2893
2894
		if ( 'term' == $object_type ) {
2895
			$object_type = 'taxonomy';
2896
		}
2897
2898
		if ( 'post_type' == $object_type ) {
2899
			$objects = self::$post_types;
2900
		} elseif ( 'taxonomy' == $object_type ) {
2901
			$objects = self::$taxonomies;
2902
		} elseif ( 'media' == $object_type ) {
2903
			$objects = self::$media;
2904
		} elseif ( 'user' == $object_type ) {
2905
			$objects = self::$user;
2906
		} elseif ( 'comment' == $object_type ) {
2907
			$objects = self::$comment;
2908
		} elseif ( 'settings' == $object_type ) {
2909
			$objects = self::$settings;
2910
		} else {
2911
			return false;
2912
		}
2913
2914
		if ( empty( $objects ) || ! is_array( $objects ) ) {
2915
			return false;
2916
		}
2917
2918
		$object_name = null;
2919
2920
		if ( 'media' == $object_type ) {
2921
			return @current( $objects );
0 ignored issues
show
Silencing errors is discouraged
Loading history...
2922
		} elseif ( 'user' == $object_type ) {
2923
			return @current( $objects );
0 ignored issues
show
Silencing errors is discouraged
Loading history...
2924
		} elseif ( 'comment' == $object_type ) {
2925
			return @current( $objects );
0 ignored issues
show
Silencing errors is discouraged
Loading history...
2926
		} elseif ( 'post_type' == $object_type ) {
2927
			$object = get_post( $object_id );
2928
2929
			if ( ! is_object( $object ) || ! isset( $object->post_type ) ) {
2930
				return false;
2931
			}
2932
2933
			$object_name = $object->post_type;
2934
		} elseif ( 'taxonomy' == $object_type ) {
2935
			$object = get_term( $object_id );
2936
2937
			if ( ! is_object( $object ) || ! isset( $object->taxonomy ) ) {
2938
				return false;
2939
			}
2940
2941
			$object_name = $object->taxonomy;
2942
			if ( empty( $aux ) ) {
2943
				$object_name = $wpdb->get_var( $wpdb->prepare( "SELECT `taxonomy` FROM `{$wpdb->term_taxonomy}` WHERE `term_id` = %d", $object_id ) );
0 ignored issues
show
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
2944
			} else {
2945
				$object_name = $aux;
2946
			}
2947
		} elseif ( 'settings' == $object_type ) {
2948
			$object = $object_id;
2949
		} else {
2950
			return false;
2951
		}
2952
2953
		$reserved_post_types = array(
2954
			'revision'
2955
		);
2956
2957
		$reserved_post_types = apply_filters( 'pods_meta_reserved_post_types', $reserved_post_types, $object_type, $object_id, $object_name, $objects );
2958
2959
		if ( empty( $object_name ) || ( 'post_type' == $object_type && ( 0 === strpos( $object_name, '_pods_' ) ) || in_array( $object_name, $reserved_post_types ) ) ) {
2960
			return false;
2961
		} elseif ( 'attachment' == $object_name ) {
2962
			return @current( self::$media );
0 ignored issues
show
Silencing errors is discouraged
Loading history...
2963
		}
2964
2965
		$recheck = array();
2966
2967
		// Return first created by Pods, save extended for later
2968
		foreach ( $objects as $pod ) {
2969
			if ( $object_name == $pod['object'] ) {
2970
				$recheck[] = $pod;
2971
			}
2972
2973
			if ( '' == $pod['object'] && $object_name == $pod['name'] ) {
2974
				return $pod;
2975
			}
2976
		}
2977
2978
		// If no objects created by Pods, return first extended
2979
		foreach ( $recheck as $pod ) {
2980
			return $pod;
2981
		}
2982
2983
		return false;
2984
	}
2985
2986
	/**
2987
	 * @param        $object_type
2988
	 * @param null   $_null
2989
	 * @param int    $object_id
2990
	 * @param string $meta_key
2991
	 * @param bool   $single
2992
	 *
2993
	 * @return array|bool|int|mixed|null|string|void
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|array|string.

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...
2994
	 */
2995
	public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $single = false ) {
2996
2997
		// Enforce boolean as it can be a string sometimes
2998
		$single = filter_var( $single, FILTER_VALIDATE_BOOLEAN );
2999
3000
		$meta_type = $object_type;
3001
3002
		if ( in_array( $meta_type, array( 'post_type', 'media' ) ) ) {
3003
			$meta_type = 'post';
3004
		} elseif ( 'taxonomy' == $meta_type ) {
3005
			$meta_type = 'term';
3006
		}
3007
3008
		if ( empty( $meta_key ) ) {
3009
			if ( ! defined( 'PODS_ALLOW_FULL_META' ) || ! PODS_ALLOW_FULL_META ) {
3010
				return $_null; // don't cover get_post_meta( $id )
3011
			}
3012
3013
			$single = false;
3014
		}
3015
3016
		if ( 'user' === $object_type && 'locale' === $meta_key ) {
3017
			return $_null; // don't interfere with locale
3018
		}
3019
3020
		$object = $this->get_object( $object_type, $object_id );
3021
3022
		if ( empty( $object_id ) || empty( $object ) ) {
3023
			return $_null;
3024
		}
3025
3026
		$no_conflict = pods_no_conflict_check( $meta_type );
3027
3028
		if ( ! $no_conflict ) {
3029
			pods_no_conflict_on( $meta_type );
3030
		}
3031
3032
		$meta_cache = array();
3033
3034
		if ( ! $single && isset( $GLOBALS['wp_object_cache'] ) && is_object( $GLOBALS['wp_object_cache'] ) ) {
3035
			$meta_cache = wp_cache_get( $object_id, 'pods_' . $meta_type . '_meta' );
3036
3037
			if ( empty( $meta_cache ) ) {
3038
				$meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
3039
3040
				if ( empty( $meta_cache ) ) {
3041
					$meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
3042
					$meta_cache = $meta_cache[ $object_id ];
3043
				}
3044
			}
3045
		}
3046
3047
		if ( empty( $meta_cache ) || ! is_array( $meta_cache ) ) {
3048
			$meta_cache = array();
3049
		}
3050
3051
		if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod != $object['name'] ) {
3052
			self::$current_field_pod = pods( $object['name'], $object_id );
3053
		} elseif ( self::$current_field_pod->id() != $object_id ) {
3054
			self::$current_field_pod->fetch( $object_id );
3055
		}
3056
3057
		$pod = self::$current_field_pod;
3058
3059
		$meta_keys = array( $meta_key );
3060
3061
		if ( empty( $meta_key ) ) {
3062
			$meta_keys = array_keys( $meta_cache );
3063
		}
3064
3065
		$key_found = false;
3066
3067
		foreach ( $meta_keys as $meta_k ) {
3068
			if ( ! empty( $pod ) ) {
3069
				if ( isset( $pod->fields[ $meta_k ] ) ) {
3070
					$key_found = true;
3071
3072
					$meta_cache[ $meta_k ] = $pod->field( array(
3073
						'name'     => $meta_k,
3074
						'single'   => $single,
3075
						'get_meta' => true
3076
					) );
3077
3078
					if ( ( ! is_array( $meta_cache[ $meta_k ] ) || ! isset( $meta_cache[ $meta_k ][0] ) ) ) {
3079
						if ( empty( $meta_cache[ $meta_k ] ) && ! is_array( $meta_cache[ $meta_k ] ) && $single ) {
3080
							$meta_cache[ $meta_k ] = array();
3081
						} else {
3082
							$meta_cache[ $meta_k ] = array( $meta_cache[ $meta_k ] );
3083
						}
3084
					}
3085
3086
					if ( in_array( $pod->fields[ $meta_k ]['type'], PodsForm::tableless_field_types() ) && isset( $meta_cache[ '_pods_' . $meta_k ] ) ) {
3087
						unset( $meta_cache[ '_pods_' . $meta_k ] );
3088
					}
3089
				} elseif ( false !== strpos( $meta_k, '.' ) ) {
3090
					$key_found = true;
3091
3092
					$first = current( explode( '.', $meta_k ) );
3093
3094
					if ( isset( $pod->fields[ $first ] ) ) {
3095
						$meta_cache[ $meta_k ] = $pod->field( array(
3096
							'name'     => $meta_k,
3097
							'single'   => $single,
3098
							'get_meta' => true
3099
						) );
3100
3101
						if ( ( ! is_array( $meta_cache[ $meta_k ] ) || ! isset( $meta_cache[ $meta_k ][0] ) ) && $single ) {
3102
							if ( empty( $meta_cache[ $meta_k ] ) && ! is_array( $meta_cache[ $meta_k ] ) && $single ) {
3103
								$meta_cache[ $meta_k ] = array();
3104
							} else {
3105
								$meta_cache[ $meta_k ] = array( $meta_cache[ $meta_k ] );
3106
							}
3107
						}
3108
3109
						if ( in_array( $pod->fields[ $first ]['type'], PodsForm::tableless_field_types() ) && isset( $meta_cache[ '_pods_' . $first ] ) ) {
3110
							unset( $meta_cache[ '_pods_' . $first ] );
3111
						}
3112
					}
3113
				}
3114
			}
3115
		}
3116
3117
		if ( ! $no_conflict ) {
3118
			pods_no_conflict_off( $meta_type );
3119
		}
3120
3121
		unset( $pod ); // memory clear
3122
3123
		if ( ! $key_found ) {
3124
			return $_null;
3125
		}
3126
3127
		if ( ! $single && isset( $GLOBALS['wp_object_cache'] ) && is_object( $GLOBALS['wp_object_cache'] ) ) {
3128
			wp_cache_set( $object_id, $meta_cache, 'pods_' . $meta_type . '_meta' );
3129
		}
3130
3131
		if ( empty( $meta_key ) ) {
3132
			return $meta_cache;
3133
		} elseif ( isset( $meta_cache[ $meta_key ] ) ) {
3134
			$value = $meta_cache[ $meta_key ];
3135
		} else {
3136
			$value = '';
3137
		}
3138
3139
		if ( ! is_numeric( $value ) && empty( $value ) ) {
3140
			if ( $single ) {
3141
				$value = '';
3142
			} else {
3143
				$value = array();
3144
			}
3145
		} // get_metadata requires $meta[ 0 ] to be set for first value to be retrieved
3146
		elseif ( ! is_array( $value ) ) {
3147
			$value = array( $value );
3148
		}
3149
3150
		return $value;
3151
	}
3152
3153
	/**
3154
	 * @param        $object_type
3155
	 * @param null   $_null
3156
	 * @param int    $object_id
3157
	 * @param string $meta_key
3158
	 * @param string $meta_value
3159
	 * @param bool   $unique
3160
	 *
3161
	 * @return bool|int|null
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|integer.

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...
3162
	 */
3163
	public function add_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $unique = false ) {
3164
3165
		if ( pods_tableless() ) {
3166
			return $_null;
3167
		}
3168
3169
		$object = $this->get_object( $object_type, $object_id );
3170
3171
		if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
3172
			return $_null;
3173
		}
3174
3175
		if ( in_array( $object['fields'][ $meta_key ]['type'], PodsForm::tableless_field_types() ) ) {
3176
			if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod != $object['name'] ) {
3177
				self::$current_field_pod = pods( $object['name'], $object_id );
3178
			} elseif ( self::$current_field_pod->id() != $object_id ) {
3179
				self::$current_field_pod->fetch( $object_id );
3180
			}
3181
3182
			$pod = self::$current_field_pod;
3183
3184
			$pod->add_to( $meta_key, $meta_value );
3185
		} else {
3186
			if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod != $object['name'] ) {
3187
				self::$current_field_pod = pods( $object['name'] );
3188
			}
3189
3190
			$pod = self::$current_field_pod;
3191
3192
			$pod->save( $meta_key, $meta_value, $object_id, array(
3193
				'podsmeta_direct' => true,
3194
				'error_mode'      => 'false'
3195
			) );
3196
		}
3197
3198
		return $object_id;
3199
	}
3200
3201
	/**
3202
	 * @param        $object_type
3203
	 * @param null   $_null
3204
	 * @param int    $object_id
3205
	 * @param string $meta_key
3206
	 * @param string $meta_value
3207
	 * @param string $prev_value
3208
	 *
3209
	 * @return bool|int|null
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|integer.

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...
3210
	 */
3211
	public function update_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) {
3212
3213
		if ( pods_tableless() ) {
3214
			return $_null;
3215
		}
3216
3217
		$object = $this->get_object( $object_type, $object_id );
3218
3219
		if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
3220
			return $_null;
3221
		}
3222
3223
		if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod != $object['name'] ) {
3224
			self::$current_field_pod = pods( $object['name'] );
3225
		}
3226
3227
		$pod = self::$current_field_pod;
3228
3229
		if ( ( isset( $pod->fields[ $meta_key ] ) || false !== strpos( $meta_key, '.' ) ) && $pod->row !== null ) {
3230
3231
			$key = $meta_key;
3232
			if ( false !== strpos( $meta_key, '.' ) ) {
3233
				$key = current( explode( '.', $meta_key ) );
3234
			}
3235
3236
			$pod->row[ $meta_key ] = $meta_value;
3237
3238
			if ( isset( $pod->fields[ $key ] ) ) {
3239
				if ( in_array( $pod->fields[ $key ]['type'], PodsForm::tableless_field_types() ) && isset( $meta_cache[ '_pods_' . $key ] ) ) {
0 ignored issues
show
The variable $meta_cache seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
3240
					unset( $meta_cache[ '_pods_' . $key ] );
3241
				}
3242
			}
0 ignored issues
show
Blank line found after control structure
Loading history...
3243
3244
		}
3245
3246
		$pod->save( $meta_key, $meta_value, $object_id, array( 'podsmeta_direct' => true, 'error_mode' => 'false' ) );
3247
3248
		return $object_id;
3249
	}
3250
3251
	/**
3252
	 * @param        $object_type
3253
	 * @param null   $_null
3254
	 * @param int    $object_id
3255
	 * @param string $meta_key
3256
	 * @param string $meta_value
3257
	 * @param bool   $delete_all
3258
	 *
3259
	 * @return null
3260
	 */
3261
	public function delete_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $delete_all = false ) {
3262
3263
		if ( pods_tableless() ) {
3264
			return $_null;
3265
		}
3266
3267
		$object = $this->get_object( $object_type, $object_id );
3268
3269
		if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
3270
			return $_null;
3271
		}
3272
3273
		// @todo handle $delete_all (delete the field values from all pod items)
3274
		if ( ! empty( $meta_value ) && in_array( $object['fields'][ $meta_key ]['type'], PodsForm::tableless_field_types() ) ) {
3275
			if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod != $object['name'] ) {
3276
				self::$current_field_pod = pods( $object['name'], $object_id );
3277
			} elseif ( self::$current_field_pod->id() != $object_id ) {
3278
				self::$current_field_pod->fetch( $object_id );
3279
			}
3280
3281
			$pod = self::$current_field_pod;
3282
3283
			$pod->remove_from( $meta_key, $meta_value );
3284
		} else {
3285
			if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod != $object['name'] ) {
3286
				self::$current_field_pod = pods( $object['name'] );
3287
			}
3288
3289
			$pod = self::$current_field_pod;
3290
3291
			$pod->save( array( $meta_key => null ), null, $object_id, array(
3292
				'podsmeta_direct' => true,
3293
				'error_mode'      => 'false'
3294
			) );
3295
		}
3296
3297
		return $_null;
3298
	}
3299
3300
	/**
3301
	 * @param $id
3302
	 *
3303
	 * @return bool|void
3304
	 */
3305
	public function delete_post( $id ) {
3306
3307
		$post = get_post( $id );
3308
3309
		if ( empty( $post ) ) {
3310
			return;
3311
		}
3312
3313
		$id        = $post->ID;
3314
		$post_type = $post->post_type;
3315
3316
		return $this->delete_object( 'post_type', $id, $post_type );
3317
	}
3318
3319
	/**
3320
	 * @param $id
3321
	 */
3322
	public function delete_taxonomy( $id ) {
3323
3324
		/**
3325
		 * @var $wpdb WPDB
3326
		 */
3327
		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...
3328
3329
		$terms = $wpdb->get_results( "SELECT `term_id`, `taxonomy` FROM `{$wpdb->term_taxonomy}` WHERE `term_taxonomy_id` = {$id}" );
0 ignored issues
show
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
3330
3331
		if ( empty( $terms ) ) {
3332
			return;
3333
		}
3334
3335
		foreach ( $terms as $term ) {
3336
			$id       = $term->term_id;
3337
			$taxonomy = $term->taxonomy;
3338
3339
			$this->delete_object( 'taxonomy', $id, $taxonomy );
3340
		}
3341
	}
3342
3343
	/**
3344
	 * Hook the split_shared_term action and point it to this method
3345
	 *
3346
	 * Fires after a previously shared taxonomy term is split into two separate terms.
3347
	 *
3348
	 * @param int    $term_id          ID of the formerly shared term.
3349
	 * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
3350
	 * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
3351
	 * @param string $taxonomy         Taxonomy for the split term.
3352
	 */
3353
	public static function split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
3354
3355
		require_once( PODS_DIR . 'classes/PodsTermSplitting.php' );
3356
3357
		$term_splitting = new Pods_Term_Splitting( $term_id, $new_term_id, $taxonomy );
3358
		$term_splitting->split_shared_term();
3359
3360
	}
3361
3362
	/**
3363
	 * @param $id
3364
	 *
3365
	 * @return bool
3366
	 */
3367
	public function delete_user( $id ) {
3368
3369
		return $this->delete_object( 'user', $id );
3370
	}
3371
3372
	/**
3373
	 * @param $id
3374
	 *
3375
	 * @return bool
3376
	 */
3377
	public function delete_comment( $id ) {
3378
3379
		return $this->delete_object( 'comment', $id );
3380
	}
3381
3382
	/**
3383
	 * @param $id
3384
	 *
3385
	 * @return bool
3386
	 */
3387
	public function delete_media( $id ) {
3388
3389
		return $this->delete_object( 'media', $id );
3390
	}
3391
3392
	/**
3393
	 * @param      $type
3394
	 * @param      $id
3395
	 * @param null $name
3396
	 *
3397
	 * @return bool
3398
	 */
3399
	public function delete_object( $type, $id, $name = null ) {
3400
3401
		if ( empty( $name ) ) {
3402
			$name = $type;
3403
		}
3404
3405
		$object = $this->object_get( $type, $name );
3406
3407
		if ( ! empty( $object ) ) {
3408
			$params = array(
3409
				'pod'    => pods_var( 'name', $object ),
3410
				'pod_id' => pods_var( 'id', $object ),
3411
				'id'     => $id
3412
			);
3413
3414
			return pods_api()->delete_pod_item( $params, false );
3415
		} else {
3416
			return pods_api()->delete_object_from_relationships( $id, $type, $name );
3417
		}
3418
	}
3419
}
3420