Completed
Push — 2.x ( c590d5...d9e9cd )
by Phil
12s
created

PodsAPI   D

Complexity

Total Complexity 1821

Size/Duplication

Total Lines 8606
Duplicated Lines 14.49 %

Coupling/Cohesion

Components 3
Dependencies 9

Importance

Changes 0
Metric Value
dl 1247
loc 8606
rs 4.4102
c 0
b 0
f 0
wmc 1821
lcom 3
cbo 9

81 Methods

Rating   Name   Duplication   Size   Complexity  
B init() 0 14 5
B __construct() 0 20 5
C save_wp_object() 0 24 7
B delete_wp_object() 0 18 6
D save_post() 11 41 13
F save_post_meta() 69 69 20
D save_user() 13 48 13
D save_user_meta() 62 62 15
C save_comment() 13 41 12
D save_comment_meta() 62 62 15
F save_term_meta() 73 73 21
C save_setting() 2 24 8
B rename_wp_object_type() 0 36 6
F get_wp_object_fields() 2 507 16
D save_term() 0 56 13
F add_pod() 4 162 41
F save_pod() 54 657 168
F save_field() 78 524 158
A save_slug_fix() 0 6 3
F save_object() 20 85 15
A save_template() 0 7 1
A save_page() 0 18 3
A save_helper() 0 17 3
F save_pod_item() 126 847 243
A save_pod_items() 0 18 4
B get_changed_fields() 0 20 5
F save_relationships() 29 130 23
C duplicate_pod() 16 58 13
C duplicate_field() 6 49 8
D duplicate_pod_item() 0 106 13
B export_pod_item() 0 29 6
F export_pod_item_level() 0 101 29
C reorder_pod_item() 0 40 11
C reset_pod() 14 102 12
D delete_pod() 24 88 13
F delete_field() 0 73 17
A delete_object() 4 16 3
A delete_template() 0 5 1
A delete_page() 0 11 3
A delete_helper() 0 5 1
F delete_pod_item() 43 130 36
D delete_object_from_relationships() 0 93 15
D delete_relationships() 27 102 19
C pod_exists() 9 23 8
A get_pod_type_count() 0 22 1
F load_pod() 67 285 82
F load_pods() 32 266 100
B field_exists() 10 21 7
F load_field() 36 203 54
F load_fields() 36 151 52
C load_object() 4 50 15
F load_objects() 20 91 32
A load_template() 0 8 2
A load_templates() 0 8 2
A load_page() 4 12 4
A load_pages() 0 8 2
A load_helper() 8 8 2
A load_helpers() 8 8 2
C load_pod_item() 4 23 8
C load_sister_fields() 8 45 15
B detect_pod_field_from_sql_data_type() 0 25 2
A get_field_types() 0 3 1
A get_field_definition() 0 5 1
F handle_field_validation() 0 75 27
F lookup_related_items() 71 165 55
F lookup_related_items_from() 74 131 42
F get_table_info_load() 14 105 28
F get_table_info() 53 478 95
A export_package() 0 6 2
A replace_package() 0 3 1
A import_package() 0 6 2
A validate_package() 0 3 1
F import() 8 159 50
B export() 0 33 6
A csv_to_php() 0 7 1
B cache_flush_pods() 0 36 5
F process_form() 0 66 13
F get_current_language() 14 212 51
A do_hook() 7 7 2
A __get() 4 20 3
A __call() 4 13 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like PodsAPI often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PodsAPI, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package Pods
4
 */
5
class PodsAPI {
6
7
    /**
8
     * @var PodsAPI
9
     */
10
    static $instance = null;
0 ignored issues
show
Coding Style introduced by
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...
11
12
	/**
13
	 * @var array PodsAPI
14
	 */
15
	static $instances = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $instances.

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...
16
17
18
    /**
19
     * @var bool
20
     */
21
    public $display_errors = false;
22
23
    /**
24
     * @var array|bool|mixed|null|void
25
     */
26
    public $pod_data;
27
28
    /**
29
     * @var
30
     */
31
    public $pod;
32
33
    /**
34
     * @var
35
     */
36
    public $pod_id;
37
38
    /**
39
     * @var
40
     */
41
    public $fields;
42
43
    /**
44
     * @var
45
     * @deprecated 2.0
46
     */
47
    public $format = null;
48
49
    /**
50
     * @var
51
     */
52
    private $deprecated;
53
54
	/**
55
	 * @var array
56
	 * @since 2.5
57
	 */
58
	private $fields_cache = array();
59
60
	/**
61
	 * @var array
62
	 * @since 2.5
63
	 *
64
	 */
65
	private static $table_info_cache = array();
66
67
	/**
68
	 * @var array
69
	 * @since 2.5
70
	 *
71
	 */
72
	private static $related_item_cache = array();
73
74
	/**
75
     * Singleton-ish handling for a basic pods_api() request
76
     *
77
     * @param string $pod (optional) The pod name
78
     * @param string $format (deprecated) Format for import/export, "php" or "csv"
79
     *
80
     * @return \PodsAPI
81
     *
82
     * @since 2.3.5
83
     */
84
	public static function init ( $pod = null, $format = null ) {
85
		if ( null !== $pod || null !== $format ) {
86
			if ( ! isset( self::$instances[ $pod ] ) ) {
87
				// Cache API singleton per Pod
88
				self::$instances[ $pod ] = new PodsAPI( $pod, $format );
89
			}
90
			return self::$instances[ $pod ];
91
		}
92
		elseif ( !is_object( self::$instance ) ) {
93
			self::$instance = new PodsAPI();
94
		}
95
96
		return self::$instance;
97
	}
98
99
100
    /**
101
     * Store and retrieve data programatically
102
     *
103
     * @param string $pod (optional) The pod name
104
     * @param string $format (deprecated) Format for import/export, "php" or "csv"
105
     *
106
     * @return \PodsAPI
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...
107
     *
108
     * @license http://www.gnu.org/licenses/gpl-2.0.html
109
     * @since 1.7.1
110
     */
111
    public function __construct ( $pod = null, $format = null ) {
112
        if ( null !== $pod && 0 < strlen( (string) $pod ) ) {
113
            if ( null !== $format ) {
114
                $this->format = $format;
0 ignored issues
show
Deprecated Code introduced by
The property PodsAPI::$format has been deprecated with message: 2.0

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
115
116
                pods_deprecated( 'pods_api( $pod, $format )', '2.0', 'pods_api( $pod )' );
117
            }
118
119
            $pod = pods_clean_name( $pod );
120
121
            $pod = $this->load_pod( array( 'name' => $pod, 'table_info' => true ), false );
122
123
            if ( !empty( $pod ) ) {
124
                $this->pod_data = $pod;
125
                $this->pod = $pod[ 'name' ];
126
                $this->pod_id = $pod[ 'id' ];
127
                $this->fields = $pod[ 'fields' ];
128
            }
129
        }
130
    }
131
132
    /**
133
     * Save a WP object and its meta
134
     *
135
     * @param string $object_type Object type: post|taxonomy|user|comment|setting
136
     * @param array $data All post data to be saved
137
     * @param array $meta (optional) Associative array of meta keys and values
138
     * @param bool $strict (optional) Decides whether the previous saved meta should be deleted or not
139
     * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
140
     * @param array $fields (optional) The array of fields and their options, for further processing with
141
     *
142
     * @return bool|mixed
143
     *
144
     * @since 2.0
145
     */
146
    public function save_wp_object ( $object_type, $data, $meta = array(), $strict = false, $sanitized = false, $fields = array() ) {
147
        if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
148
            $object_type = 'post';
149
150
        if ( 'taxonomy' == $object_type )
151
            $object_type = 'term';
152
153
        if ( $sanitized ) {
154
            $data = pods_unsanitize( $data );
155
            $meta = pods_unsanitize( $meta );
156
        }
157
158
        if ( in_array( $object_type, array( 'post', 'term', 'user', 'comment' ) ) )
159
            return call_user_func( array( $this, 'save_' . $object_type ), $data, $meta, $strict, false, $fields );
160
        elseif ( 'settings' == $object_type ) {
161
            // Nothing to save
162
            if ( empty( $meta ) )
163
                return true;
164
165
            return $this->save_setting( pods_var( 'option_id', $data ), $meta, false );
166
        }
167
168
        return false;
169
    }
170
171
    /**
172
     * Delete a WP object
173
     *
174
     * @param string $object_type Object type: post|user|comment
175
     * @param int $id Object ID
176
     * @param bool $force_delete (optional) Force deletion instead of trashing (post types only)
177
     *
178
     * @return bool|mixed
179
     *
180
     * @since 2.0
181
     */
182
    public function delete_wp_object ( $object_type, $id, $force_delete = true ) {
183
        if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
184
            $object_type = 'post';
185
186
        if ( 'taxonomy' == $object_type )
187
            $object_type = 'term';
188
189
        if ( empty( $id ) )
190
            return false;
191
192
        if ( in_array( $object_type, array( 'post' ) ) )
193
            return wp_delete_post( $id, $force_delete );
194
195
        if ( function_exists( 'wp_delete_' . $object_type ) )
196
            return call_user_func( 'wp_delete_' . $object_type, $id );
197
198
        return false;
199
    }
200
201
    /**
202
     * Save a post and it's meta
203
     *
204
     * @param array $post_data All post data to be saved (using wp_insert_post / wp_update_post)
205
     * @param array $post_meta (optional) All meta to be saved (set value to null to delete)
206
     * @param bool $strict (optional) Whether to delete previously saved meta not in $post_meta
207
     * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
208
     * @param array $fields (optional) The array of fields and their options, for further processing with
209
     *
210
     * @return mixed|void
211
     *
212
     * @since 2.0
213
     */
214
    public function save_post ( $post_data, $post_meta = null, $strict = false, $sanitized = false, $fields = array() ) {
215
        $conflicted = pods_no_conflict_check( 'post' );
216
217
        if ( !$conflicted )
218
            pods_no_conflict_on( 'post' );
219
220
        if ( !is_array( $post_data ) || empty( $post_data ) )
221
            $post_data = array( 'post_title' => '' );
222
223
        if ( !is_array( $post_meta ) )
224
            $post_meta = array();
225
226
        if ( $sanitized ) {
227
            $post_data = pods_unsanitize( $post_data );
228
            $post_meta = pods_unsanitize( $post_meta );
229
        }
230
231
        if ( !isset( $post_data[ 'ID' ] ) || empty( $post_data[ 'ID' ] ) )
232
            $post_data[ 'ID' ] = wp_insert_post( $post_data, true );
233
        elseif ( 2 < count( $post_data ) || !isset( $post_data[ 'post_type' ] ) )
234
            $post_data[ 'ID' ] = wp_update_post( $post_data, true );
235
236 View Code Duplication
        if ( is_wp_error( $post_data[ 'ID' ] ) ) {
237
            if ( !$conflicted )
238
                pods_no_conflict_off( 'post' );
239
240
            /**
241
             * @var $post_error WP_Error
242
             */
243
            $post_error = $post_data[ 'ID' ];
244
245
            return pods_error( $post_error->get_error_message(), $this );
246
        }
247
248
        $this->save_post_meta( $post_data[ 'ID' ], $post_meta, $strict, $fields );
249
250
        if ( !$conflicted )
251
            pods_no_conflict_off( 'post' );
252
253
        return $post_data[ 'ID' ];
254
    }
255
256
    /**
257
     * Save a post's meta
258
     *
259
     * @param int $id Post ID
260
     * @param array $post_meta All meta to be saved (set value to null to delete)
261
     * @param bool $strict Whether to delete previously saved meta not in $post_meta
262
     * @param array $fields (optional) The array of fields and their options, for further processing with
263
     *
264
     * @return int Id of the post with the meta
265
     *
266
     * @since 2.0
267
     */
268 View Code Duplication
    public function save_post_meta ( $id, $post_meta = null, $strict = false, $fields = array() ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
269
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
270
271
        $conflicted = pods_no_conflict_check( 'post' );
272
273
        if ( !$conflicted )
274
            pods_no_conflict_on( 'post' );
275
276
        if ( !is_array( $post_meta ) )
277
            $post_meta = array();
278
279
        $id = (int) $id;
280
281
        $meta = get_post_meta( $id );
282
283
        foreach ( $meta as $k => $value ) {
284
            if ( is_array( $value ) && 1 == count( $value ) )
285
                $meta[ $k ] = current( $value );
286
        }
287
288
        foreach ( $post_meta as $meta_key => $meta_value ) {
289
            if ( null === $meta_value || ( $strict && '' === $post_meta[ $meta_key ] ) ) {
290
                $old_meta_value = '';
291
292
                if ( isset( $meta[ $meta_key ] ) )
293
                    $old_meta_value = $meta[ $meta_key ];
294
295
                delete_post_meta( $id, $meta_key, $old_meta_value );
296
            }
297
            else {
298
				$simple = false;
299
300
				if ( isset( $fields[ $meta_key ] ) ) {
301
					$field_data = $fields[ $meta_key ];
302
303
					$simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
304
				}
305
306
				if ( $simple ) {
307
					delete_post_meta( $id, $meta_key );
308
309
					update_post_meta( $id, '_pods_' . $meta_key, $meta_value );
310
311
					if ( ! is_array( $meta_value ) ) {
312
						$meta_value = array( $meta_value );
313
					}
314
315
					foreach ( $meta_value as $value ) {
316
						add_post_meta( $id, $meta_key, $value );
317
					}
318
				}
319
				else {
320
                	update_post_meta( $id, $meta_key, $meta_value );
321
				}
322
			}
323
        }
324
325
        if ( $strict ) {
326
            foreach ( $meta as $meta_key => $meta_value ) {
327
                if ( !isset( $post_meta[ $meta_key ] ) )
328
                    delete_post_meta( $id, $meta_key, $meta_value );
329
            }
330
        }
331
332
        if ( !$conflicted )
333
            pods_no_conflict_off( 'post' );
334
335
        return $id;
336
    }
337
338
    /**
339
     * Save a user and it's meta
340
     *
341
     * @param array $user_data All user data to be saved (using wp_insert_user / wp_update_user)
342
     * @param array $user_meta (optional) All meta to be saved (set value to null to delete)
343
     * @param bool $strict (optional) Whether to delete previously saved meta not in $user_meta
344
     * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
345
     * @param array $fields (optional) The array of fields and their options, for further processing with
346
     *
347
     * @return int Returns user id on success
348
     *
349
     * @since 2.0
350
     */
351
    public function save_user ( $user_data, $user_meta = null, $strict = false, $sanitized = false, $fields = array() ) {
352 View Code Duplication
        if ( !is_array( $user_data ) || empty( $user_data ) )
353
            return pods_error( __( 'User data is required but is either invalid or empty', 'pods' ), $this );
354
355
        $conflicted = pods_no_conflict_check( 'user' );
356
357
        if ( !$conflicted )
358
            pods_no_conflict_on( 'user' );
359
360
        if ( !is_array( $user_meta ) )
361
            $user_meta = array();
362
363
        if ( $sanitized ) {
364
            $user_data = pods_unsanitize( $user_data );
365
            $user_meta = pods_unsanitize( $user_meta );
366
        }
367
368
		// Set role
369
		if ( isset( $user_meta[ 'role' ] ) ) {
370
			$user_data[ 'role' ] = $user_meta[ 'role' ];
371
372
			unset( $user_meta[ 'role' ] );
373
		}
374
375
        if ( !isset( $user_data[ 'ID' ] ) || empty( $user_data[ 'ID' ] ) )
376
            $user_data[ 'ID' ] = wp_insert_user( $user_data );
377
        elseif ( 1 < count( $user_data ) )
378
            wp_update_user( $user_data );
379
380 View Code Duplication
        if ( is_wp_error( $user_data[ 'ID' ] ) ) {
381
            if ( !$conflicted )
382
                pods_no_conflict_off( 'user' );
383
384
            /**
385
             * @var $user_error WP_Error
386
             */
387
            $user_error = $user_data[ 'ID' ];
388
389
            return pods_error( $user_error->get_error_message(), $this );
390
        }
391
392
        $this->save_user_meta( $user_data[ 'ID' ], $user_meta, $strict, $fields );
393
394
        if ( !$conflicted )
395
            pods_no_conflict_off( 'user' );
396
397
        return $user_data[ 'ID' ];
398
    }
399
400
    /**
401
     * Save a user meta
402
     *
403
     * @param int $id User ID
404
     * @param array $user_meta (optional) All meta to be saved (set value to null to delete)
405
     * @param bool $strict (optional) Whether to delete previously saved meta not in $user_meta
406
     * @param array $fields (optional) The array of fields and their options, for further processing with
407
     *
408
     * @return int User ID
409
     *
410
     * @since 2.0
411
     *
412
     */
413 View Code Duplication
    public function save_user_meta ( $id, $user_meta = null, $strict = false, $fields = array() ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
414
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
415
416
        $conflicted = pods_no_conflict_check( 'user' );
417
418
        if ( !$conflicted )
419
            pods_no_conflict_on( 'user' );
420
421
        if ( !is_array( $user_meta ) )
422
            $user_meta = array();
423
424
        $id = (int) $id;
425
426
        $meta = get_user_meta( $id );
427
428
        foreach ( $user_meta as $meta_key => $meta_value ) {
429
            if ( null === $meta_value ) {
430
                $old_meta_value = '';
431
432
                if ( isset( $meta[ $meta_key ] ) )
433
                    $old_meta_value = $meta[ $meta_key ];
434
435
                delete_user_meta( $id, $meta_key, $old_meta_value );
436
            }
437
            else {
438
				$simple = false;
439
440
				if ( isset( $fields[ $meta_key ] ) ) {
441
					$field_data = $fields[ $meta_key ];
442
443
					$simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
444
				}
445
446
				if ( $simple ) {
447
					delete_user_meta( $id, $meta_key );
448
449
					if ( ! is_array( $meta_value ) ) {
450
						$meta_value = array( $meta_value );
451
					}
452
453
					foreach ( $meta_value as $value ) {
454
						add_user_meta( $id, $meta_key, $value );
455
					}
456
				}
457
				else {
458
                	update_user_meta( $id, $meta_key, $meta_value );
459
				}
460
			}
461
        }
462
463
        if ( $strict ) {
464
            foreach ( $meta as $meta_key => $meta_value ) {
465
                if ( !isset( $user_meta[ $meta_key ] ) )
466
                    delete_user_meta( $id, $meta_key, $user_meta[ $meta_key ] );
467
            }
468
        }
469
470
        if ( !$conflicted )
471
            pods_no_conflict_off( 'user' );
472
473
        return $id;
474
    }
475
476
    /**
477
     * Save a comment and it's meta
478
     *
479
     * @param array $comment_data All comment data to be saved (using wp_insert_comment / wp_update_comment)
480
     * @param array $comment_meta (optional) All meta to be saved (set value to null to delete)
481
     * @param bool $strict (optional) Whether to delete previously saved meta not in $comment_meta
482
     * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
483
     * @param array $fields (optional) The array of fields and their options, for further processing with
484
     *
485
     * @return int Comment ID
486
     *
487
     * @since 2.0
488
     */
489
    public function save_comment ( $comment_data, $comment_meta = null, $strict = false, $sanitized = false, $fields = array() ) {
490 View Code Duplication
        if ( !is_array( $comment_data ) || empty( $comment_data ) )
491
            return pods_error( __( 'Comment data is required but is either invalid or empty', 'pods' ), $this );
492
493
        $conflicted = pods_no_conflict_check( 'comment' );
494
495
        if ( !$conflicted )
496
            pods_no_conflict_on( 'comment' );
497
498
        if ( !is_array( $comment_meta ) )
499
            $comment_meta = array();
500
501
        if ( $sanitized ) {
502
            $comment_data = pods_unsanitize( $comment_data );
503
            $comment_meta = pods_unsanitize( $comment_meta );
504
        }
505
506
        if ( !isset( $comment_data[ 'comment_ID' ] ) || empty( $comment_data[ 'comment_ID' ] ) )
507
	        $comment_data[ 'comment_ID' ] = wp_insert_comment( pods_slash( $comment_data ) ); // Expects slashed
508
        elseif ( 1 < count( $comment_data ) )
509
            wp_update_comment( $comment_data );
510
511 View Code Duplication
        if ( is_wp_error( $comment_data[ 'comment_ID' ] ) ) {
512
            if ( !$conflicted )
513
                pods_no_conflict_off( 'comment' );
514
515
            /**
516
             * @var $comment_error WP_Error
517
             */
518
            $comment_error = $comment_data[ 'comment_ID' ];
519
520
            return pods_error( $comment_error->get_error_message(), $this );
521
        }
522
523
        $this->save_comment_meta( $comment_data[ 'comment_ID' ], $comment_meta, $strict, $fields );
524
525
        if ( !$conflicted )
526
            pods_no_conflict_off( 'comment' );
527
528
        return $comment_data[ 'comment_ID' ];
529
    }
530
531
    /**
532
     * Save a comment meta
533
     *
534
     * @param int $id Comment ID
535
     * @param array $comment_meta (optional) All meta to be saved (set value to null to delete)
536
     * @param bool $strict (optional) Whether to delete previously saved meta not in $comment_meta
537
     * @param array $fields (optional) The array of fields and their options, for further processing with
538
     *
539
     * @return int Comment ID
540
     *
541
     * @since 2.0
542
     */
543 View Code Duplication
    public function save_comment_meta ( $id, $comment_meta = null, $strict = false, $fields = array() ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
544
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
545
546
        $conflicted = pods_no_conflict_check( 'comment' );
547
548
        if ( !$conflicted )
549
            pods_no_conflict_on( 'comment' );
550
551
        if ( !is_array( $comment_meta ) )
552
            $comment_meta = array();
553
554
        $id = (int) $id;
555
556
        $meta = get_comment_meta( $id );
557
558
        foreach ( $comment_meta as $meta_key => $meta_value ) {
559
            if ( null === $meta_value ) {
560
                $old_meta_value = '';
561
562
                if ( isset( $meta[ $meta_key ] ) )
563
                    $old_meta_value = $meta[ $meta_key ];
564
565
                delete_comment_meta( $id, $meta_key, $old_meta_value );
566
            }
567
            else {
568
				$simple = false;
569
570
				if ( isset( $fields[ $meta_key ] ) ) {
571
					$field_data = $fields[ $meta_key ];
572
573
					$simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
574
				}
575
576
				if ( $simple ) {
577
					delete_comment_meta( $id, $meta_key );
578
579
					if ( ! is_array( $meta_value ) ) {
580
						$meta_value = array( $meta_value );
581
					}
582
583
					foreach ( $meta_value as $value ) {
584
						add_comment_meta( $id, $meta_key, $value );
585
					}
586
				}
587
				else {
588
                	update_comment_meta( $id, $meta_key, $meta_value );
589
				}
590
			}
591
        }
592
593
        if ( $strict ) {
594
            foreach ( $meta as $meta_key => $meta_value ) {
595
                if ( !isset( $comment_meta[ $meta_key ] ) )
596
                    delete_comment_meta( (int) $id, $meta_key, $comment_meta[ $meta_key ] );
597
            }
598
        }
599
600
        if ( !$conflicted )
601
            pods_no_conflict_off( 'comment' );
602
603
        return $id;
604
    }
605
606
    /**
607
     * Save a taxonomy's term
608
     *
609
     * @param array $term_data All term data to be saved (using wp_insert_term / wp_update_term)
610
     * @param array $term_meta All meta to be saved (set value to null to delete)
611
     * @param bool $strict (optional) Whether to delete previously saved meta not in $post_meta
612
     * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
613
     * @param array $fields (optional) The array of fields and their options, for further processing with
614
     *
615
     * @return int Term ID
616
     *
617
     * @since 2.0
618
     */
619
    public function save_term ( $term_data, $term_meta, $strict = false, $sanitized = false, $fields = array() ) {
620
		if ( empty( $term_data['taxonomy'] ) ) {
621
            return 0;
622
		}
623
624
        $conflicted = pods_no_conflict_check( 'taxonomy' );
625
626
        if ( !is_array( $term_data ) || empty( $term_data ) )
627
            $term_data = array( 'name' => '' );
628
629
        if ( !$conflicted )
630
            pods_no_conflict_on( 'taxonomy' );
631
632
        if ( !is_array( $term_meta ) )
633
            $term_meta = array();
634
635
        if ( $sanitized ) {
636
            $term_data = pods_unsanitize( $term_data );
637
            $term_meta = pods_unsanitize( $term_meta );
638
        }
639
640
        $taxonomy = $term_data['taxonomy'];
641
642
        unset( $term_data['taxonomy'] );
643
644
        if ( empty( $term_data['term_id'] ) ) {
645
        	$term_name = $term_data['name'];
646
647
        	unset( $term_data['name'] );
648
649
            $term_data['term_id'] = wp_insert_term( $term_name, $taxonomy, $term_data );
650
		} elseif ( 2 < count( $term_data ) ) {
651
            $term_data['term_id'] = wp_update_term( $term_data['term_id'], $taxonomy, $term_data );
652
        }
653
654
        if ( is_wp_error( $term_data['term_id'] ) ) {
655
            if ( !$conflicted )
656
                pods_no_conflict_off( 'taxonomy' );
657
658
            /**
659
             * @var $term_error WP_Error
660
             */
661
            $term_error = $term_data[ 'term_id' ];
662
663
            return pods_error( $term_error->get_error_message(), $this );
664
        }
665
        elseif ( is_array( $term_data['term_id'] ) )
666
            $term_data['term_id'] = $term_data['term_id'][ 'term_id' ];
667
668
        $this->save_term_meta( $term_data['term_id'], $term_meta, $strict, $fields );
669
670
        if ( !$conflicted )
671
            pods_no_conflict_off( 'taxonomy' );
672
673
        return $term_data['term_id'];
674
    }
675
676
    /**
677
     * Save a term's meta
678
     *
679
     * @param int $id Term ID
680
     * @param array $term_meta All meta to be saved (set value to null to delete)
681
     * @param bool $strict Whether to delete previously saved meta not in $term_meta
682
     * @param array $fields (optional) The array of fields and their options, for further processing with
683
     *
684
     * @return int Id of the term with the meta
685
     *
686
     * @since 2.0
687
     */
688 View Code Duplication
    public function save_term_meta ( $id, $term_meta = null, $strict = false, $fields = array() ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
689
        if ( ! function_exists( 'get_term_meta' ) ) {
690
        	return $id;
691
        }
692
693
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
694
695
        $conflicted = pods_no_conflict_check( 'taxonomy' );
696
697
        if ( !$conflicted )
698
            pods_no_conflict_on( 'taxonomy' );
699
700
        if ( !is_array( $term_meta ) )
701
            $term_meta = array();
702
703
        $id = (int) $id;
704
705
        $meta = get_term_meta( $id );
706
707
        foreach ( $meta as $k => $value ) {
708
            if ( is_array( $value ) && 1 == count( $value ) )
709
                $meta[ $k ] = current( $value );
710
        }
711
712
        foreach ( $term_meta as $meta_key => $meta_value ) {
713
            if ( null === $meta_value || ( $strict && '' === $term_meta[ $meta_key ] ) ) {
714
                $old_meta_value = '';
715
716
                if ( isset( $meta[ $meta_key ] ) )
717
                    $old_meta_value = $meta[ $meta_key ];
718
719
                delete_term_meta( $id, $meta_key, $old_meta_value );
720
            }
721
            else {
722
				$simple = false;
723
724
				if ( isset( $fields[ $meta_key ] ) ) {
725
					$field_data = $fields[ $meta_key ];
726
727
					$simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
728
				}
729
730
				if ( $simple ) {
731
					delete_term_meta( $id, $meta_key );
732
733
					update_term_meta( $id, '_pods_' . $meta_key, $meta_value );
734
735
					if ( ! is_array( $meta_value ) ) {
736
						$meta_value = array( $meta_value );
737
					}
738
739
					foreach ( $meta_value as $value ) {
740
						add_term_meta( $id, $meta_key, $value );
741
					}
742
				}
743
				else {
744
                	update_term_meta( $id, $meta_key, $meta_value );
745
				}
746
			}
747
        }
748
749
        if ( $strict ) {
750
            foreach ( $meta as $meta_key => $meta_value ) {
751
                if ( !isset( $term_meta[ $meta_key ] ) )
752
                    delete_term_meta( $id, $meta_key, $meta_value );
753
            }
754
        }
755
756
        if ( !$conflicted )
757
            pods_no_conflict_off( 'taxonomy' );
758
759
        return $id;
760
    }
761
762
    /**
763
     * Save a set of options
764
     *
765
     * @param string $setting Setting group name
766
     * @param array $option_data All option data to be saved
767
     * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
768
     *
769
     * @return bool
770
     *
771
     * @since 2.3
772
     */
773
    public function save_setting ( $setting, $option_data, $sanitized = false ) {
774 View Code Duplication
        if ( !is_array( $option_data ) || empty( $option_data ) )
775
            return pods_error( __( 'Setting data is required but is either invalid or empty', 'pods' ), $this );
776
777
        $conflicted = pods_no_conflict_check( 'settings' );
778
779
        if ( !$conflicted )
780
            pods_no_conflict_on( 'settings' );
781
782
        if ( $sanitized )
783
            $option_data = pods_unsanitize( $option_data );
784
785
        foreach ( $option_data as $option => $value ) {
786
            if ( !empty( $setting ) )
787
                $option = $setting . '_' . $option;
788
789
            update_option( $option, $value );
790
        }
791
792
        if ( !$conflicted )
793
            pods_no_conflict_off( 'settings' );
794
795
        return true;
796
    }
797
798
    /**
799
     * Rename a WP object's type
800
     *
801
     * @param string $object_type Object type: post|taxonomy|comment|setting
802
     * @param string $old_name The old name
803
     * @param string $new_name The new name
804
     *
805
     * @return bool
806
     *
807
     * @since 2.0
808
     */
809
    public function rename_wp_object_type ( $object_type, $old_name, $new_name ) {
810
        /**
811
         * @var $wpdb wpdb
812
         */
813
        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...
814
815
        if ( 'post_type' == $object_type )
816
            $object_type = 'post';
817
818
        if ( 'post' == $object_type ) {
819
            pods_query( "UPDATE `{$wpdb->posts}` SET `post_type` = %s WHERE `post_type` = %s", array(
820
                $new_name,
821
                $old_name
822
            ) );
823
        }
824
        elseif ( 'taxonomy' == $object_type ) {
825
            pods_query( "UPDATE `{$wpdb->term_taxonomy}` SET `taxonomy` = %s WHERE `taxonomy` = %s", array(
826
                $new_name,
827
                $old_name
828
            ) );
829
        }
830
        elseif ( 'comment' == $object_type ) {
831
            pods_query( "UPDATE `{$wpdb->comments}` SET `comment_type` = %s WHERE `comment_type` = %s", array(
832
                $new_name,
833
                $old_name
834
            ) );
835
        }
836
        elseif ( 'settings' == $object_type ) {
837
            pods_query( "UPDATE `{$wpdb->options}` SET `option_name` = REPLACE( `option_name`, %s, %s ) WHERE `option_name` LIKE '" . pods_sanitize_like( $old_name ) . "_%'", array(
838
                $new_name . '_',
839
                $old_name . '_'
840
            ) );
841
        }
842
843
        return true;
844
    }
845
846
    /**
847
     * Get a list of core WP object fields for a specific object
848
     *
849
     * @param string $object The pod type to look for, possible values: post_type, user, comment, taxonomy
850
     * @param array $pod Array of Pod data
851
     * @param boolean $refresh Whether to force refresh the information
852
     *
853
     * @return array Array of fields
854
     *
855
     * @since 2.0
856
     */
857
    public function get_wp_object_fields ( $object = 'post_type', $pod = null, $refresh = false ) {
858
        $pod_name = pods_var_raw( 'name', $pod, $object, null, true );
859
860
		if ( 'media' == $pod_name ) {
861
			$object = 'post_type';
862
			$pod_name = 'attachment';
863
		}
864
865
        $fields = false;
866
867
        if ( pods_api_cache() )
868
            $fields = pods_transient_get( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ) );
869
870
        if ( false !== $fields && !$refresh )
871
            return $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
872
873
        $fields = array();
874
875
        if ( 'post_type' == $object ) {
876
            $fields = array(
877
	            'ID' => array(
878
		            'name' => 'ID',
879
		            'label' => 'ID',
880
		            'type' => 'number',
881
		            'alias' => array( 'id' ),
882
	                'options' => array(
883
                        'number_format' => '9999.99'
884
	                )
885
	            ),
886
                'post_title' => array(
887
                    'name' => 'post_title',
888
                    'label' => 'Title',
889
                    'type' => 'text',
890
                    'alias' => array( 'title', 'name' ),
891
                    'options' => array(
892
                        'display_filter' => 'the_title',
893
                        'display_filter_args' => array( 'post_ID' )
894
                    )
895
                ),
896
                'post_content' => array(
897
                    'name' => 'post_content',
898
                    'label' => 'Content',
899
                    'type' => 'wysiwyg',
900
                    'alias' => array( 'content' ),
901
                    'options' => array(
902
                        'wysiwyg_allowed_html_tags' => '',
903
                        'display_filter' => 'the_content',
904
                        'pre_save' => 0
905
                    )
906
                ),
907
                'post_excerpt' => array(
908
                    'name' => 'post_excerpt',
909
                    'label' => 'Excerpt',
910
                    'type' => 'paragraph',
911
                    'alias' => array( 'excerpt' ),
912
                    'options' => array(
913
                        'paragraph_allow_html' => 1,
914
                        'paragraph_allowed_html_tags' => '',
915
                        'display_filter' => 'the_excerpt',
916
                        'pre_save' => 0
917
                    )
918
                ),
919
                'post_author' => array(
920
                    'name' => 'post_author',
921
                    'label' => 'Author',
922
                    'type' => 'pick',
923
                    'alias' => array( 'author' ),
924
                    'pick_object' => 'user',
925
                    'options' => array(
926
                        'pick_format_type' => 'single',
927
                        'pick_format_single' => 'autocomplete',
928
                        'default_value' => '{@user.ID}'
929
                    )
930
                ),
931
                'post_date' => array(
932
                    'name' => 'post_date',
933
                    'label' => 'Publish Date',
934
                    'type' => 'datetime',
935
                    'alias' => array( 'created', 'date' )
936
                ),
937
                'post_date_gmt' => array(
938
                    'name' => 'post_date_gmt',
939
                    'label' => 'Publish Date (GMT)',
940
                    'type' => 'datetime',
941
                    'alias' => array(),
942
                    'hidden' => true
943
                ),
944
                'post_status' => array(
945
                    'name' => 'post_status',
946
                    'label' => 'Status',
947
                    'type' => 'pick',
948
                    'pick_object' => 'post-status',
949
                    'default' => $this->do_hook( 'default_status_' . $pod_name, pods_var( 'default_status', pods_var_raw( 'options', $pod ), 'draft', null, true ), $pod ),
950
                    'alias' => array( 'status' )
951
                ),
952
                'comment_status' => array(
953
                    'name' => 'comment_status',
954
                    'label' => 'Comment Status',
955
                    'type' => 'text',
956
                    'default' => get_option( 'default_comment_status', 'open' ),
957
                    'alias' => array(),
958
                    'data' => array(
959
                        'open' => __( 'Open', 'pods' ),
960
                        'closed' => __( 'Closed', 'pods' )
961
                    )
962
                ),
963
                'ping_status' => array(
964
                    'name' => 'ping_status',
965
                    'label' => 'Ping Status',
966
                    'default' => get_option( 'default_ping_status', 'open' ),
967
                    'type' => 'text',
968
                    'alias' => array(),
969
                    'data' => array(
970
                        'open' => __( 'Open', 'pods' ),
971
                        'closed' => __( 'Closed', 'pods' )
972
                    )
973
                ),
974
                'post_password' => array(
975
                    'name' => 'post_password',
976
                    'label' => 'Password',
977
                    'type' => 'text',
978
                    'alias' => array()
979
                ),
980
                'post_name' => array(
981
                    'name' => 'post_name',
982
                    'label' => 'Permalink',
983
                    'type' => 'slug',
984
                    'alias' => array( 'slug', 'permalink' )
985
                ),
986
                'to_ping' => array(
987
                    'name' => 'to_ping',
988
                    'label' => 'To Ping',
989
                    'type' => 'text',
990
                    'alias' => array(),
991
                    'hidden' => true
992
                ),
993
                'pinged' => array(
994
                    'name' => 'pinged',
995
                    'label' => 'Pinged',
996
                    'type' => 'text',
997
                    'alias' => array(),
998
                    'hidden' => true
999
                ),
1000
                'post_modified' => array(
1001
                    'name' => 'post_modified',
1002
                    'label' => 'Last Modified Date',
1003
                    'type' => 'datetime',
1004
                    'alias' => array( 'modified' ),
1005
                    'hidden' => true
1006
                ),
1007
                'post_modified_gmt' => array(
1008
                    'name' => 'post_modified_gmt',
1009
                    'label' => 'Last Modified Date (GMT)',
1010
                    'type' => 'datetime',
1011
                    'alias' => array(),
1012
                    'hidden' => true
1013
                ),
1014
                'post_content_filtered' => array(
1015
                    'name' => 'post_content_filtered',
1016
                    'label' => 'Content (filtered)',
1017
                    'type' => 'paragraph',
1018
                    'alias' => array(),
1019
                    'hidden' => true,
1020
                    'options' => array(
1021
                        'paragraph_allow_html' => 1,
1022
                        'paragraph_oembed' => 1,
1023
                        'paragraph_wptexturize' => 1,
1024
                        'paragraph_convert_chars' => 1,
1025
                        'paragraph_wpautop' => 1,
1026
                        'paragraph_allow_shortcode' => 1,
1027
                        'paragraph_allowed_html_tags' => ''
1028
                    )
1029
                ),
1030
                'post_parent' => array(
1031
                    'name' => 'post_parent',
1032
                    'label' => 'Parent',
1033
                    'type' => 'pick',
1034
                    'pick_object' => 'post_type',
1035
                    'pick_val' => '__current__',
1036
                    'alias' => array( 'parent' ),
1037
                    'data' => array(),
1038
                    'hidden' => true
1039
                ),
1040
                'guid' => array(
1041
                    'name' => 'guid',
1042
                    'label' => 'GUID',
1043
                    'type' => 'text',
1044
                    'alias' => array(),
1045
                    'hidden' => true
1046
                ),
1047
                'menu_order' => array(
1048
                    'name' => 'menu_order',
1049
                    'label' => 'Menu Order',
1050
                    'type' => 'number',
1051
                    'alias' => array(),
1052
	                'options' => array(
1053
                        'number_format' => '9999.99'
1054
	                )
1055
                ),
1056
                'post_type' => array(
1057
                    'name' => 'post_type',
1058
                    'label' => 'Type',
1059
                    'type' => 'text',
1060
                    'alias' => array( 'type' ),
1061
                    'hidden' => true
1062
                ),
1063
                'post_mime_type' => array(
1064
                    'name' => 'post_mime_type',
1065
                    'label' => 'Mime Type',
1066
                    'type' => 'text',
1067
                    'alias' => array(),
1068
                    'hidden' => true
1069
                ),
1070
                'comment_count' => array(
1071
                    'name' => 'comment_count',
1072
                    'label' => 'Comment Count',
1073
                    'type' => 'number',
1074
                    'alias' => array(),
1075
                    'hidden' => true
1076
                )
1077
            );
1078
1079
            if ( !empty( $pod ) ) {
1080
                $taxonomies = get_object_taxonomies( $pod_name, 'objects' );
1081
1082
                foreach ( $taxonomies as $taxonomy ) {
1083
                    $fields[ $taxonomy->name ] = array(
1084
                        'name' => $taxonomy->name,
1085
                        'label' => $taxonomy->labels->name,
1086
                        'type' => 'taxonomy',
1087
						'pick_object' => 'taxonomy',
1088
						'pick_val' => $taxonomy->name,
1089
                        'alias' => array(),
1090
                        'hidden' => true,
1091
						'options' => array(
1092
							'taxonomy_format_type' => 'multi'
1093
						)
1094
                    );
1095
                }
1096
            }
1097
        }
1098
        elseif ( 'user' == $object ) {
1099
            $fields = array(
1100
	            'ID' => array(
1101
		            'name' => 'ID',
1102
		            'label' => 'ID',
1103
		            'type' => 'number',
1104
		            'alias' => array( 'id' ),
1105
	                'options' => array(
1106
                        'number_format' => '9999.99'
1107
	                )
1108
	            ),
1109
                'user_login' => array(
1110
                    'name' => 'user_login',
1111
                    'label' => 'Title',
1112
                    'type' => 'text',
1113
                    'alias' => array( 'login' ),
1114
                    'options' => array(
1115
                        'required' => 1
1116
                    )
1117
                ),
1118
                'user_nicename' => array(
1119
                    'name' => 'user_nicename',
1120
                    'label' => 'Permalink',
1121
                    'type' => 'slug',
1122
                    'alias' => array( 'nicename', 'slug', 'permalink' )
1123
                ),
1124
                'display_name' => array(
1125
                    'name' => 'display_name',
1126
                    'label' => 'Display Name',
1127
                    'type' => 'text',
1128
                    'alias' => array( 'title', 'name' )
1129
                ),
1130
                'user_pass' => array(
1131
                    'name' => 'user_pass',
1132
                    'label' => 'Password',
1133
                    'type' => 'text',
1134
                    'alias' => array( 'password', 'pass' ),
1135
                    'options' => array(
1136
                        'required' => 1,
1137
                        'text_format_type' => 'password'
1138
                    )
1139
                ),
1140
                'user_email' => array(
1141
                    'name' => 'user_email',
1142
                    'label' => 'E-mail',
1143
                    'type' => 'text',
1144
                    'alias' => array( 'email' ),
1145
                    'options' => array(
1146
                        'required' => 1,
1147
                        'text_format_type' => 'email'
1148
                    )
1149
                ),
1150
                'user_url' => array(
1151
                    'name' => 'user_url',
1152
                    'label' => 'URL',
1153
                    'type' => 'text',
1154
                    'alias' => array( 'url', 'website' ),
1155
                    'options' => array(
1156
                        'required' => 0,
1157
                        'text_format_type' => 'website',
1158
                        'text_format_website' => 'normal'
1159
                    )
1160
                ),
1161
                'user_registered' => array(
1162
                    'name' => 'user_registered',
1163
                    'label' => 'Registration Date',
1164
                    'type' => 'date',
1165
                    'alias' => array( 'created', 'date', 'registered' ),
1166
                    'options' => array(
1167
                        'date_format_type' => 'datetime'
1168
                    )
1169
                )
1170
            );
1171
        }
1172
        elseif ( 'comment' == $object ) {
1173
            $fields = array(
1174
	            'comment_ID' => array(
1175
		            'name' => 'comment_ID',
1176
		            'label' => 'ID',
1177
		            'type' => 'number',
1178
		            'alias' => array( 'id', 'ID', 'comment_id' ),
1179
	                'options' => array(
1180
                        'number_format' => '9999.99'
1181
	                )
1182
	            ),
1183
                'comment_content' => array(
1184
                    'name' => 'comment_content',
1185
                    'label' => 'Content',
1186
                    'type' => 'wysiwyg',
1187
                    'alias' => array( 'content' )
1188
                ),
1189
                'comment_approved' => array(
1190
                    'name' => 'comment_approved',
1191
                    'label' => 'Approved',
1192
                    'type' => 'number',
1193
                    'alias' => array( 'approved' ),
1194
	                'options' => array(
1195
                        'number_format' => '9999.99'
1196
	                )
1197
                ),
1198
                'comment_post_ID' => array(
1199
                    'name' => 'comment_post_ID',
1200
                    'label' => 'Post',
1201
                    'type' => 'pick',
1202
                    'alias' => array( 'post', 'post_id' ),
1203
                    'data' => array()
1204
                ),
1205
                'user_id' => array(
1206
                    'name' => 'user_id',
1207
                    'label' => 'Author',
1208
                    'type' => 'pick',
1209
                    'alias' => array( 'author' ),
1210
                    'pick_object' => 'user',
1211
                    'data' => array()
1212
                ),
1213
                'comment_date' => array(
1214
                    'name' => 'comment_date',
1215
                    'label' => 'Date',
1216
                    'type' => 'date',
1217
                    'alias' => array( 'created', 'date' ),
1218
                    'options' => array(
1219
                        'date_format_type' => 'datetime'
1220
                    )
1221
                ),
1222
                'comment_author' => array(
1223
                    'name' => 'comment_author',
1224
                    'label' => 'Author',
1225
                    'type' => 'text',
1226
                    'alias' => array( 'author' )
1227
                ),
1228
                'comment_author_email' => array(
1229
                    'name' => 'comment_author_email',
1230
                    'label' => 'Author E-mail',
1231
                    'type' => 'email',
1232
                    'alias' => array( 'author_email' )
1233
                ),
1234
                'comment_author_url' => array(
1235
                    'name' => 'comment_author_url',
1236
                    'label' => 'Author URL',
1237
                    'type' => 'text',
1238
                    'alias' => array( 'author_url' )
1239
                ),
1240
                'comment_author_IP' => array(
1241
                    'name' => 'comment_author_IP',
1242
                    'label' => 'Author IP',
1243
                    'type' => 'text',
1244
                    'alias' => array( 'author_IP' )
1245
                ),
1246
                'comment_type' => array(
1247
                    'name' => 'comment_type',
1248
                    'label' => 'Type',
1249
                    'type' => 'text',
1250
                    'alias' => array( 'type' ),
1251
                    'hidden' => true
1252
                ),
1253
                'comment_parent' => array(
1254
                    'name' => 'comment_parent',
1255
                    'label' => 'Parent',
1256
                    'type' => 'pick',
1257
                    'pick_object' => 'comment',
1258
                    'pick_val' => '__current__',
1259
                    'alias' => array( 'parent' ),
1260
                    'data' => array(),
1261
                    'hidden' => true
1262
                )
1263
            );
1264
        }
1265
        elseif ( 'taxonomy' == $object ) {
1266
            $fields = array(
1267
	            'term_id' => array(
1268
		            'name' => 'term_id',
1269
		            'label' => 'ID',
1270
		            'type' => 'number',
1271
		            'alias' => array( 'id', 'ID' ),
1272
	                'options' => array(
1273
                        'number_format' => '9999.99'
1274
	                )
1275
	            ),
1276
                'name' => array(
1277
                    'name' => 'name',
1278
                    'label' => 'Title',
1279
                    'type' => 'text',
1280
                    'alias' => array( 'title' )
1281
                ),
1282
                'slug' => array(
1283
                    'name' => 'slug',
1284
                    'label' => 'Permalink',
1285
                    'type' => 'slug',
1286
                    'alias' => array( 'permalink' )
1287
                ),
1288
                'description' => array(
1289
                    'name' => 'description',
1290
                    'label' => 'Description',
1291
                    'type' => 'wysiwyg',
1292
                    'alias' => array( 'content' )
1293
                ),
1294
                'taxonomy' => array(
1295
                    'name' => 'taxonomy',
1296
                    'label' => 'Taxonomy',
1297
                    'type' => 'text',
1298
                    'alias' => array()
1299
                ),
1300
                'parent' => array(
1301
                    'name' => 'parent',
1302
                    'label' => 'Parent',
1303
                    'type' => 'pick',
1304
                    'pick_object' => 'taxonomy',
1305
                    'pick_val' => '__current__',
1306
                    'alias' => array( 'parent' ),
1307
                    'data' => array(),
1308
                    'hidden' => true
1309
                ),
1310
                'term_taxonomy_id' => array(
1311
                    'name' => 'term_taxonomy_id',
1312
                    'label' => 'Term Taxonomy ID',
1313
                    'type' => 'number',
1314
                    'alias' => array(),
1315
                    'hidden' => true,
1316
	                'options' => array(
1317
                        'number_format' => '9999.99'
1318
	                )
1319
                ),
1320
                'term_group' => array(
1321
                    'name' => 'term_group',
1322
                    'label' => 'Term Group',
1323
                    'type' => 'number',
1324
                    'alias' => array( 'group' ),
1325
                    'hidden' => true,
1326
	                'options' => array(
1327
                        'number_format' => '9999.99'
1328
	                )
1329
                ),
1330
                'count' => array(
1331
                    'name' => 'count',
1332
                    'label' => 'Count',
1333
                    'type' => 'number',
1334
                    'alias' => array(),
1335
                    'hidden' => true,
1336
	                'options' => array(
1337
                        'number_format' => '9999.99'
1338
	                )
1339
                )
1340
            );
1341
        }
1342
1343
        $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
1344
1345
        foreach ( $fields as $field => $options ) {
1346
            if ( !isset( $options[ 'alias' ] ) )
1347
                $options[ 'alias' ] = array();
1348
            else
1349
                $options[ 'alias' ] = (array) $options[ 'alias' ];
1350
1351
            if ( !isset( $options[ 'name' ] ) )
1352
                $options[ 'name' ] = $field;
1353
1354
            $fields[ $field ] = $options;
1355
        }
1356
1357
        $fields = PodsForm::fields_setup( $fields );
1358
1359 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
1360
            pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields );
1361
1362
        return $fields;
1363
    }
1364
1365
    /**
1366
     *
1367
     * @see PodsAPI::save_pod
1368
     *
1369
     * Add a Pod via the Wizard
1370
     *
1371
     * $params['create_extend'] string Create or Extend a Content Type
1372
     * $params['create_pod_type'] string Pod Type (for Creating)
1373
     * $params['create_name'] string Pod Name (for Creating)
1374
     * $params['create_label_plural'] string Plural Label (for Creating)
1375
     * $params['create_label_singular'] string Singular Label (for Creating)
1376
     * $params['create_storage'] string Storage Type (for Creating Post Types)
1377
     * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies)
1378
     * $params['extend_pod_type'] string Pod Type (for Extending)
1379
     * $params['extend_post_type'] string Post Type (for Extending Post Types)
1380
     * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies)
1381
     * $params['extend_storage'] string Storage Type (for Extending Post Types / Users / Comments)
1382
     *
1383
     * @param array $params An associative array of parameters
1384
     *
1385
     * @return bool|int Pod ID
1386
     * @since 2.0
1387
     */
1388
    public function add_pod ( $params ) {
1389
        $defaults = array(
1390
            'create_extend' => 'create',
1391
            'create_pod_type' => 'post_type',
1392
1393
            'create_name' => '',
1394
            'create_label_singular' => '',
1395
            'create_label_plural' => '',
1396
            'create_storage' => 'meta',
1397
            'create_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' ),
1398
1399
            'create_setting_name' => '',
1400
            'create_label_title' => '',
1401
            'create_label_menu' => '',
1402
            'create_menu_location' => 'settings',
1403
1404
            'extend_pod_type' => 'post_type',
1405
            'extend_post_type' => 'post',
1406
            'extend_taxonomy' => 'category',
1407
            'extend_table' => '',
1408
            'extend_storage' => 'meta',
1409
            'extend_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'table' ),
1410
        );
1411
1412
        $params = (object) array_merge( $defaults, (array) $params );
1413
1414
        if ( empty( $params->create_extend ) || !in_array( $params->create_extend, array( 'create', 'extend' ) ) )
1415
            return pods_error( __( 'Please choose whether to Create or Extend a Content Type', 'pods' ), $this );
1416
1417
        $pod_params = array(
1418
            'name' => '',
1419
            'label' => '',
1420
            'type' => '',
1421
            'storage' => 'table',
1422
            'object' => '',
1423
            'options' => array()
1424
        );
1425
1426
        if ( 'create' == $params->create_extend ) {
1427
            $label = ucwords( str_replace( '_', ' ', $params->create_name ) );
1428
1429
            if ( !empty( $params->create_label_singular ) )
1430
                $label = $params->create_label_singular;
1431
1432
            $pod_params[ 'name' ] = $params->create_name;
1433
            $pod_params[ 'label' ] = ( !empty( $params->create_label_plural ) ? $params->create_label_plural : $label );
1434
            $pod_params[ 'type' ] = $params->create_pod_type;
1435
            $pod_params[ 'options' ] = array(
1436
                'label_singular' => ( !empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params[ 'label' ] ),
1437
                'public' => 1,
1438
                'show_ui' => 1
1439
            );
1440
1441
            // Auto-generate name if not provided
1442
            if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'options' ][ 'label_singular' ] ) )
1443
                $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'options' ][ 'label_singular' ] );
1444
1445
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1446
                if ( empty(  $pod_params[ 'name' ] ) )
1447
                    return pods_error( 'Please enter a Name for this Pod', $this );
1448
1449
                $pod_params[ 'storage' ] = $params->create_storage;
1450
1451
                if ( pods_tableless() )
1452
                    $pod_params[ 'storage' ] = 'meta';
1453
            }
1454
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1455
                if ( empty(  $pod_params[ 'name' ] ) )
1456
                    return pods_error( 'Please enter a Name for this Pod', $this );
1457
1458
                $pod_params[ 'storage' ] = $params->create_storage_taxonomy;
1459
1460
                if ( pods_tableless() )
1461
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1462
1463
				$pod_params['options']['hierarchical'] = 1;
1464
            }
1465
            elseif ( 'pod' == $pod_params[ 'type' ] ) {
1466
                if ( empty(  $pod_params[ 'name' ] ) )
1467
                    return pods_error( 'Please enter a Name for this Pod', $this );
1468
1469
                if ( pods_tableless() ) {
1470
                    $pod_params[ 'type' ] = 'post_type';
1471
                    $pod_params[ 'storage' ] = 'meta';
1472
                }
1473
            }
1474
            elseif ( 'settings' == $pod_params[ 'type' ] ) {
1475
                $pod_params[ 'name' ] = $params->create_setting_name;
1476
                $pod_params[ 'label' ] = ( !empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) );
1477
                $pod_params[ 'options' ] = array(
1478
                    'menu_name' => ( !empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params[ 'label' ] ),
1479
                    'menu_location' => $params->create_menu_location
1480
                );
1481
                $pod_params[ 'storage' ] = 'none';
1482
1483
                // Auto-generate name if not provided
1484
                if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'label' ] ) )
1485
                    $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'label' ] );
1486
1487
                if ( empty( $pod_params[ 'name' ] ) )
1488
                    return pods_error( 'Please enter a Name for this Pod', $this );
1489
            }
1490
        }
1491
        elseif ( 'extend' == $params->create_extend ) {
1492
            $pod_params[ 'type' ] = $params->extend_pod_type;
1493
1494
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1495
                $pod_params[ 'storage' ] = $params->extend_storage;
1496
1497
                if ( pods_tableless() )
1498
                    $pod_params[ 'storage' ] = 'meta';
1499
1500
                $pod_params[ 'name' ] = $params->extend_post_type;
1501
            }
1502
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1503
                $pod_params[ 'storage' ] = $params->extend_storage_taxonomy;
1504
1505
                if ( pods_tableless() )
1506
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1507
1508
                $pod_params[ 'name' ] = $params->extend_taxonomy;
1509
            }
1510
            elseif ( 'table' == $pod_params[ 'type' ] ) {
1511
                $pod_params[ 'storage' ] = 'table';
1512
                $pod_params[ 'name' ] = $params->extend_table;
1513
            }
1514
            else {
1515
                $pod_params[ 'storage' ] = $params->extend_storage;
1516
1517
                if ( pods_tableless() )
1518
                    $pod_params[ 'storage' ] = 'meta';
1519
1520
                $pod_params[ 'name' ] = $params->extend_pod_type;
1521
            }
1522
1523
            $pod_params[ 'label' ] = ucwords( str_replace( '_', ' ', $pod_params[ 'name' ] ) );
1524
            $pod_params[ 'object' ] = $pod_params[ 'name' ];
1525
        }
1526
1527
        if ( empty( $pod_params[ 'object' ] ) ) {
1528
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1529
                $check = get_post_type_object( $pod_params[ 'name' ] );
1530
1531 View Code Duplication
                if ( !empty( $check ) )
1532
                    return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1533
1534
                $pod_params[ 'options' ][ 'supports_title' ] = 1;
1535
                $pod_params[ 'options' ][ 'supports_editor' ] = 1;
1536
            }
1537
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1538
                $check = get_taxonomy( $pod_params[ 'name' ] );
1539
1540 View Code Duplication
                if ( !empty( $check ) )
1541
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1542
            }
1543
        }
1544
1545
        if ( !empty( $pod_params ) )
1546
            return $this->save_pod( $pod_params );
1547
1548
        return false;
1549
    }
1550
1551
    /**
1552
     * Add or edit a Pod
1553
     *
1554
     * $params['id'] int The Pod ID
1555
     * $params['name'] string The Pod name
1556
     * $params['label'] string The Pod label
1557
     * $params['type'] string The Pod type
1558
     * $params['object'] string The object being extended (if any)
1559
     * $params['storage'] string The Pod storage
1560
     * $params['options'] array Options
1561
     *
1562
     * @param array $params An associative array of parameters
1563
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
1564
     * @param bool|int $db (optional) Whether to save into the DB or just return Pod array.
1565
     *
1566
     * @return int Pod ID
1567
     * @since 1.7.9
1568
     */
1569
    public function save_pod ( $params, $sanitized = false, $db = true ) {
1570
        $tableless_field_types = PodsForm::tableless_field_types();
1571
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
1572
1573
        $load_params = (object) $params;
1574
1575
        if ( isset( $load_params->id ) && isset( $load_params->name ) )
1576
            unset( $load_params->name );
1577
1578
        if ( isset( $load_params->old_name ) )
1579
            $load_params->name = $load_params->old_name;
1580
1581
        $load_params->table_info = true;
1582
1583
        $pod = $this->load_pod( $load_params, false );
1584
1585
        $params = (object) $params;
1586
1587
        if ( false === $sanitized )
1588
            $params = pods_sanitize( $params );
1589
1590
        $old_id = $old_name = $old_storage = null;
1591
1592
        $old_fields = $old_options = array();
1593
1594
		if ( isset( $params->name ) && ! isset( $params->object ) ) {
1595
			$params->name = pods_clean_name( $params->name );
1596
		}
1597
1598
        if ( !empty( $pod ) ) {
1599
            if ( isset( $params->id ) && 0 < $params->id )
1600
                $old_id = $params->id;
1601
1602
            $params->id = $pod[ 'id' ];
1603
1604
            $old_name = $pod[ 'name' ];
1605
            $old_storage = $pod[ 'storage' ];
1606
            $old_fields = $pod[ 'fields' ];
1607
            $old_options = $pod[ 'options' ];
1608
1609
            if ( !isset( $params->name ) && empty( $params->name ) )
1610
                $params->name = $pod[ 'name' ];
1611
1612
            if ( $old_name != $params->name && false !== $this->pod_exists( array( 'name' => $params->name ) ) )
1613
                return pods_error( sprintf( __( 'Pod %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1614
1615
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'user', 'comment', 'media' ) ) && in_array( $pod[ 'object' ], array( 'user', 'comment', 'media' ) ) )
1616
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1617
1618
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && !empty( $pod[ 'object' ] ) && $pod[ 'object' ] == $old_name )
1619
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1620
1621
            if ( $old_id != $params->id ) {
1622
                if ( $params->type == $pod[ 'type' ] && isset( $params->object ) && $params->object == $pod[ 'object' ] )
1623
                    return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this );
1624
                else
1625
                    return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this );
1626
            }
1627
        }
1628
		elseif ( in_array( $params->name, array( 'order','orderby','post_type' ) ) && 'post_type' == pods_var( 'type', $params ) ) {
1629
			return pods_error( sprintf( 'There are certain names that a Custom Post Types cannot be named and unfortunately, %s is one of them.', $params->name ), $this );
1630
		}
1631
        else {
1632
            $pod = array(
1633
                'id' => 0,
1634
                'name' => $params->name,
1635
                'label' => $params->name,
1636
                'description' => '',
1637
                'type' => 'pod',
1638
                'storage' => 'table',
1639
                'object' => '',
1640
                'alias' => '',
1641
                'options' => array(),
1642
                'fields' => array()
1643
            );
1644
        }
1645
1646
        // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite)
1647
        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1648
            $pod[ 'fields' ] = array();
1649
            $pod[ 'options' ] = array();
1650
        }
1651
1652
        // Setup options
1653
        $options = get_object_vars( $params );
1654
1655
        if ( isset( $options[ 'method' ] ) )
1656
            unset( $options[ 'method' ] );
1657
1658
        $options_ignore = array(
1659
            'object_type',
1660
            'object_name',
1661
            'table',
1662
            'meta_table',
1663
            'pod_table',
1664
            'field_id',
1665
            'field_index',
1666
            'field_slug',
1667
            'field_type',
1668
            'field_parent',
1669
            'field_parent_select',
1670
            'meta_field_id',
1671
            'meta_field_index',
1672
            'meta_field_value',
1673
            'pod_field_id',
1674
            'pod_field_index',
1675
            'object_fields',
1676
            'join',
1677
            'where',
1678
            'where_default',
1679
            'orderby',
1680
            'pod',
1681
            'recurse',
1682
            'table_info',
1683
            'attributes',
1684
            'group',
1685
            'grouped',
1686
            'developer_mode',
1687
            'dependency',
1688
            'depends-on',
1689
            'excludes-on'
1690
        );
1691
1692
        foreach ( $options_ignore as $ignore ) {
1693
            if ( isset( $options[ $ignore ] ) )
1694
                unset( $options[ $ignore ] );
1695
        }
1696
1697
        $exclude = array(
1698
            'id',
1699
            'name',
1700
            'label',
1701
            'description',
1702
            'type',
1703
            'storage',
1704
            'object',
1705
            'alias',
1706
            'options',
1707
            'fields'
1708
        );
1709
1710 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
1711
            $aliases = array( $exclude_field );
1712
1713
            if ( is_array( $exclude_field ) ) {
1714
                $aliases = array_merge( array( $k ), $exclude_field );
1715
                $exclude_field = $k;
1716
            }
1717
1718
            foreach ( $aliases as $alias ) {
1719
                if ( isset( $options[ $alias ] ) ) {
1720
                    $pod[ $exclude_field ] = pods_trim( $options[ $alias ] );
1721
1722
                    unset( $options[ $alias ] );
1723
                }
1724
            }
1725
        }
1726
1727
        if ( pods_tableless() && !in_array( $pod[ 'type' ], array( 'settings', 'table' ) ) ) {
1728
            if ( 'pod' == $pod[ 'type' ] )
1729
                $pod[ 'type' ] = 'post_type';
1730
1731 View Code Duplication
            if ( 'table' == $pod[ 'storage' ] ) {
1732
                if ( 'taxonomy' == $pod[ 'type' ] && ! function_exists( 'get_term_meta' ) )
1733
                    $pod[ 'storage' ] = 'none';
1734
                else
1735
                    $pod[ 'storage' ] = 'meta';
1736
            }
1737
        }
1738
1739
        $pod[ 'options' ][ 'type' ] = $pod[ 'type' ];
1740
        $pod[ 'options' ][ 'storage' ] = $pod[ 'storage' ];
1741
        $pod[ 'options' ][ 'object' ] = $pod[ 'object' ];
1742
        $pod[ 'options' ][ 'alias' ] = $pod[ 'alias' ];
1743
1744
        $pod[ 'options' ] = array_merge( $pod[ 'options' ], $options );
1745
1746
		/**
1747
		 * @var WP_Query
1748
		 */
1749
		global $wp_query;
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...
1750
1751
		$reserved_query_vars = array(
1752
			'post_type',
1753
			'taxonomy',
1754
			'output'
1755
		);
1756
1757
		if ( is_object( $wp_query ) ) {
1758
			$reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
1759
		}
1760
1761 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var_string' ] ) ) {
1762
			if ( in_array( $pod[ 'options' ][ 'query_var_string' ], $reserved_query_vars ) ) {
1763
				$pod[ 'options' ][ 'query_var_string' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var_string' ];
1764
			}
1765
		}
1766
1767 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var' ] ) ) {
1768
			if ( in_array( $pod[ 'options' ][ 'query_var' ], $reserved_query_vars ) ) {
1769
				$pod[ 'options' ][ 'query_var' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var' ];
1770
			}
1771
		}
1772
1773
        if ( strlen( $pod[ 'label' ] ) < 1 )
1774
            $pod[ 'label' ] = $pod[ 'name' ];
1775
1776
        if ( 'post_type' == $pod[ 'type' ] ) {
1777
            // Max length for post types are 20 characters
1778
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 20 );
1779
        }
1780
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1781
            // Max length for taxonomies are 32 characters
1782
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 32 );
1783
        }
1784
1785
        $params->id = $pod[ 'id' ];
1786
        $params->name = $pod[ 'name' ];
1787
1788
        if ( null !== $old_name && $old_name != $params->name && empty( $pod[ 'object' ] ) ) {
1789
            if ( 'post_type' == $pod[ 'type' ] ) {
1790
                $check = get_post_type_object( $params->name );
1791
1792 View Code Duplication
                if ( !empty( $check ) )
1793
                    return pods_error( sprintf( __( 'Post Type %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1794
            }
1795
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1796
                $check = get_taxonomy( $params->name );
1797
1798 View Code Duplication
                if ( !empty( $check ) )
1799
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1800
            }
1801
        }
1802
1803
        $field_table_operation = true;
1804
1805
        // Add new pod
1806
        if ( empty( $params->id ) ) {
1807
            if ( strlen( $params->name ) < 1 )
1808
                return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this );
1809
1810
            $post_data = array(
1811
                'post_name' => $pod[ 'name' ],
1812
                'post_title' => $pod[ 'label' ],
1813
                'post_content' => $pod[ 'description' ],
1814
                'post_type' => '_pods_pod',
1815
                'post_status' => 'publish'
1816
            );
1817
1818
            if ( 'pod' == $pod[ 'type' ] && ( !is_array( $pod[ 'fields' ] ) || empty( $pod[ 'fields' ] ) ) ) {
1819
                $pod[ 'fields' ] = array();
1820
1821
                $pod[ 'fields' ][ 'name' ] = array(
1822
                    'name' => 'name',
1823
                    'label' => 'Name',
1824
                    'type' => 'text',
1825
                    'options' => array(
1826
                        'required' => '1'
1827
                    )
1828
                );
1829
1830
                $pod[ 'fields' ][ 'created' ] = array(
1831
                    'name' => 'created',
1832
                    'label' => 'Date Created',
1833
                    'type' => 'datetime',
1834
                    'options' => array(
1835
                        'datetime_format' => 'ymd_slash',
1836
                        'datetime_time_type' => '12',
1837
                        'datetime_time_format' => 'h_mm_ss_A'
1838
                    )
1839
                );
1840
1841
                $pod[ 'fields' ][ 'modified' ] = array(
1842
                    'name' => 'modified',
1843
                    'label' => 'Date Modified',
1844
                    'type' => 'datetime',
1845
                    'options' => array(
1846
                        'datetime_format' => 'ymd_slash',
1847
                        'datetime_time_type' => '12',
1848
                        'datetime_time_format' => 'h_mm_ss_A'
1849
                    )
1850
                );
1851
1852
                $pod[ 'fields' ][ 'author' ] = array(
1853
                    'name' => 'author',
1854
                    'label' => 'Author',
1855
                    'type' => 'pick',
1856
                    'pick_object' => 'user',
1857
                    'options' => array(
1858
                        'pick_format_type' => 'single',
1859
                        'pick_format_single' => 'autocomplete',
1860
                        'default_value' => '{@user.ID}'
1861
                    )
1862
                );
1863
1864
                $pod[ 'fields' ][ 'permalink' ] = array(
1865
                    'name' => 'permalink',
1866
                    'label' => 'Permalink',
1867
                    'type' => 'slug',
1868
                    'description' => 'Leave blank to auto-generate from Name'
1869
                );
1870
1871
                if ( !isset( $pod[ 'options' ][ 'pod_index' ] ) )
1872
                    $pod[ 'options' ][ 'pod_index' ] = 'name';
1873
            }
1874
1875
            $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db );
1876
1877
            $field_table_operation = false;
1878
        }
1879
        else {
1880
            $post_data = array(
1881
                'ID' => $pod[ 'id' ],
1882
                'post_name' => $pod[ 'name' ],
1883
                'post_title' => $pod[ 'label' ],
1884
                'post_content' => $pod[ 'description' ],
1885
                'post_status' => 'publish'
1886
            );
1887
        }
1888
1889
        if ( true === $db ) {
1890
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
1891
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
1892
1893
            $conflicted = false;
1894
1895
            // Headway compatibility fix
1896
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
1897
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1898
1899
                $conflicted = true;
1900
            }
1901
1902
            $params->id = $this->save_wp_object( 'post', $post_data, $pod[ 'options' ], true, true );
1903
1904
            if ( $conflicted )
1905
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1906
1907
            if ( false === $params->id )
1908
                return pods_error( __( 'Cannot save Pod', 'pods' ), $this );
1909
        }
1910
        elseif ( empty( $params->id ) )
1911
            $params->id = (int) $db;
1912
1913
        $pod[ 'id' ] = $params->id;
1914
1915
        // Setup / update tables
1916
        if ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $old_storage != $pod[ 'storage' ] && $db ) {
1917
            $definitions = array( "`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY" );
1918
1919
            $defined_fields = array();
1920
1921
            foreach ( $pod[ 'fields' ] as $field ) {
1922
                if ( !is_array( $field ) || !isset( $field[ 'name' ] ) || in_array( $field[ 'name' ], $defined_fields ) )
1923
                    continue;
1924
1925
                $defined_fields[] = $field[ 'name' ];
1926
1927
                if ( !in_array( $field[ 'type' ], $tableless_field_types ) || ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) ) {
1928
                    $definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, pods_var_raw( 'options', $field, array() ) ) );
1929
1930
                    if ( 0 < strlen( $definition ) )
1931
                        $definitions[] = "`{$field['name']}` " . $definition;
1932
                }
1933
            }
1934
1935
            pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`" );
1936
1937
            $result = pods_query( "CREATE TABLE `@wp_pods_{$params->name}` (" . implode( ', ', $definitions ) . ") DEFAULT CHARSET utf8", $this );
1938
1939
            if ( empty( $result ) )
1940
                return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this );
1941
1942
        }
1943
        elseif ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $pod[ 'storage' ] == $old_storage && null !== $old_name && $old_name != $params->name && $db ) {
1944
            $result = pods_query( "ALTER TABLE `@wp_pods_{$old_name}` RENAME `@wp_pods_{$params->name}`", $this );
1945
1946
            if ( empty( $result ) )
1947
                return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this );
1948
        }
1949
1950
        /**
1951
         * @var $wpdb wpdb
1952
         */
1953
        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...
1954
1955
		if ( null !== $old_name && $old_name != $params->name && $db ) {
1956
        	// Rename items in the DB pointed at the old WP Object names
1957
			if ( 'post_type' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1958
				$this->rename_wp_object_type( 'post', $old_name, $params->name );
1959
			}
1960 View Code Duplication
			elseif ( 'taxonomy' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1961
				$this->rename_wp_object_type( 'taxonomy', $old_name, $params->name );
1962
			}
1963 View Code Duplication
			elseif ( 'comment' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1964
				$this->rename_wp_object_type( 'comment', $old_name, $params->name );
1965
			}
1966
			elseif ( 'settings' == $pod[ 'type' ] ) {
1967
				$this->rename_wp_object_type( 'settings', $old_name, $params->name );
1968
			}
1969
1970
        	// Sync any related fields if the name has changed
1971
            $fields = pods_query( "
1972
                SELECT `p`.`ID`
1973
                FROM `{$wpdb->posts}` AS `p`
1974
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1975
                LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID`
1976
                WHERE
1977
                    `p`.`post_type` = '_pods_field'
1978
                    AND `pm`.`meta_key` = 'pick_object'
1979
                    AND (
1980
                    	`pm`.`meta_value` = 'pod'
1981
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "'
1982
					)
1983
                    AND `pm2`.`meta_key` = 'pick_val'
1984
                    AND `pm2`.`meta_value` = '{$old_name}'
1985
            " );
1986
1987 View Code Duplication
            if ( !empty( $fields ) ) {
1988
                foreach ( $fields as $field ) {
1989
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
1990
                    update_post_meta( $field->ID, 'pick_val', $params->name );
1991
                }
1992
            }
1993
1994
            $fields = pods_query( "
1995
                SELECT `p`.`ID`
1996
                FROM `{$wpdb->posts}` AS `p`
1997
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1998
                WHERE
1999
                    `p`.`post_type` = '_pods_field'
2000
                    AND `pm`.`meta_key` = 'pick_object'
2001
                    AND (
2002
                    	`pm`.`meta_value` = 'pod-{$old_name}'
2003
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "-{$old_name}'
2004
					)
2005
            " );
2006
2007 View Code Duplication
            if ( !empty( $fields ) ) {
2008
                foreach ( $fields as $field ) {
2009
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
2010
                    update_post_meta( $field->ID, 'pick_val', $params->name );
2011
                }
2012
            }
2013
        }
2014
2015
        // Sync built-in options for post types and taxonomies
2016
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) && $db ) {
2017
            // Build list of 'built_in' for later
2018
            $built_in = array();
2019
2020
            foreach ( $pod[ 'options' ] as $key => $val ) {
2021
                if ( false === strpos( $key, 'built_in_' ) )
2022
                    continue;
2023
                elseif ( false !== strpos( $key, 'built_in_post_types_' ) )
2024
                    $built_in_type = 'post_type';
2025
                elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) )
2026
                    $built_in_type = 'taxonomy';
2027
                else
2028
                    continue;
2029
2030
                if ( $built_in_type == $pod[ 'type' ] )
2031
                    continue;
2032
2033
                if ( !isset( $built_in[ $built_in_type ] ) )
2034
                    $built_in[ $built_in_type ] = array();
2035
2036
                $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key );
2037
2038
                $built_in[ $built_in_type ][ $built_in_object ] = (int) $val;
2039
            }
2040
2041
            $lookup_option = $lookup_built_in = false;
2042
2043
            $lookup_name = $pod[ 'name' ];
2044
2045
            if ( 'post_type' == $pod[ 'type' ] ) {
2046
                $lookup_option = 'built_in_post_types_' . $lookup_name;
2047
                $lookup_built_in = 'taxonomy';
2048
            }
2049
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
2050
                $lookup_option = 'built_in_taxonomies_' . $lookup_name;
2051
                $lookup_built_in = 'post_type';
2052
            }
2053
2054
            if ( !empty( $lookup_option ) && !empty( $lookup_built_in ) && isset( $built_in[ $lookup_built_in ] ) ) {
2055
                foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) {
2056
                    $search_val = 1;
2057
2058
                    if ( 1 == $val )
2059
                        $search_val = 0;
2060
2061
                    $query = "SELECT p.ID FROM {$wpdb->posts} AS p
2062
                                LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}'
2063
                                LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}'
2064
                                LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = ''
2065
                                WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}'
2066
                                    AND pm2.meta_id IS NOT NULL
2067
                                    AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )";
2068
2069
                    $results = pods_query( $query );
2070
2071
                    if ( !empty( $results ) ) {
2072
                        foreach ( $results as $the_pod ) {
2073
                            delete_post_meta( $the_pod->ID, $lookup_option );
2074
2075
                            add_post_meta( $the_pod->ID, $lookup_option, $val );
2076
                        }
2077
                    }
2078
                }
2079
            }
2080
        }
2081
2082
        $saved = array();
2083
        $errors = array();
2084
2085
        $field_index_change = false;
2086
        $field_index_id = 0;
2087
2088
        $id_required = false;
2089
2090
        $field_index = pods_var( 'pod_index', $pod[ 'options' ], 'id', null, true );
2091
2092
        if ( 'pod' == $pod[ 'type' ] && !empty( $pod[ 'fields' ] ) && isset( $pod[ 'fields' ][ $field_index ] ) )
2093
            $field_index_id = $pod[ 'fields' ][ $field_index ];
2094
2095
        if ( isset( $params->fields ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
2096
            $fields = array();
2097
2098
            if ( isset( $params->fields ) ) {
2099
                $params->fields = (array) $params->fields;
2100
2101
                $weight = 0;
2102
2103
                foreach ( $params->fields as $field ) {
2104
                    if ( !is_array( $field ) || !isset( $field[ 'name' ] ) )
2105
                        continue;
2106
2107
                    if ( !isset( $field[ 'weight' ] ) ) {
2108
                        $field[ 'weight' ] = $weight;
2109
2110
                        $weight++;
2111
                    }
2112
2113
                    $fields[ $field[ 'name' ] ] = $field;
2114
                }
2115
            }
2116
2117
            $weight = 0;
2118
2119
            $saved_field_ids = array();
2120
2121
            foreach ( $pod[ 'fields' ] as $k => $field ) {
2122
                if ( !empty( $old_id ) && ( !is_array( $field ) || !isset( $field[ 'name' ] ) || !isset( $fields[ $field[ 'name' ] ] ) ) ) {
2123
                    // Iterative change handling for setup-edit.php
2124
                    if ( !is_array( $field ) && isset( $old_fields[ $k ] ) )
2125
                        $saved[ $old_fields[ $k ][ 'name' ] ] = true;
2126
2127
                    continue;
2128
                }
2129
2130
                if ( !empty( $old_id ) )
2131
                    $field = array_merge( $field, $fields[ $field[ 'name' ] ] );
2132
2133
                $field[ 'pod' ] = $pod;
2134
2135
                if ( !isset( $field[ 'weight' ] ) ) {
2136
                    $field[ 'weight' ] = $weight;
2137
2138
                    $weight++;
2139
                }
2140
2141
                if ( 0 < $field_index_id && pods_var( 'id', $field ) == $field_index_id )
2142
                    $field_index_change = $field[ 'name' ];
2143
2144
                if ( 0 < pods_var( 'id', $field ) )
2145
                    $id_required = true;
2146
2147
                if ( $id_required )
2148
                    $field[ 'id_required' ] = true;
2149
2150
                $field_data = $field;
2151
2152
                $field = $this->save_field( $field_data, $field_table_operation, true, $db );
2153
2154
                if ( true !== $db ) {
2155
                    $pod[ 'fields' ][ $k ] = $field;
2156
                    $saved_field_ids[] = $field[ 'id' ];
2157
                }
2158
                else {
2159
                    if ( !empty( $field ) && 0 < $field ) {
2160
                        $saved[ $field_data[ 'name' ] ] = true;
2161
                        $saved_field_ids[] = $field;
2162
                    }
2163
                    else
2164
                        $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data[ 'name' ] );
2165
                }
2166
            }
2167
2168
            if ( true === $db ) {
2169
                foreach ( $old_fields as $field ) {
2170
                    if ( isset( $pod[ 'fields' ][ $field[ 'name' ] ] ) || isset( $saved[ $field[ 'name' ] ] ) || in_array( $field[ 'id' ], $saved_field_ids ) )
2171
                        continue;
2172
2173
                    if ( $field[ 'id' ] == $field_index_id )
2174
                        $field_index_change = 'id';
2175
                    elseif ( $field[ 'name' ] == $field_index )
2176
                        $field_index_change = 'id';
2177
2178
                    $this->delete_field( array(
2179
                        'id' => (int) $field[ 'id' ],
2180
                        'name' => $field[ 'name' ],
2181
                        'pod' => $pod
2182
                    ), $field_table_operation );
2183
                }
2184
            }
2185
2186
            // Update field index if the name has changed or the field has been removed
2187
            if ( false !== $field_index_change && true === $db )
2188
                update_post_meta( $pod[ 'id' ], 'pod_index', $field_index_change );
2189
        }
2190
2191
        if ( !empty( $errors ) )
2192
            return pods_error( $errors, $this );
2193
2194
        $this->cache_flush_pods( $pod );
2195
2196
		$refresh_pod = $this->load_pod( array( 'name' => $pod['name'] ), false );
2197
2198
		if ( $refresh_pod ) {
2199
			$pod = $refresh_pod;
2200
		}
2201
2202
		if ( 'post_type' == $pod['type'] ) {
2203
			PodsMeta::$post_types[ $pod['id'] ] = $pod;
2204
		} elseif ( 'taxonomy' == $pod['type'] ) {
2205
			PodsMeta::$taxonomies[ $pod['id'] ] = $pod;
2206
		} elseif ( 'media' == $pod['type'] ) {
2207
			PodsMeta::$media[ $pod['id'] ] = $pod;
2208
		} elseif ( 'user' == $pod['type'] ) {
2209
			PodsMeta::$user[ $pod['id'] ] = $pod;
2210
		} elseif ( 'comment' == $pod['type'] ) {
2211
			PodsMeta::$comment[ $pod['id'] ] = $pod;
2212
		}
2213
2214
        // Register Post Types / Taxonomies post-registration from PodsInit
2215
        if ( !empty( PodsInit::$content_types_registered ) && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) ) {
0 ignored issues
show
Bug introduced by
The property content_types_registered cannot be accessed from this context as it is declared private in class PodsInit.

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

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

Loading history...
2216
            global $pods_init;
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...
2217
2218
            $pods_init->setup_content_types( true );
2219
        }
2220
2221
        if ( true === $db )
2222
            return $pod[ 'id' ];
2223
        else
2224
            return $pod;
2225
    }
2226
2227
    /**
2228
     * Add or edit a field within a Pod
2229
     *
2230
     * $params['id'] int Field ID (id OR pod_id+pod+name required)
2231
     * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
2232
     * $params['pod'] string Pod name (id OR pod_id+pod+name required)
2233
     * $params['name'] string Field name (id OR pod_id+pod+name required)
2234
     * $params['label'] string (optional) Field label
2235
     * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email, file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg)
2236
     * $params['pick_object'] string (optional) Related Object (for relationships)
2237
     * $params['pick_val'] string (optional) Related Object name (for relationships)
2238
     * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
2239
     * $params['weight'] int (optional) Order in which the field appears
2240
     * $params['options'] array (optional) Options
2241
     *
2242
     * @param array $params An associative array of parameters
2243
     * @param bool $table_operation (optional) Whether or not to handle table operations
2244
     * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2245
     * @param bool|int $db (optional) Whether to save into the DB or just return field array.
2246
     *
2247
     * @return int|array The field ID or field array (if !$db)
2248
     * @since 1.7.9
2249
     */
2250
    public function save_field ( $params, $table_operation = true, $sanitized = false, $db = true ) {
2251
        /**
2252
         * @var $wpdb wpdb
2253
         */
2254
        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...
2255
2256
        if ( true !== $db )
2257
            $table_operation = false;
2258
2259
        $tableless_field_types = PodsForm::tableless_field_types();
2260
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
2261
2262
        $params = (object) $params;
2263
2264
        if ( false === $sanitized )
2265
            $params = pods_sanitize( $params );
2266
2267
        if ( isset( $params->pod_id ) )
2268
            $params->pod_id = pods_absint( $params->pod_id );
2269
2270
        if ( true !== $db )
2271
            $params->pod_id = (int) $db;
2272
2273
        $pod = null;
2274
        $save_pod = false;
2275
        $id_required = false;
2276
2277
        if ( isset( $params->id_required ) ) {
2278
            unset( $params->id_required );
2279
2280
            $id_required = true;
2281
        }
2282
2283 View Code Duplication
        if ( ( !isset( $params->pod ) || empty( $params->pod ) ) && ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) )
2284
            return pods_error( __( 'Pod ID or name is required', 'pods' ), $this );
2285
2286
        if ( isset( $params->pod ) && is_array( $params->pod ) ) {
2287
            $pod = $params->pod;
2288
2289
            $save_pod = true;
2290
        }
2291 View Code Duplication
        elseif ( ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) )
2292
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
2293 View Code Duplication
        elseif ( !isset( $params->pod ) && ( true === $db || 0 < $db ) )
2294
            $pod = $this->load_pod( array( 'id' => $params->pod_id, 'table_info' => true ) );
2295 View Code Duplication
        elseif ( true === $db || 0 < $db )
2296
            $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
2297
2298
        if ( empty( $pod ) && true === $db )
2299
            return pods_error( __( 'Pod not found', 'pods' ), $this );
2300
2301
        $params->pod_id = $pod[ 'id' ];
2302
        $params->pod = $pod[ 'name' ];
2303
        $params->pod_data = $pod;
2304
2305
        $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2306
2307
        if ( !isset( $params->id ) )
2308
            $params->id = 0;
2309
2310
        if ( empty( $params->name ) )
2311
            return pods_error( 'Pod field name is required', $this );
2312
2313
        $field = $this->load_field( $params );
2314
2315
        unset( $params->pod_data );
2316
2317
        $old_id = $old_name = $old_type = $old_definition = $old_simple = $old_options = $old_sister_id = null;
2318
2319
        if ( !empty( $field ) ) {
2320
            $old_id = pods_var( 'id', $field );
2321
            $old_name = pods_clean_name( $field[ 'name' ], true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2322
            $old_type = $field[ 'type' ];
2323
            $old_options = $field[ 'options' ];
2324
            $old_sister_id = (int) pods_var( 'sister_id', $old_options, 0 );
2325
2326
            $old_simple = ( 'pick' == $old_type && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
2327
2328
            if ( isset( $params->name ) && !empty( $params->name ) )
2329
                $field[ 'name' ] = $params->name;
2330
2331
            if ( $old_name != $field[ 'name' ] && false !== $this->field_exists( $params ) )
2332
                return pods_error( sprintf( __( 'Field %s already exists, you cannot rename %s to that', 'pods' ), $field[ 'name' ], $old_name ), $this );
2333
2334
            if ( ( $id_required || !empty( $params->id ) ) && ( empty( $old_id ) || $old_id != $params->id ) )
2335
                return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field[ 'name' ] ), $this );
2336
2337
            if ( empty( $params->id ) )
2338
                $params->id = $old_id;
2339
2340
            if ( !in_array( $old_type, $tableless_field_types ) || $old_simple ) {
2341
                $definition = $this->get_field_definition( $old_type, array_merge( $field, $old_options ) );
2342
2343
                if ( 0 < strlen( $definition ) )
2344
                    $old_definition = "`{$old_name}` " . $definition;
2345
            }
2346
        }
2347
        else {
2348
            $field = array(
2349
                'id' => 0,
2350
                'pod_id' => $params->pod_id,
2351
                'name' => $params->name,
2352
                'label' => $params->name,
2353
                'description' => '',
2354
                'type' => 'text',
2355
                'pick_object' => '',
2356
                'pick_val' => '',
2357
                'sister_id' => '',
2358
                'weight' => null,
2359
                'options' => array()
2360
            );
2361
        }
2362
2363
        // Setup options
2364
        $options = get_object_vars( $params );
2365
2366
        $options_ignore = array(
2367
            'method',
2368
            'table_info',
2369
            'attributes',
2370
            'group',
2371
            'grouped',
2372
            'developer_mode',
2373
            'dependency',
2374
            'depends-on',
2375
            'excludes-on'
2376
        );
2377
2378
        foreach ( $options_ignore as $ignore ) {
2379
            if ( isset( $options[ $ignore ] ) )
2380
                unset( $options[ $ignore ] );
2381
        }
2382
2383
        if ( isset( $options[ 'method' ] ) )
2384
            unset( $options[ 'method' ] );
2385
        elseif ( isset( $options[ 'table_info' ] ) )
2386
            unset( $options[ 'table_info' ] );
2387
2388
        $exclude = array(
2389
            'id',
2390
            'pod_id',
2391
            'pod',
2392
            'name',
2393
            'label',
2394
            'description',
2395
            'type',
2396
            'pick_object',
2397
            'pick_val',
2398
            'sister_id',
2399
            'weight',
2400
            'options'
2401
        );
2402
2403 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2404
            $aliases = array( $exclude_field );
2405
2406
            if ( is_array( $exclude_field ) ) {
2407
                $aliases = array_merge( array( $k ), $exclude_field );
2408
                $exclude_field = $k;
2409
            }
2410
2411
            foreach ( $aliases as $alias ) {
2412
                if ( isset( $options[ $alias ] ) ) {
2413
                    $field[ $exclude_field ] = pods_trim( $options[ $alias ] );
2414
2415
                    unset( $options[ $alias ] );
2416
                }
2417
            }
2418
        }
2419
2420
        if ( strlen( $field[ 'label' ] ) < 1 )
2421
            $field[ 'label' ] = $field[ 'name' ];
2422
2423
        $field[ 'options' ][ 'type' ] = $field[ 'type' ];
2424
2425
        if ( in_array( $field[ 'options' ][ 'type' ], $tableless_field_types ) ) {
2426
            // Clean up special drop-down in field editor and save out pick_val
2427
            $field[ 'pick_object' ] = pods_var( 'pick_object', $field, '', null, true );
2428
2429
            if ( 0 === strpos( $field[ 'pick_object' ], 'pod-' ) ) {
2430
                $field[ 'pick_val' ] = pods_str_replace( 'pod-', '', $field[ 'pick_object' ], 1 );
2431
                $field[ 'pick_object' ] = 'pod';
2432
            }
2433 View Code Duplication
            elseif ( 0 === strpos( $field[ 'pick_object' ], 'post_type-' ) ) {
2434
                $field[ 'pick_val' ] = pods_str_replace( 'post_type-', '', $field[ 'pick_object' ], 1 );
2435
                $field[ 'pick_object' ] = 'post_type';
2436
            }
2437 View Code Duplication
            elseif ( 0 === strpos( $field[ 'pick_object' ], 'taxonomy-' ) ) {
2438
                $field[ 'pick_val' ] = pods_str_replace( 'taxonomy-', '', $field[ 'pick_object' ], 1 );
2439
                $field[ 'pick_object' ] = 'taxonomy';
2440
            }
2441
            elseif ( 'table' == $field[ 'pick_object' ] && 0 < strlen( pods_var_raw( 'pick_table', $field[ 'options' ] ) ) ) {
2442
                $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_table' ];
2443
                $field[ 'pick_object' ] = 'table';
2444
            }
2445
            elseif ( false === strpos( $field[ 'pick_object' ], '-' ) && !in_array( $field[ 'pick_object' ], array( 'pod', 'post_type', 'taxonomy' ) ) ) {
2446
                $field[ 'pick_val' ] = '';
2447
			}
2448
			elseif ( 'custom-simple' == $field[ 'pick_object' ] ) {
2449
                $field[ 'pick_val' ] = '';
2450
			}
2451
2452
            $field[ 'options' ][ 'pick_object' ] = $field[ 'pick_object' ];
2453
            $field[ 'options' ][ 'pick_val' ] = $field[ 'pick_val' ];
2454
            $field[ 'options' ][ 'sister_id' ] = pods_var( 'sister_id', $field );
2455
2456
            unset( $field[ 'pick_object' ] );
2457
            unset( $field[ 'pick_val' ] );
2458
2459
            if ( isset( $field[ 'sister_id' ] ) )
2460
                unset( $field[ 'sister_id' ] );
2461
        }
2462
2463
        $field[ 'options' ] = array_merge( $field[ 'options' ], $options );
2464
2465
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
2466
2467
        if ( 0 < $old_id && defined( 'PODS_FIELD_STRICT' ) && !PODS_FIELD_STRICT )
2468
            $params->id = $field[ 'id' ] = $old_id;
2469
2470
        // Add new field
2471
        if ( !isset( $params->id ) || empty( $params->id ) || empty( $field ) ) {
2472
            if ( $table_operation && in_array( $field[ 'name' ], array( 'created', 'modified' ) ) && !in_array( $field[ 'type' ], array( 'date', 'datetime' ) ) && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2473
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2474
2475
            if ( $table_operation && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2476
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2477
2478 View Code Duplication
            if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) )
2479
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2480
2481
            foreach ( $object_fields as $object_field => $object_field_opt ) {
2482
                if ( $object_field == $field[ 'name' ] || in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2483
                    return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name. Also consider what WordPress and Pods provide you built-in.', 'pods' ), $field[ 'name' ] ), $this );
2484
            }
2485
2486
            if ( in_array( $field[ 'name' ], array( 'rss' ) ) ) // Reserved post_name values that can't be used as field names
2487
                $field[ 'name' ] .= '2';
2488
2489
            if ( 'slug' == $field[ 'type' ] && true === $db ) {
2490 View Code Duplication
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy', 'user' ) ) )
2491
                    return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this );
2492
2493
                $slug_field = get_posts( array(
2494
                    'post_type' => '_pods_field',
2495
                    'orderby' => 'menu_order',
2496
                    'order' => 'ASC',
2497
                    'posts_per_page' => 1,
2498
                    'post_parent' => $field[ 'pod_id' ],
2499
                    'meta_query' => array(
2500
                        array(
2501
                            'key' => 'type',
2502
                            'value' => 'slug'
2503
                        )
2504
                    )
2505
                ) );
2506
2507
                if ( !empty( $slug_field ) )
2508
                    return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this );
2509
            }
2510
2511
            // Sink the new field to the bottom of the list
2512
            if ( null === $field[ 'weight' ] ) {
2513
                $field[ 'weight' ] = 0;
2514
2515
                $bottom_most_field = get_posts( array(
2516
                    'post_type' => '_pods_field',
2517
                    'orderby' => 'menu_order',
2518
                    'order' => 'DESC',
2519
                    'posts_per_page' => 1,
2520
                    'post_parent' => $field[ 'pod_id' ]
2521
                ) );
2522
2523
                if ( !empty( $bottom_most_field ) )
2524
                    $field[ 'weight' ] = pods_absint( $bottom_most_field[ 0 ]->menu_order ) + 1;
2525
            }
2526
2527
            $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2528
2529
            $post_data = array(
2530
                'post_name' => $field[ 'name' ],
2531
                'post_title' => $field[ 'label' ],
2532
                'post_content' => $field[ 'description' ],
2533
                'post_type' => '_pods_field',
2534
                'post_parent' => $field[ 'pod_id' ],
2535
                'post_status' => 'publish',
2536
                'menu_order' => $field[ 'weight' ]
2537
            );
2538
        }
2539
        else {
2540
            if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) ) {
2541 View Code Duplication
                if ( null !== $old_name )
2542
                    return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2543
                else
2544
                    return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2545
            }
2546
2547
            if ( null !== $old_name && $field[ 'name' ] != $old_name && in_array( $field[ 'name' ], array( 'created', 'modified' ) ) && !in_array( $field[ 'type' ], array( 'date', 'datetime' ) ) && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2548
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2549
2550
            if ( null !== $old_name && $field[ 'name' ] != $old_name && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2551
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2552
2553
            foreach ( $object_fields as $object_field => $object_field_opt ) {
2554
                if ( $object_field != $field[ 'name' ] && !in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2555
                    continue;
2556
2557 View Code Duplication
                if ( null !== $old_name )
2558
                    return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2559
                else
2560
                    return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2561
            }
2562
2563
            $post_data = array(
2564
                'ID' => $field[ 'id' ],
2565
                'post_name' => $field[ 'name' ],
2566
                'post_title' => $field[ 'label' ],
2567
                'post_content' => $field[ 'description' ]
2568
            );
2569
2570
            if ( null !== $field[ 'weight' ] ) {
2571
                $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2572
2573
                $post_data[ 'menu_order' ] = $field[ 'weight' ];
2574
            }
2575
        }
2576
2577
        if ( true === $db ) {
2578
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
2579
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
2580
2581
            $conflicted = false;
2582
2583
            // Headway compatibility fix
2584
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
2585
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2586
2587
                $conflicted = true;
2588
            }
2589
2590
            // Store the old field name
2591
            if ( $old_name && $old_name != $post_data['post_name'] ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $old_name of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
2592
	            $field['options']['old_name'] = $old_name;
2593
            }
2594
2595
            $params->id = $this->save_wp_object( 'post', $post_data, $field[ 'options' ], true, true );
2596
2597
            if ( $conflicted )
2598
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2599
2600
            if ( false === $params->id )
2601
                return pods_error( __( 'Cannot save Field', 'pods' ), $this );
2602
        }
2603
        else
2604
            $params->id = $field[ 'name' ];
2605
2606
        $field[ 'id' ] = $params->id;
2607
2608
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field[ 'options' ] ), $simple_tableless_objects ) );
2609
2610
        $definition = false;
2611
2612
        if ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) {
2613
            $field_definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, $field[ 'options' ] ) );
2614
2615
            if ( 0 < strlen( $field_definition ) )
2616
                $definition = '`' . $field[ 'name' ] . '` ' . $field_definition;
2617
        }
2618
2619
        $sister_id = (int) pods_var( 'sister_id', $field[ 'options' ], 0 );
2620
2621
        if ( $table_operation && 'table' == $pod[ 'storage' ] && !pods_tableless() ) {
2622
            if ( !empty( $old_id ) ) {
2623
                if ( ( $field[ 'type' ] != $old_type || $old_simple != $simple ) && empty( $definition ) )
2624
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false );
2625
                elseif ( 0 < strlen( $definition ) ) {
2626
                    if ( $old_name != $field[ 'name' ] || $old_simple != $simple ) {
2627
                        $test = false;
2628
2629 View Code Duplication
                        if ( 0 < strlen( $old_definition ) )
2630
                            $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2631
2632
                        // If the old field doesn't exist, continue to add a new field
2633
                        if ( false === $test )
2634
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2635
                    }
2636
                    elseif ( null !== $old_definition && $definition != $old_definition ) {
2637
                        $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2638
2639
                        // If the old field doesn't exist, continue to add a new field
2640
                        if ( false === $test )
2641
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2642
                    }
2643
                }
2644
            }
2645
            elseif ( 0 < strlen( $definition ) ) {
2646
                $test = false;
2647
2648 View Code Duplication
                if ( 0 < strlen( $old_definition ) )
2649
                    $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `" . $field[ 'name' ] . "` {$definition}", false );
2650
2651
                // If the old field doesn't exist, continue to add a new field
2652
                if ( false === $test )
2653
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2654
            }
2655
        }
2656
2657
        if ( !empty( $old_id ) && 'meta' == $pod[ 'storage' ] && $old_name != $field[ 'name' ] && $pod[ 'meta_table' ] != $pod[ 'table' ] ) {
2658
            $prepare = array(
2659
                $field[ 'name' ],
2660
                $old_name
2661
            );
2662
2663
            // Users don't have a type
2664
            if ( !empty( $pod[ 'field_type' ] ) )
2665
                $prepare[] = $pod[ 'name' ];
2666
2667
            pods_query( "
2668
                UPDATE `{$pod[ 'meta_table' ]}` AS `m`
2669
                LEFT JOIN `{$pod[ 'table' ]}` AS `t`
2670
                    ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}`
2671
                SET
2672
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2673
                WHERE
2674
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2675
            " . ( !empty( $pod[ 'field_type' ] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ),
2676
                $prepare
2677
            );
2678
        }
2679
2680
        if ( $field[ 'type' ] != $old_type && in_array( $old_type, $tableless_field_types ) ) {
2681
            delete_post_meta( $old_sister_id, 'sister_id' );
2682
2683
            if ( true === $db ) {
2684
                pods_query( "
2685
                        DELETE pm
2686
                        FROM {$wpdb->postmeta} AS pm
2687
                        LEFT JOIN {$wpdb->posts} AS p
2688
                            ON p.post_type = '_pods_field'
2689
                            AND p.ID = pm.post_id
2690
                        WHERE
2691
                            p.ID IS NOT NULL
2692
                            AND pm.meta_key = 'sister_id'
2693
                            AND pm.meta_value = %d
2694
                    ", array(
2695
                        $params->id
2696
                    )
2697
                );
2698
2699
                if ( !pods_tableless() ) {
2700
                    pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false );
2701
2702
                    pods_query( "
2703
                            UPDATE `@wp_podsrel`
2704
                            SET `related_field_id` = 0
2705
                            WHERE `field_id` = %d
2706
                        ", array(
2707
                            $old_sister_id
2708
                        )
2709
                    );
2710
                }
2711
            }
2712
        }
2713 View Code Duplication
        elseif ( 0 < $sister_id ) {
2714
            update_post_meta( $sister_id, 'sister_id', $params->id );
2715
2716
            if ( true === $db && ( !pods_tableless() ) ) {
2717
                pods_query( "
2718
                        UPDATE `@wp_podsrel`
2719
                        SET `related_field_id` = %d
2720
                        WHERE `field_id` = %d
2721
                    ",
2722
                    array(
2723
                        $params->id,
2724
                        $sister_id
2725
                    )
2726
                );
2727
            }
2728
        }
2729 View Code Duplication
        elseif ( 0 < $old_sister_id ) {
2730
            delete_post_meta( $old_sister_id, 'sister_id' );
2731
2732
            if ( true === $db && ( !pods_tableless() ) ) {
2733
                pods_query( "
2734
                        UPDATE `@wp_podsrel`
2735
                        SET `related_field_id` = 0
2736
                        WHERE `field_id` = %d
2737
                    ", array(
2738
                        $old_sister_id
2739
                    )
2740
                );
2741
            }
2742
        }
2743
2744
        if ( !empty( $old_id ) && $old_name != $field[ 'name' ] && true === $db ) {
2745
            pods_query( "
2746
                    UPDATE `@wp_postmeta`
2747
                    SET `meta_value` = %s
2748
                    WHERE
2749
                        `post_id` = %d
2750
                        AND `meta_key` = 'pod_index'
2751
                        AND `meta_value` = %s
2752
                ", array(
2753
                    $field[ 'name' ],
2754
                    $pod[ 'id' ],
2755
                    $old_name
2756
                )
2757
            );
2758
        }
2759
2760
        if ( !$save_pod )
2761
            $this->cache_flush_pods( $pod );
2762
        else {
2763
            pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
2764
2765
            if ( !empty( $old_id ) && $old_name != $field[ 'name' ] )
2766
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $old_name );
2767
        }
2768
2769
        if ( true === $db )
2770
            return $params->id;
2771
        else
2772
            return $field;
2773
    }
2774
2775
    /**
2776
     * Fix Pod / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name)
2777
     *
2778
     * @param string $slug Unique slug value
2779
     * @param int $post_ID Post ID
2780
     * @param string $post_status Post Status
2781
     * @param string $post_type Post Type
2782
     * @param int $post_parent Post Parent ID
2783
     * @param string $original_slug Original slug value
2784
     *
2785
     * @return string Final slug value
2786
     *
2787
     * @since 2.3.3
2788
     */
2789
    public function save_slug_fix ( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) {
2790
        if ( in_array( $post_type, array( '_pods_field', '_pods_pod' ) ) && false !== strpos( $slug, '-' ) )
2791
            $slug = $original_slug;
2792
2793
        return $slug;
2794
    }
2795
2796
    /**
2797
     * Add or Edit a Pods Object
2798
     *
2799
     * $params['id'] int The Object ID
2800
     * $params['name'] string The Object name
2801
     * $params['type'] string The Object type
2802
     * $params['options'] Associative array of Object options
2803
     *
2804
     * @param array|object $params An associative array of parameters
2805
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
2806
     *
2807
     * @return int The Object ID
2808
     * @since 2.0
2809
     */
2810
    public function save_object ( $params, $sanitized = false ) {
2811
        $params = (object) $params;
2812
2813
        if ( false === $sanitized )
2814
            $params = pods_sanitize( $params );
2815
2816 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
2817
            return pods_error( __( 'Name must be given to save an Object', 'pods' ), $this );
2818
2819 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
2820
            return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this );
2821
2822
        $object = array(
2823
            'id' => 0,
2824
            'name' => $params->name,
2825
            'type' => $params->type,
2826
            'code' => '',
2827
            'options' => array()
2828
        );
2829
2830
        // Setup options
2831
        $options = get_object_vars( $params );
2832
2833
        if ( isset( $options[ 'method' ] ) )
2834
            unset( $options[ 'method' ] );
2835
2836
        $exclude = array(
2837
            'id',
2838
            'name',
2839
            'helper_type',
2840
            'code',
2841
            'options',
2842
            'status'
2843
        );
2844
2845 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2846
            $aliases = array( $exclude_field );
2847
2848
            if ( is_array( $exclude_field ) ) {
2849
                $aliases = array_merge( array( $k ), $exclude_field );
2850
                $exclude_field = $k;
2851
            }
2852
2853
            foreach ( $aliases as $alias ) {
2854
                if ( isset( $options[ $alias ] ) ) {
2855
                    $object[ $exclude_field ] = pods_trim( $options[ $alias ] );
2856
2857
                    unset( $options[ $alias ] );
2858
                }
2859
            }
2860
        }
2861
2862
        if ( 'helper' == $object[ 'type' ] )
2863
            $object[ 'options' ][ 'helper_type' ] = $object[ 'helper_type' ];
2864
2865
        if ( isset( $object[ 'options' ][ 'code' ] ) )
2866
            unset( $object[ 'options' ][ 'code' ] );
2867
2868
        $object[ 'options' ] = array_merge( $object[ 'options' ], $options );
2869
2870
        $post_data = array(
2871
            'post_name' => pods_clean_name( $object[ 'name' ], true),
2872
            'post_title' => $object[ 'name' ],
2873
            'post_content' => $object[ 'code' ],
2874
            'post_type' => '_pods_' . $object[ 'type' ],
2875
            'post_status' => 'publish'
2876
        );
2877
2878
        if ( !empty( $object[ 'id' ] ) )
2879
            $post_data[ 'ID' ] = $object[ 'id' ];
2880
2881
        if ( null !== pods_var( 'status', $object, null, null, true ) )
2882
            $post_data[ 'post_status' ] = pods_var( 'status', $object, null, null, true );
2883
2884
        remove_filter( 'content_save_pre', 'balanceTags', 50 );
2885
2886
        $post_data = pods_sanitize( $post_data );
2887
2888
        $params->id = $this->save_post( $post_data, $object[ 'options' ], true, true );
2889
2890
        pods_transient_clear( 'pods_objects_' . $params->type );
2891
        pods_transient_clear( 'pods_objects_' . $params->type . '_get' );
2892
2893
        return $params->id;
2894
    }
2895
2896
    /**
2897
     * @see PodsAPI::save_object
2898
     *
2899
     * Add or edit a Pod Template
2900
     *
2901
     * $params['id'] int The template ID
2902
     * $params['name'] string The template name
2903
     * $params['code'] string The template code
2904
     *
2905
     * @param array|object $params An associative array of parameters
2906
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2907
     *
2908
     * @return int The Template ID
2909
     *
2910
     * @since 1.7.9
2911
     */
2912
    public function save_template ( $params, $sanitized = false ) {
2913
        $params = (object) $params;
2914
2915
        $params->type = 'template';
2916
2917
        return $this->save_object( $params, $sanitized );
2918
    }
2919
2920
    /**
2921
     * @see PodsAPI::save_object
2922
     *
2923
     * Add or edit a Pod Page
2924
     *
2925
     * $params['id'] int The page ID
2926
     * $params['name'] string The page URI
2927
     * $params['code'] string The page code
2928
     *
2929
     * @param array|object $params An associative array of parameters
2930
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2931
     *
2932
     * @return int The page ID
2933
     * @since 1.7.9
2934
     */
2935
    public function save_page ( $params, $sanitized = false ) {
2936
        $params = (object) $params;
2937
2938
        if ( !isset( $params->name ) ) {
2939
            $params->name = $params->uri;
2940
            unset( $params->uri );
2941
        }
2942
2943
        if ( isset( $params->phpcode ) ) {
2944
            $params->code = $params->phpcode;
2945
            unset( $params->phpcode );
2946
        }
2947
2948
        $params->name = trim( $params->name, '/' );
2949
        $params->type = 'page';
2950
2951
        return $this->save_object( $params, $sanitized );
2952
    }
2953
2954
    /**
2955
     * @see PodsAPI::save_object
2956
     *
2957
     * Add or edit a Pod Helper
2958
     *
2959
     * $params['id'] int The helper ID
2960
     * $params['name'] string The helper name
2961
     * $params['helper_type'] string The helper type ("pre_save", "display", etc)
2962
     * $params['code'] string The helper code
2963
     *
2964
     * @param array $params An associative array of parameters
2965
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2966
     *
2967
     * @return int The helper ID
2968
     * @since 1.7.9
2969
     */
2970
    public function save_helper ( $params, $sanitized = false ) {
2971
        $params = (object) $params;
2972
2973
        if ( isset( $params->phpcode ) ) {
2974
            $params->code = $params->phpcode;
2975
            unset( $params->phpcode );
2976
        }
2977
2978
        if ( isset( $params->type ) ) {
2979
            $params->helper_type = $params->type;
2980
            unset( $params->type );
2981
        }
2982
2983
        $params->type = 'helper';
2984
2985
        return $this->save_object( $params, $sanitized );
2986
    }
2987
2988
    /**
2989
     * Add or edit a single pod item
2990
     *
2991
     * $params['pod'] string The Pod name (pod or pod_id is required)
2992
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
2993
     * $params['id'] int|array The item ID, or an array of item IDs to save data for
2994
     * $params['data'] array (optional) Associative array of field names + values
2995
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
2996
	 * $params['track_changed_fields'] bool Set to true to enable tracking of saved fields via PodsAPI::get_changed_fields()
2997
	 * $params['error_mode'] string Throw an 'exception', 'exit' with the message, return 'false', or return 'wp_error'
2998
     *
2999
     * @param array|object $params An associative array of parameters
3000
     *
3001
     * @return int|array The item ID, or an array of item IDs (if `id` is an array if IDs)
3002
     *
3003
     * @since 1.7.9
3004
     */
3005
    public function save_pod_item ( $params ) {
3006
3007
		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...
3008
3009
        $params = (object) pods_str_replace( '@wp_', '{prefix}', $params );
3010
3011
        $tableless_field_types = PodsForm::tableless_field_types();
3012
        $repeatable_field_types = PodsForm::repeatable_field_types();
3013
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
3014
3015
	    $error_mode = $this->display_errors;
3016
3017
	    if ( ! empty( $params->error_mode ) ) {
3018
		    $error_mode = $params->error_mode;
3019
	    }
3020
3021
        // @deprecated 2.0
3022
        if ( isset( $params->datatype ) ) {
3023
            pods_deprecated( '$params->pod instead of $params->datatype', '2.0' );
3024
3025
            $params->pod = $params->datatype;
3026
3027
            unset( $params->datatype );
3028
3029
            if ( isset( $params->pod_id ) ) {
3030
                pods_deprecated( '$params->id instead of $params->pod_id', '2.0' );
3031
3032
                $params->id = $params->pod_id;
3033
3034
                unset( $params->pod_id );
3035
            }
3036
3037
            if ( isset( $params->data ) && !empty( $params->data ) && is_array( $params->data ) ) {
3038
                $check = current( $params->data );
3039
3040
                if ( is_array( $check ) ) {
3041
                    pods_deprecated( 'PodsAPI::save_pod_items', '2.0' );
3042
3043
                    return $this->save_pod_items( $params, $params->data );
3044
                }
3045
            }
3046
        }
3047
3048
        // @deprecated 2.0
3049
        if ( isset( $params->tbl_row_id ) ) {
3050
            pods_deprecated( '$params->id instead of $params->tbl_row_id', '2.0' );
3051
3052
            $params->id = $params->tbl_row_id;
3053
3054
            unset( $params->tbl_row_id );
3055
        }
3056
3057
        // @deprecated 2.0
3058
        if ( isset( $params->columns ) ) {
3059
            pods_deprecated( '$params->data instead of $params->columns', '2.0' );
3060
3061
            $params->data = $params->columns;
3062
3063
            unset( $params->columns );
3064
        }
3065
3066
        if ( !isset( $params->pod ) )
3067
            $params->pod = false;
3068 View Code Duplication
        if ( isset( $params->pod_id ) )
3069
            $params->pod_id = pods_absint( $params->pod_id );
3070
        else
3071
            $params->pod_id = 0;
3072
3073 View Code Duplication
        if ( isset( $params->id ) )
3074
            $params->id = pods_absint( $params->id );
3075
        else
3076
            $params->id = 0;
3077
3078
        if ( !isset( $params->from ) )
3079
            $params->from = 'save';
3080
3081
        if ( !isset( $params->location ) )
3082
            $params->location = null;
3083
3084
        if ( !isset( $params->track_changed_fields ) )
3085
            $params->track_changed_fields = false;
3086
3087
		/**
3088
		 * Override $params['track_changed_fields']
3089
		 *
3090
		 * Use for globally setting field change tracking.
3091
		 *
3092
		 * @param bool
3093
		 *
3094
		 * @since 2.3.19
3095
		 */
3096
		$track_changed_fields = apply_filters( 'pods_api_save_pod_item_track_changed_fields_' . $params->pod, (boolean) $params->track_changed_fields, $params );
3097
3098
		$changed_fields = array();
3099
3100
		if ( !isset( $params->clear_slug_cache ) ) {
3101
			$params->clear_slug_cache = true;
3102
		}
3103
3104
        // Support for bulk edit
3105
        if ( isset( $params->id ) && !empty( $params->id ) && is_array( $params->id ) ) {
3106
            $ids = array();
3107
            $new_params = $params;
3108
3109
            foreach ( $params->id as $id ) {
3110
                $new_params->id = $id;
3111
3112
                $ids[] = $this->save_pod_item( $new_params );
3113
            }
3114
3115
            return $ids;
3116
        }
3117
3118
        // Allow Helpers to know what's going on, are we adding or saving?
3119
        $is_new_item = false;
3120
3121
        if ( empty( $params->id ) )
3122
            $is_new_item = true;
3123
3124
        if ( isset( $params->is_new_item ) )
3125
            $is_new_item = (boolean) $params->is_new_item;
3126
3127
        // Allow Helpers to bypass subsequent helpers in recursive save_pod_item calls
3128
        $bypass_helpers = false;
3129
3130
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
3131
            $bypass_helpers = true;
3132
3133
        // Allow Custom Fields not defined by Pods to be saved
3134
        $allow_custom_fields = false;
3135
3136
        if ( isset( $params->allow_custom_fields ) && false !== $params->allow_custom_fields )
3137
            $allow_custom_fields = true;
3138
3139
        // Get array of Pods
3140
        $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
3141
3142
        if ( false === $pod )
3143
            return pods_error( __( 'Pod not found', 'pods' ), $error_mode );
3144
3145
        $params->pod = $pod[ 'name' ];
3146
        $params->pod_id = $pod[ 'id' ];
3147
3148
        if ( 'settings' == $pod[ 'type' ] )
3149
            $params->id = $pod[ 'id' ];
3150
3151
        $fields = $pod[ 'fields' ];
3152
3153
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
3154
3155
        $fields_active = array();
3156
        $custom_data = array();
3157
3158
        // Find the active fields (loop through $params->data to retain order)
3159
        if ( !empty( $params->data ) && is_array( $params->data ) ) {
3160
            $custom_fields = array();
3161
3162
            foreach ( $params->data as $field => $value ) {
3163
                if ( isset( $object_fields[ $field ] ) ) {
3164
                    $object_fields[ $field ][ 'value' ] = $value;
3165
                    $fields_active[] = $field;
3166
                }
3167
                elseif ( isset( $fields[ $field ] ) ) {
3168
                    if ( 'save' == $params->from || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3169
                        $fields[ $field ][ 'value' ] = $value;
3170
                        $fields_active[] = $field;
3171
                    }
3172
                    elseif ( !pods_has_permissions( $fields[ $field ][ 'options' ] ) && pods_var( 'hidden', $fields[ $field ][ 'options' ], false ) ) {
3173
                        $fields[ $field ][ 'value' ] = $value;
3174
                        $fields_active[] = $field;
3175
                    }
3176
                }
3177
                else {
3178
                    $found = false;
3179
3180
                    foreach ( $object_fields as $object_field => $object_field_opt ) {
3181
                        if ( in_array( $field, $object_field_opt[ 'alias' ] ) ) {
3182
                            $object_fields[ $object_field ][ 'value' ] = $value;
3183
                            $fields_active[] = $object_field;
3184
3185
                            $found = true;
3186
3187
                            break;
3188
                        }
3189
                    }
3190
3191
                    if ( $allow_custom_fields && !$found )
3192
                        $custom_fields[] = $field;
3193
                }
3194
            }
3195
3196
            if ( $allow_custom_fields && !empty( $custom_fields ) ) {
3197
                foreach ( $custom_fields as $field ) {
3198
                    $custom_data[ $field ] = $params->data[ $field ];
3199
                }
3200
            }
3201
3202
           unset( $params->data );
3203
        }
3204
3205 View Code Duplication
		if ( empty( $params->id ) && !in_array( 'created', $fields_active ) && isset( $fields[ 'created' ] ) && in_array( $fields[ 'created' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3206
			$fields[ 'created' ][ 'value' ] = current_time( 'mysql' );
3207
			$fields_active[] = 'created';
3208
		}
3209
3210 View Code Duplication
		if ( !in_array( 'modified', $fields_active ) && isset( $fields[ 'modified' ] ) && in_array( $fields[ 'modified' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3211
			$fields[ 'modified' ][ 'value' ] = current_time( 'mysql' );
3212
			$fields_active[] = 'modified';
3213
		}
3214
3215
        if ( in_array( $pod[ 'type' ], array( 'pod', 'table' ) ) && empty( $params->id ) && !empty( $pod[ 'pod_field_index' ] ) && in_array( $pod[ 'pod_field_index' ], $fields_active ) && !in_array( $pod[ 'pod_field_slug' ], $fields_active ) && isset( $fields[ $pod[ 'pod_field_slug' ] ] ) ) {
3216
			$fields[ $pod[ 'pod_field_slug' ] ][ 'value' ] = ''; // this will get picked up by slug pre_save method
3217
			$fields_active[] = $pod[ 'pod_field_slug' ];
3218
        }
3219
3220
        // Handle hidden fields
3221
        if ( empty( $params->id ) ) {
3222
            foreach ( $fields as $field => $field_data ) {
3223
                if ( in_array( $field, $fields_active ) )
3224
                    continue;
3225
3226
                if ( in_array( $params->from, array( 'save', 'process_form' ) ) || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3227
                    $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3228
3229
                    if ( null !== $value && '' !== $value && false !== $value ) {
3230
                        $fields[ $field ][ 'value' ] = $value;
3231
                        $fields_active[] = $field;
3232
                    }
3233
                }
3234
            }
3235
3236
			// Set default field values for object fields
3237
			if ( !empty( $object_fields ) ) {
3238 View Code Duplication
				foreach ( $object_fields as $field => $field_data ) {
3239
					if ( in_array( $field, $fields_active ) ) {
3240
						continue;
3241
					}
3242
					elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3243
						continue;
3244
					}
3245
3246
                    $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3247
3248
                    if ( null !== $value && '' !== $value && false !== $value ) {
3249
                        $object_fields[ $field ][ 'value' ] = $value;
3250
                        $fields_active[] = $field;
3251
                    }
3252
				}
3253
			}
3254
3255
			// Set default field values for Pod fields
3256 View Code Duplication
			foreach ( $fields as $field => $field_data ) {
3257
				if ( in_array( $field, $fields_active ) ) {
3258
					continue;
3259
				}
3260
				elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3261
					continue;
3262
				}
3263
3264
				$value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3265
3266
				if ( null !== $value && '' !== $value && false !== $value ) {
3267
					$fields[ $field ][ 'value' ] = $value;
3268
					$fields_active[] = $field;
3269
				}
3270
			}
3271
        }
3272
3273
        $columns =& $fields; // @deprecated 2.0
3274
        $active_columns =& $fields_active; // @deprecated 2.0
3275
        $params->tbl_row_id =& $params->id; // @deprecated 2.0
3276
3277
        $pre_save_helpers = $post_save_helpers = array();
3278
3279
		$pieces = array(
3280
			'fields',
3281
			'params',
3282
			'pod',
3283
			'fields_active',
3284
			'object_fields',
3285
			'custom_fields',
3286
			'custom_data',
3287
			'track_changed_fields',
3288
			'changed_fields'
3289
		);
3290
3291
        if ( false === $bypass_helpers ) {
3292
            // Plugin hooks
3293
            $hooked = $this->do_hook( 'pre_save_pod_item', compact( $pieces ), $is_new_item, $params->id );
3294
3295
            if ( is_array( $hooked ) && !empty( $hooked ) )
3296
                extract( $hooked );
3297
3298
            $hooked = $this->do_hook( "pre_save_pod_item_{$params->pod}", compact( $pieces ), $is_new_item, $params->id );
3299
3300
            if ( is_array( $hooked ) && !empty( $hooked ) )
3301
                extract( $hooked );
3302
3303
            if ( $is_new_item ) {
3304
                $hooked = $this->do_hook( 'pre_create_pod_item', compact( $pieces ) );
3305
3306
                if ( is_array( $hooked ) && !empty( $hooked ) )
3307
                    extract( $hooked );
3308
3309
                $hooked = $this->do_hook( "pre_create_pod_item_{$params->pod}", compact( $pieces ) );
3310
3311
                if ( is_array( $hooked ) && !empty( $hooked ) )
3312
                    extract( $hooked );
3313
            }
3314
            else {
3315
                $hooked = $this->do_hook( 'pre_edit_pod_item', compact( $pieces ), $params->id );
3316
3317
                if ( is_array( $hooked ) && !empty( $hooked ) )
3318
                    extract( $hooked );
3319
3320
                $hooked = $this->do_hook( "pre_edit_pod_item_{$params->pod}", compact( $pieces ), $params->id );
3321
3322
                if ( is_array( $hooked ) && !empty( $hooked ) )
3323
                    extract( $hooked );
3324
            }
3325
3326
            // Call any pre-save helpers (if not bypassed)
3327 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3328
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
3329
                    $helpers = array( 'pre_save_helpers', 'post_save_helpers' );
3330
3331
                    foreach ( $helpers as $helper ) {
3332
                        if ( isset( $pod[ 'options' ][ $helper ] ) && !empty( $pod[ 'options' ][ $helper ] ) )
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
3333
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
3334
                    }
3335
                }
3336
3337
                if ( !empty( $pre_save_helpers ) ) {
3338
                    pods_deprecated( sprintf( __( 'Pre-save helpers are deprecated, use the action pods_pre_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3339
3340
                    foreach ( $pre_save_helpers as $helper ) {
3341
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3342
3343
                        if ( false !== $helper )
3344
                            eval( '?>' . $helper[ 'code' ] );
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
3345
                    }
3346
                }
3347
            }
3348
        }
3349
3350
		if ( $track_changed_fields ) {
3351
			$changed_fields = $this->get_changed_fields( compact( $pieces ) );
3352
		}
3353
3354
        $table_data = $table_formats = $update_values = $rel_fields = $rel_field_ids = array();
3355
3356
        $object_type = $pod[ 'type' ];
3357
3358
        $object_ID = 'ID';
3359
3360
        if ( 'comment' == $object_type )
3361
            $object_ID = 'comment_ID';
3362
        elseif ( 'taxonomy' == $object_type )
3363
            $object_ID = 'term_id';
3364
3365
        $object_data = $object_meta = $post_term_data = array();
3366
3367
        if ( 'settings' == $object_type )
3368
            $object_data[ 'option_id' ] = $pod[ 'name' ];
3369
        elseif ( !empty( $params->id ) )
3370
            $object_data[ $object_ID ] = $params->id;
3371
3372
        $fields_active = array_unique( $fields_active );
3373
3374
        // Loop through each active field, validating and preparing the table data
3375
        foreach ( $fields_active as $field ) {
3376 View Code Duplication
            if ( isset( $object_fields[ $field ] ) )
3377
                $field_data = $object_fields[ $field ];
3378
            elseif ( isset( $fields[ $field ] ) )
3379
                $field_data = $fields[ $field ];
3380
            else
3381
                continue;
3382
3383
            $value = $field_data[ 'value' ];
3384
            $type = $field_data[ 'type' ];
3385
            $options = pods_var( 'options', $field_data, array() );
3386
3387
            // WPML AJAX compatibility
3388
            if ( is_admin() && isset( $_GET[ 'page' ] ) && false !== strpos( $_GET[ 'page' ], '/menu/languages.php' ) && isset( $_POST[ 'icl_ajx_action' ] ) && isset( $_POST[ '_icl_nonce' ] ) && wp_verify_nonce( $_POST[ '_icl_nonce' ], $_POST[ 'icl_ajx_action' ] . '_nonce' ) )
3389
                $options[ 'unique' ] = $fields[ $field ][ 'options' ][ 'unique' ] = $options[ 'required' ] = $fields[ $field ][ 'options' ][ 'required' ] = 0;
3390
            else {
3391
                // Validate value
3392
                $validate = $this->handle_field_validation( $value, $field, $object_fields, $fields, $pod, $params );
3393
3394
                if ( false === $validate )
3395
                    $validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field_data[ 'label' ] );
3396
                elseif ( true !== $validate )
3397
                    $validate = (array) $validate;
3398
3399
                if ( !is_bool( $validate ) && !empty( $validate ) )
3400
                    return pods_error( $validate, $error_mode );
3401
            }
3402
3403
            $value = PodsForm::pre_save( $field_data[ 'type' ], $value, $params->id, $field, array_merge( $field_data, $options ), array_merge( $fields, $object_fields ), $pod, $params );
3404
3405
            $field_data[ 'value' ] = $value;
3406
3407
            if ( isset( $object_fields[ $field ] ) ) {
3408
				if ( 'taxonomy' == $object_fields[ $field ][ 'type' ] ) {
3409
					$post_term_data[ $field ] = $value;
3410
				}
3411
				else {
3412
                	$object_data[ $field ] = $value;
3413
				}
3414
			}
3415
            else {
3416
                $simple = ( 'pick' == $type && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
3417
                $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field_data, $field, $fields, $pod, $params );
3418
3419
                // Handle Simple Relationships
3420
                if ( $simple ) {
3421
                    if ( !is_array( $value ) )
3422
                        $value = explode( ',', $value );
3423
3424
                    $pick_limit = (int) pods_var_raw( 'pick_limit', $options, 0 );
3425
3426
                    if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
3427
                        $pick_limit = 1;
3428
3429
                    if ( 'custom-simple' == pods_var( 'pick_object', $field_data ) ) {
3430
                        $custom = pods_var_raw( 'pick_custom', $options, '' );
3431
3432
                        $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data[ 'name' ], $value, array_merge( $field_data, $options ), $pod, $params->id );
3433
3434
                        if ( empty( $value ) || empty( $custom ) )
3435
                            $value = '';
3436
                        elseif ( !empty( $custom ) ) {
3437
                            if ( !is_array( $custom ) ) {
3438
                                $custom = explode( "\n", $custom );
3439
3440
                                $custom_values = array();
3441
3442
                                foreach ( $custom as $c => $cv ) {
3443
                                    if ( 0 < strlen( $cv ) ) {
3444
                                        $custom_label = explode( '|', $cv );
3445
3446
                                        if ( !isset( $custom_label[ 1 ] ) )
3447
                                            $custom_label[ 1 ] = $custom_label[ 0 ];
3448
3449
                                        $custom_label[ 0 ] = trim( (string) $custom_label[ 0 ] );
3450
                                        $custom_label[ 1 ] = trim( (string) $custom_label[ 1 ] );
3451
                                        $custom_values[ $custom_label[ 0 ] ] = $custom_label[ 1 ];
3452
                                    }
3453
                                }
3454
                            }
3455
                            else
3456
                                $custom_values = $custom;
3457
3458
                            $values = array();
3459
3460
                            foreach ( $value as $k => $v ) {
3461
                                $v = pods_unsanitize( $v );
3462
3463
                                if ( isset( $custom_values[ $v ] ) )
3464
                                    $values[ $k ] = $v;
3465
                            }
3466
3467
                            $value = $values;
3468
                        }
3469
                    }
3470
3471
                    if ( 0 < $pick_limit && !empty( $value ) )
3472
                        $value = array_slice( $value, 0, $pick_limit );
3473
3474
                    // Don't save an empty array, just make it an empty string
3475 View Code Duplication
                    if ( empty( $value ) )
3476
                        $value = '';
3477
                    elseif ( is_array( $value ) ) {
3478
                        // If there's just one item, don't save as an array, save the string
3479
                        if ( 1 == $pick_limit || 1 == count( $value ) )
3480
                            $value = implode( '', $value );
3481
                        // If storage is set to table, json encode, otherwise WP will serialize automatically
3482
                        elseif ( 'table' == pods_var( 'storage', $pod ) )
3483
                            $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

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

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

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

Loading history...
3484
                    }
3485
                }
3486
3487
                // Prepare all table / meta data
3488
                if ( !in_array( $type, $tableless_field_types ) || $simple ) {
3489
                    if ( in_array( $type, $repeatable_field_types ) && 1 == pods_var( $type . '_repeatable', $field_data, 0 ) ) {
3490
                        // Don't save an empty array, just make it an empty string
3491 View Code Duplication
                        if ( empty( $value ) )
3492
                            $value = '';
3493
                        elseif ( is_array( $value ) ) {
3494
                            // If there's just one item, don't save as an array, save the string
3495
                            if ( 1 == count( $value ) )
3496
                                $value = implode( '', $value );
3497
                            // If storage is set to table, json encode, otherwise WP will serialize automatically
3498
                            elseif ( 'table' == pods_var( 'storage', $pod ) )
3499
                                $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

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

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

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

Loading history...
3500
                        }
3501
                    }
3502
3503
                    $table_data[ $field ] = str_replace( array( '{prefix}', '@wp_' ), array( '{/prefix/}', '{prefix}' ), $value ); // Fix for pods_query
3504
                    $table_formats[] = PodsForm::prepare( $type, $options );
3505
3506
                    $object_meta[ $field ] = $value;
3507
                }
3508
                // Store relational field data to be looped through later
3509
                else {
3510
                    // Convert values from a comma-separated string into an array
3511
                    if ( !is_array( $value ) )
3512
                        $value = explode( ',', $value );
3513
3514
                    $rel_fields[ $type ][ $field ] = $value;
3515
                    $rel_field_ids[] = $field_data[ 'id' ];
3516
                }
3517
            }
3518
        }
3519
3520
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) ) {
3521
            $object_name = $pod[ 'name' ];
3522
3523
            if ( !empty( $pod[ 'object' ] ) )
3524
                $object_name = $pod[ 'object' ];
3525
3526
            $object_name_field = 'post_type';
3527
3528
            if ( 'taxonomy' == $pod['type'] ) {
3529
                $object_name_field = 'taxonomy';
3530
            }
3531
3532
            $object_data[ $object_name_field ] = $object_name;
3533
        }
3534
3535
        if ( ( 'meta' == $pod[ 'storage' ] || 'settings' == $pod[ 'type' ] || ( 'taxonomy' == $pod[ 'type' ] && 'none' == $pod[ 'storage' ] ) ) && !in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3536
            if ( $allow_custom_fields && !empty( $custom_data ) )
3537
                $object_meta = array_merge( $custom_data, $object_meta );
3538
3539
			$fields_to_send = array_flip( array_keys( $object_meta ) );
3540
3541
			foreach ( $fields_to_send as $field => $field_data ) {
3542 View Code Duplication
				if ( isset( $object_fields[ $field ] ) ) {
3543
					$field_data = $object_fields[ $field ];
3544
				}
3545
				elseif ( isset( $fields[ $field ] ) ) {
3546
					$field_data = $fields[ $field ];
3547
				}
3548
				else {
3549
					unset( $fields_to_send[ $field ] );
3550
				}
3551
3552
				$fields_to_send[ $field ] = $field_data;
3553
			}
3554
3555
            $params->id = $this->save_wp_object( $object_type, $object_data, $object_meta, false, true, $fields_to_send );
3556
3557
            if ( !empty( $params->id ) && 'settings' == $object_type )
3558
                $params->id = $pod[ 'id' ];
3559
        }
3560
        else {
3561
            if ( ! in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3562
                $params->id = $this->save_wp_object( $object_type, $object_data, array(), false, true );
3563
            }
3564
3565
            if ( 'table' == $pod[ 'storage' ] ) {
3566
                // Every row should have an id set here, otherwise Pods with nothing
3567
                // but relationship fields won't get properly ID'd
3568
                if ( empty( $params->id ) )
3569
                    $params->id = 0;
3570
3571
                $table_data = array( 'id' => $params->id ) + $table_data;
3572
                array_unshift( $table_formats, '%d' );
3573
3574
                if ( !empty( $table_data ) ) {
3575
                    $sql = pods_data()->insert_on_duplicate( "@wp_pods_{$params->pod}", $table_data, $table_formats );
3576
3577
                    $id = pods_query( $sql, 'Cannot add/save table row' );
3578
3579
                    if ( empty( $params->id ) )
3580
                        $params->id = $id;
3581
                }
3582
            }
3583
        }
3584
3585
        $params->id = (int) $params->id;
3586
3587
		// Save terms for taxonomies associated to a post type
3588
        if ( 0 < $params->id && 'post_type' == $pod[ 'type' ] && !empty( $post_term_data ) ) {
3589
			foreach ( $post_term_data as $post_taxonomy => $post_terms ) {
3590
                $post_terms = (array) $post_terms;
3591
3592
                foreach ( $post_terms as $k => $v ) {
3593
                    if ( ! preg_match( '/[^0-9]/', $v ) ) {
3594
                        $v = (int) $v;
3595
                    }
3596
3597
                    $post_terms[ $k ] = $v;
3598
                }
3599
3600
				wp_set_object_terms( $params->id, $post_terms, $post_taxonomy );
3601
			}
3602
		}
3603
3604
        $no_conflict = pods_no_conflict_check( $pod[ 'type' ] );
3605
3606
        if ( !$no_conflict )
3607
            pods_no_conflict_on( $pod[ 'type' ] );
3608
3609
        // Save relationship / file data
3610
        if ( !empty( $rel_fields ) ) {
3611
            foreach ( $rel_fields as $type => $data ) {
3612
                // Only handle tableless fields
3613
                if ( !in_array( $type, $tableless_field_types ) ) {
3614
                    continue;
3615
				}
3616
3617
                foreach ( $data as $field => $values ) {
3618
                    $pick_val = pods_var( 'pick_val', $fields[ $field ] );
3619
3620
                    if ( 'table' == pods_var( 'pick_object', $fields[ $field ] ) ) {
3621
                        $pick_val = pods_var( 'pick_table', $fields[ $field ][ 'options' ], $pick_val, null, true );
3622
					}
3623
3624 View Code Duplication
                    if ( '__current__' == $pick_val ) {
3625
                        if ( is_object( $pod ) ) {
3626
                            $pick_val = $pod->pod;
3627
						}
3628
                        elseif ( is_array( $pod ) ) {
3629
                            $pick_val = $pod[ 'name' ];
3630
						}
3631
                        elseif ( 0 < strlen( $pod ) ) {
3632
                            $pick_val = $pod;
3633
						}
3634
                    }
3635
3636
                    $fields[ $field ][ 'options' ][ 'table_info' ] = pods_api()->get_table_info( pods_var( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ][ 'options' ] );
3637
3638
                    if ( isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && !empty( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] ) ) {
3639
						$search_data = pods( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] );
3640
3641
						$data_mode = 'pods';
3642
                    }
3643
					else {
3644
						$search_data = pods_data();
3645
						$search_data->table( $fields[ $field ][ 'options' ][ 'table_info' ] );
3646
3647
						$data_mode = 'data';
3648
					}
3649
3650
					$find_rel_params = array(
3651
						'select' => "`t`.`{$search_data->field_id}`",
3652
						'where' => "`t`.`{$search_data->field_slug}` = %s OR `t`.`{$search_data->field_index}` = %s",
3653
						'limit' => 1,
3654
						'pagination' => false,
3655
						'search' => false
3656
					);
3657
3658
					if ( empty( $search_data->field_slug ) && !empty( $search_data->field_index ) ) {
3659
						$find_rel_params[ 'where' ] = "`t`.`{$search_data->field_index}` = %s";
3660
					}
3661
					elseif ( empty( $search_data->field_slug ) && empty( $search_data->field_index ) ) {
3662
						$find_rel_params = false;
3663
					}
3664
3665
                    $related_limit = (int) pods_var_raw( $type . '_limit', $fields[ $field ][ 'options' ], 0 );
3666
3667 View Code Duplication
                    if ( 'single' == pods_var_raw( $type . '_format_type', $fields[ $field ][ 'options' ] ) ) {
3668
                        $related_limit = 1;
3669
					}
3670
3671
                    // Enforce integers / unique values for IDs
3672
                    $value_ids = array();
3673
3674
					$is_file_field = in_array( $type, PodsForm::file_field_types() );
3675
					$is_taggable = ( in_array( $type, PodsForm::tableless_field_types() ) && 1 == pods_v( $type . '_taggable', $fields[ $field ][ 'options' ] ) );
3676
3677
					// @todo Handle simple relationships eventually
3678
                    foreach ( $values as $v ) {
3679
                        if ( !empty( $v ) ) {
3680
							if ( !is_array( $v ) ) {
3681
								if ( !preg_match( '/[^0-9]/', $v ) ) {
3682
									$v = (int) $v;
3683
								}
3684
								// File handling
3685
								elseif ( $is_file_field ) {
3686
									// Get ID from GUID
3687
									$v = pods_image_id_from_field( $v );
3688
3689
									// If file not found, add it
3690
									if ( empty( $v ) ) {
3691
										$v = pods_attachment_import( $v );
3692
									}
3693
								}
3694
								// Reference by slug
3695
								else {
3696
									$v_data = false;
3697
3698
									if ( false !== $find_rel_params ) {
3699
										$rel_params = $find_rel_params;
3700
										$rel_params[ 'where' ] = $wpdb->prepare( $rel_params[ 'where' ], array( $v, $v ) );
3701
3702
										$search_data->select( $rel_params );
0 ignored issues
show
Bug introduced by
The method select does only exist in PodsData, but not in Pods.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
3703
3704
										$v_data = $search_data->fetch( $v );
3705
									}
3706
3707
									if ( !empty( $v_data ) && isset( $v_data[ $search_data->field_id ] ) ) {
3708
										$v = (int) $v_data[ $search_data->field_id ];
3709
									}
3710
									// Allow tagging for Pods objects
3711
									elseif ( $is_taggable && 'pods' == $data_mode ) {
3712
										$tag_data = array(
3713
											$search_data->field_index => $v
3714
										);
3715
3716
										if ( 'post_type' == $search_data->pod_data[ 'type' ] ) {
3717
											$tag_data[ 'post_status' ] = 'publish';
3718
										}
3719
3720
										/**
3721
										 * Filter for changing tag before adding new item.
3722
										 *
3723
										 * @param array $tag_data Fields for creating new item.
3724
										 * @param int $v Field ID of tag.
3725
										 * @param obj $search_data Search object for tag.
3726
										 * @param string $field Table info for field.
3727
										 * @param array	$pieces Field array.
3728
										 *
3729
										 * @since 2.3.19
3730
										 */
3731
										$tag_data = apply_filters( 'pods_api_save_pod_item_taggable_data', $tag_data, $v, $search_data, $field, compact( $pieces ) );
3732
3733
										// Save $v to a new item on related object
3734
										$v = $search_data->add( $tag_data );
0 ignored issues
show
Bug introduced by
The method add does only exist in Pods, but not in PodsData.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
3735
3736
										// @todo Support non-Pods for tagging
3737
									}
3738
								}
3739
							}
3740
							elseif ( $is_file_field && isset( $v[ 'id' ] ) ) {
3741
								$v = (int) $v[ 'id' ];
3742
							}
3743
							else {
3744
								continue;
3745
							}
3746
3747
							if ( !empty( $v ) && !in_array( $v, $value_ids ) ) {
3748
								$value_ids[] = $v;
3749
							}
3750
                        }
3751
                    }
3752
3753
                    $value_ids = array_unique( array_filter( $value_ids ) );
3754
3755
                    // Limit values
3756
                    if ( 0 < $related_limit && !empty( $value_ids ) )
3757
                        $value_ids = array_slice( $value_ids, 0, $related_limit );
3758
3759
                    // Get current values
3760
                    if ( 'pick' == $type && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ] ) )
3761
                        $related_ids = PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ];
3762
                    else
3763
                        $related_ids = $this->lookup_related_items( $fields[ $field ][ 'id' ], $pod[ 'id' ], $params->id, $fields[ $field ], $pod );
3764
3765
                    // Get ids to remove
3766
                    $remove_ids = array_diff( $related_ids, $value_ids );
3767
3768
                    // Delete relationships
3769
                    if ( !empty( $remove_ids ) )
3770
                        $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] );
3771
3772
                    // Save relationships
3773
                    if ( !empty( $value_ids ) )
3774
                        $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] );
3775
3776
                    // Run save function for field type (where needed)
3777
                    PodsForm::save( $type, $value_ids, $params->id, $field, array_merge( $fields[ $field ], $fields[ $field ][ 'options' ] ), array_merge( $fields, $object_fields ), $pod, $params );
3778
                }
3779
3780
                // Unset data no longer needed
3781
                if ( 'pick' == $type ) {
3782
                    foreach ( $data as $field => $values ) {
3783
                        if ( isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) ) {
3784
                            unset( PodsField_Pick::$related_data[ PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'related_field' ][ 'id' ] ] );
3785
                            unset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] );
3786
                        }
3787
                    }
3788
                }
3789
            }
3790
        }
3791
3792
        if ( !$no_conflict )
3793
            pods_no_conflict_off( $pod[ 'type' ] );
3794
3795
        // Clear cache
3796
        pods_cache_clear( $params->id, 'pods_items_' . $pod[ 'name' ] );
3797
3798
		if ( $params->clear_slug_cache && !empty( $pod[ 'field_slug' ] ) ) {
3799
			$slug = pods( $pod[ 'name' ], $params->id )->field( $pod[ 'field_slug' ] );
3800
3801
			if ( 0 < strlen( $slug ) ) {
3802
        		pods_cache_clear( $slug, 'pods_items_' . $pod[ 'name' ] );
3803
			}
3804
		}
3805
3806
        // Clear WP meta cache
3807
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3808
            $meta_type = $pod[ 'type' ];
3809
3810
            if ( 'post_type' == $meta_type )
3811
                $meta_type = 'post';
3812
3813
            wp_cache_delete( $params->id, $meta_type . '_meta' );
3814
            wp_cache_delete( $params->id, 'pods_' . $meta_type . '_meta' );
3815
        }
3816
3817
        if ( false === $bypass_helpers ) {
3818
            $pieces = compact( $pieces );
3819
3820
            // Plugin hooks
3821
            $this->do_hook( 'post_save_pod_item', $pieces, $is_new_item, $params->id );
3822
            $this->do_hook( "post_save_pod_item_{$params->pod}", $pieces, $is_new_item, $params->id );
3823
3824
            if ( $is_new_item ) {
3825
                $this->do_hook( 'post_create_pod_item', $pieces, $params->id );
3826
                $this->do_hook( "post_create_pod_item_{$params->pod}", $pieces, $params->id );
3827
            }
3828
            else {
3829
                $this->do_hook( 'post_edit_pod_item', $pieces, $params->id );
3830
                $this->do_hook( "post_edit_pod_item_{$params->pod}", $pieces, $params->id );
3831
            }
3832
3833
            // Call any post-save helpers (if not bypassed)
3834
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3835 View Code Duplication
                if ( !empty( $post_save_helpers ) ) {
3836
                    pods_deprecated( sprintf( __( 'Post-save helpers are deprecated, use the action pods_post_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3837
3838
                    foreach ( $post_save_helpers as $helper ) {
3839
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3840
3841
                        if ( false !== $helper && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
3842
                            eval( '?>' . $helper[ 'code' ] );
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
3843
                    }
3844
                }
3845
            }
3846
        }
3847
3848
        // Success! Return the id
3849
        return $params->id;
3850
3851
    }
3852
3853
    /**
3854
     * @see PodsAPI::save_pod_item
3855
     * Add multiple pod items
3856
     *
3857
     * $params['pod'] string The Pod name (pod or pod_id is required)
3858
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
3859
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
3860
     *
3861
     * $data['id'] int The item ID (optional)
3862
     * $data['data'] array An associative array of field names + values
3863
     *
3864
     * @param array|object $params An associative array of parameters, data excluded
3865
     * @param array $data An associative array of pod ids and field names + values (arrays of field data)
3866
     *
3867
     * @return int The item ID
3868
     * @since 2.0
3869
     */
3870
    public function save_pod_items ( $params, $data ) {
3871
        $params = (object) $params;
3872
3873
        $ids = array();
3874
3875
        foreach ( $data as $fields ) {
3876
            $params->data = $fields;
3877
3878
            if ( isset( $fields[ 'id' ] ) && isset( $fields[ 'data' ] ) ) {
3879
                $params->id = $fields[ 'id' ];
3880
                $params->data = $fields[ 'data' ];
3881
            }
3882
3883
            $ids[] = $this->save_pod_item( $params );
3884
        }
3885
3886
        return $ids;
3887
    }
3888
3889
	/**
3890
	 * Get the fields that have changed during a save
3891
	 *
3892
	 * @param array $pieces Pieces array from save_pod_item
3893
	 *
3894
	 * @return array Array of fields and values that have changed
3895
	 */
3896
	public function get_changed_fields( $pieces ) {
3897
3898
		$fields = $pieces[ 'fields' ];
3899
		$fields_active = $pieces[ 'fields_active' ];
3900
3901
		$fields_changed = array();
3902
3903
		if ( 0 < $pieces[ 'params' ]->id ) {
3904
			$pod = pods( $pieces[ 'params' ]->pod, $pieces[ 'params' ]->id );
3905
3906
			foreach ( $fields_active as $field ) {
3907
				if ( isset( $fields[ $field ] ) && $pod->raw( $field ) != $fields[ $field ][ 'value' ] ) {
3908
					$fields_changed[ $field ] = $fields[ $field ][ 'value' ];
3909
				}
3910
			}
3911
		}
3912
3913
		return $fields_changed;
3914
3915
	}
3916
3917
    /**
3918
     * Save relationships
3919
     *
3920
     * @param int $id ID of item
3921
     * @param int|array $related_id ID or IDs to save
0 ignored issues
show
Documentation introduced by
There is no parameter named $related_id. Did you maybe mean $related_ids?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
3922
     * @param array $pod Pod data
3923
     * @param array $field Field data
3924
     */
3925
    public function save_relationships ( $id, $related_ids, $pod, $field ) {
3926
        // Get current values
3927
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ] ) )
3928
            $current_ids = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ];
3929
        else
3930
            $current_ids = $this->lookup_related_items( $field[ 'id' ], $pod[ 'id' ], $id, $field, $pod );
3931
3932
	    if ( isset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] ) ) {
3933
		    // Delete relationship from cache
3934
		    unset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] );
3935
	    }
3936
3937
        if ( !is_array( $related_ids ) )
3938
            $related_ids = implode( ',', $related_ids );
3939
3940
        foreach ( $related_ids as $k => $related_id ) {
0 ignored issues
show
Bug introduced by
The expression $related_ids of type string|array 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...
3941
            $related_ids[ $k ] = (int) $related_id;
3942
        }
3943
3944
        $related_ids = array_unique( array_filter( $related_ids ) );
3945
3946
        $related_limit = (int) pods_var_raw( $field[ 'type' ] . '_limit', $field[ 'options' ], 0 );
3947
3948 View Code Duplication
        if ( 'single' == pods_var_raw( $field[ 'type' ] . '_format_type', $field[ 'options' ] ) )
3949
            $related_limit = 1;
3950
3951
        // Limit values
3952
        if ( 0 < $related_limit && !empty( $related_ids ) )
3953
            $related_ids = array_slice( $related_ids, 0, $related_limit );
3954
3955
        // Post Types, Media, Users, and Comments (meta-based)
3956 View Code Duplication
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3957
            $object_type = $pod[ 'type' ];
3958
3959
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
3960
                $object_type = 'post';
3961
            elseif ( 'taxonomy' == $object_type )
3962
                $object_type = 'term';
3963
3964
            delete_metadata( $object_type, $id, $field[ 'name' ] );
3965
3966
            if ( !empty( $related_ids ) ) {
3967
                update_metadata( $object_type, $id, '_pods_' . $field[ 'name' ], $related_ids );
3968
3969
                foreach ( $related_ids as $related_id ) {
3970
                    add_metadata( $object_type, $id, $field[ 'name' ], $related_id );
3971
                }
3972
            }
3973
            else
3974
                delete_metadata( $object_type, $id, '_pods_' . $field[ 'name' ] );
3975
        }
3976
        // Custom Settings Pages (options-based)
3977
        elseif ( 'settings' == $pod[ 'type' ] ) {
3978
            if ( !empty( $related_ids ) )
3979
                update_option( $pod[ 'name' ] . '_' . $field[ 'name' ], $related_ids );
3980
            else
3981
                delete_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
3982
        }
3983
3984
        $related_pod_id = $related_field_id = 0;
3985
3986
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && !empty( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ] ) ) {
3987
            $related_pod_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_pod' ][ 'id' ];
3988
            $related_field_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ][ 'id' ];
3989
        }
3990
3991
        // Relationships table
3992
        if ( !pods_tableless() ) {
3993
            $related_weight = 0;
3994
3995
            foreach ( $related_ids as $related_id ) {
3996
                if ( in_array( $related_id, $current_ids ) ) {
3997
                    pods_query( "
3998
                        UPDATE `@wp_podsrel`
3999
                        SET
4000
                            `pod_id` = %d,
4001
                            `field_id` = %d,
4002
                            `item_id` = %d,
4003
                            `related_pod_id` = %d,
4004
                            `related_field_id` = %d,
4005
                            `related_item_id` = %d,
4006
                            `weight` = %d
4007
                        WHERE
4008
                            `pod_id` = %d
4009
                            AND `field_id` = %d
4010
                            AND `item_id` = %d
4011
                            AND `related_item_id` = %d
4012
                    ", array(
4013
                        $pod[ 'id' ],
4014
                        $field[ 'id' ],
4015
                        $id,
4016
                        $related_pod_id,
4017
                        $related_field_id,
4018
                        $related_id,
4019
                        $related_weight,
4020
4021
                        $pod[ 'id' ],
4022
                        $field[ 'id' ],
4023
                        $id,
4024
                        $related_id,
4025
                    ) );
4026
                }
4027
                else {
4028
                    pods_query( "
4029
                        INSERT INTO `@wp_podsrel`
4030
                            (
4031
                                `pod_id`,
4032
                                `field_id`,
4033
                                `item_id`,
4034
                                `related_pod_id`,
4035
                                `related_field_id`,
4036
                                `related_item_id`,
4037
                                `weight`
4038
                            )
4039
                        VALUES ( %d, %d, %d, %d, %d, %d, %d )
4040
                    ", array(
4041
                        $pod[ 'id' ],
4042
                        $field[ 'id' ],
4043
                        $id,
4044
                        $related_pod_id,
4045
                        $related_field_id,
4046
                        $related_id,
4047
                        $related_weight
4048
                    ) );
4049
                }
4050
4051
                $related_weight++;
4052
            }
4053
        }
4054
    }
4055
4056
    /**
4057
     * Duplicate a Pod
4058
     *
4059
     * $params['id'] int The Pod ID
4060
     * $params['name'] string The Pod name
4061
     * $params['new_name'] string The new Pod name
4062
     *
4063
     * @param array $params An associative array of parameters
4064
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4065
     *
4066
     * @return int New Pod ID
4067
     * @since 2.3
4068
     */
4069
    public function duplicate_pod ( $params, $strict = false ) {
4070 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4071
            if ( is_numeric( $params ) )
4072
                $params = array( 'id' => $params );
4073
            else
4074
                $params = array( 'name' => $params );
4075
4076
            $params = (object) pods_sanitize( $params );
4077
        }
4078
        else
4079
            $params = (object) pods_sanitize( $params );
4080
4081
        $params->table_info = false;
4082
4083
        $pod = $this->load_pod( $params, $strict );
4084
4085
        if ( empty( $pod ) ) {
4086
            if ( false !== $strict )
4087
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4088
4089
            return false;
4090
        }
4091
        elseif ( in_array( $pod[ 'type' ], array( 'media', 'user', 'comment' ) ) ) {
4092
            if ( false !== $strict )
4093
                return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this );
4094
4095
            return false;
4096
        }
4097
        elseif ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod[ 'object' ] ) ) {
4098
			$pod[ 'object' ] = '';
4099
        }
4100
4101
        unset( $pod[ 'id' ] );
4102
4103
        if ( isset( $params->new_name ) )
4104
            $pod[ 'name' ] = $params->new_name;
4105
4106
        $try = 1;
4107
4108
        $check_name = $pod[ 'name' ];
4109
        $new_label = $pod[ 'label' ];
4110
4111 View Code Duplication
        while ( $this->load_pod( array( 'name' => $check_name, 'table_info' => false ), false ) ) {
4112
            $try++;
4113
4114
            $check_name = $pod[ 'name' ] . $try;
4115
            $new_label = $pod[ 'label' ] . $try;
4116
        }
4117
4118
        $pod[ 'name' ] = $check_name;
4119
        $pod[ 'label' ] = $new_label;
4120
4121
        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
4122
            unset( $pod[ 'fields' ][ $field ][ 'id' ] );
4123
        }
4124
4125
        return $this->save_pod( $pod );
4126
    }
4127
4128
    /**
4129
     * Duplicate a Field
4130
     *
4131
     * $params['pod_id'] int The Pod ID
4132
     * $params['pod'] string The Pod name
4133
     * $params['id'] int The Field ID
4134
     * $params['name'] string The Field name
4135
     * $params['new_name'] string The new Field name
4136
     *
4137
     * @param array $params An associative array of parameters
4138
     * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error
4139
     *
4140
     * @return int New Field ID
4141
     * @since 2.3.10
4142
     */
4143
	public function duplicate_field( $params, $strict = false ) {
4144
4145
		if ( !is_object( $params ) && !is_array( $params ) ) {
4146
			if ( is_numeric( $params ) ) {
4147
				$params = array( 'id' => $params );
4148
			}
4149
			else {
4150
				$params = array( 'name' => $params );
4151
			}
4152
		}
4153
4154
		$params = (object) pods_sanitize( $params );
4155
4156
		$params->table_info = false;
4157
4158
		$field = $this->load_field( $params, $strict );
4159
4160
		if ( empty( $field ) ) {
4161
			if ( false !== $strict ) {
4162
				return pods_error( __( 'Field not found', 'pods' ), $this );
4163
			}
4164
4165
			return false;
4166
		}
4167
4168
		unset( $field[ 'id' ] );
4169
4170
		if ( isset( $params->new_name ) ) {
4171
			$field[ 'name' ] = $params->new_name;
4172
		}
4173
4174
		$try = 1;
4175
4176
		$check_name = $field[ 'name' ];
4177
		$new_label = $field[ 'label' ];
4178
4179 View Code Duplication
		while ( $this->load_field( array( 'pod_id' => $field[ 'pod_id' ], 'name' => $check_name, 'table_info' => false ), false ) ) {
4180
			$try++;
4181
4182
			$check_name = $field[ 'name' ] . $try;
4183
			$new_label = $field[ 'label' ] . $try;
4184
		}
4185
4186
		$field[ 'name' ] = $check_name;
4187
		$field[ 'label' ] = $new_label;
4188
4189
		return $this->save_field( $field );
4190
4191
	}
4192
4193
	/**
4194
	* @see PodsAPI::save_pod_item
4195
	*
4196
	* Duplicate a pod item
4197
	*
4198
	* $params['pod'] string The Pod name
4199
	* $params['id'] int The item's ID from the wp_pods_* table
4200
	*
4201
	* @param array $params An associative array of parameters
4202
	*
4203
	* @return int The table row ID
4204
	*
4205
	* @since 1.12
4206
	*/
4207
	public function duplicate_pod_item ( $params ) {
4208
4209
		$params = (object) pods_sanitize( $params );
4210
4211
		$load_pod_params = array(
4212
			'name' => $params->pod,
4213
			'table_info' => false,
4214
		);
4215
4216
		$pod = $this->load_pod( $load_pod_params );
4217
4218
		if ( false === $pod ) {
4219
			return pods_error( __( 'Pod not found', 'pods' ), $this );
4220
		}
4221
4222
		$pod = pods( $params->pod, $params->id );
4223
4224
		$params->pod = $pod->pod;
4225
		$params->pod_id = $pod->pod_id;
4226
4227
		$fields = (array) pods_var_raw( 'fields', $pod->pod_data, array(), null, true );
4228
		$object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4229
4230
		if ( ! empty( $object_fields ) ) {
4231
			$fields = array_merge( $object_fields, $fields );
4232
		}
4233
4234
		$save_params = array(
4235
			'pod' => $params->pod,
4236
			'data' => array()
4237
		);
4238
4239
		$ignore_fields = array(
4240
			$pod->pod_data['field_id'],
4241
			$pod->pod_data['field_slug'],
4242
		);
4243
4244
		if ( in_array( $pod->pod_data['type'], array( 'post_type', 'media' ) ) ) {
4245
			$ignore_fields = array(
4246
				'ID',
4247
				'post_name',
4248
				'post_date',
4249
				'post_date_gmt',
4250
				'post_modified',
4251
				'post_modified_gmt',
4252
				'guid',
4253
		        );
4254
		} elseif ( 'term' == $pod->pod_data['type'] ) {
4255
			$ignore_fields = array(
4256
				'term_id',
4257
				'term_taxonomy_id',
4258
				'slug',
4259
		        );
4260
		} elseif ( 'user' == $pod->pod_data['type'] ) {
4261
			$ignore_fields = array(
4262
				'ID',
4263
				'user_nicename',
4264
		        );
4265
		} elseif ( 'comment' == $pod->pod_data['type'] ) {
4266
			$ignore_fields = array(
4267
				'comment_ID',
4268
		        );
4269
		} elseif ( 'settings' == $pod->pod_data['type'] ) {
4270
			return pods_error( __( 'Settings do not support duplication.', 'pods' ), $this );
4271
		}
4272
4273
		/**
4274
		 * Filter the fields to ignore during duplication
4275
		 *
4276
		 * @since 2.6.6
4277
		 *
4278
		 * @param array  $ignore_fields Fields to ignore and not save during duplication
4279
		 * @param Pods   $pod           Pod object
4280
		 * @param array  $fields        Fields on the pod to duplicate
4281
		 * @param object $params        Params passed into duplicate_pod_item()
4282
		 */
4283
		$ignore_fields = apply_filters( 'pods_api_duplicate_pod_item_ignore_fields', $ignore_fields, $pod, $fields, $params );
4284
4285
		foreach ( $fields as $field ) {
4286
			if ( in_array( $field['name'], $ignore_fields ) ) {
4287
				continue;
4288
			}
4289
4290
			$field = array(
4291
				'name' => $field['name'],
4292
				'output' => 'ids'
4293
			);
4294
4295
			$value = $pod->field( $field );
4296
4297
			// @todo Add post type compatibility to set unique post_title
4298
			// @todo Add term compatibility to set unique name
4299
			// @todo Add user compatibility to set unique user_login/user_email
4300
4301
			if ( ! empty( $value ) || ( ! is_array( $value ) && 0 < strlen( $value ) ) ) {
4302
				$save_params['data'][ $field['name'] ] = $value;
4303
			}
4304
		}
4305
4306
		$save_params = $this->do_hook( 'duplicate_pod_item', $save_params, $pod->pod, $pod->id(), $params );
4307
4308
		$id = $this->save_pod_item( $save_params );
4309
4310
		return $id;
4311
4312
	}
4313
4314
    /**
4315
     * @see pods()
4316
     *
4317
     * Export a pod item
4318
     *
4319
     * $params['pod'] string The Pod name
4320
     * $params['id'] int The item's ID from the wp_pods_* table
4321
     * $params['fields'] array The fields to export
4322
     * $params['depth'] int How many levels deep to export data
4323
     *
4324
     * @param array $params An associative array of parameters
4325
     * @param object $pod (optional) Pods object
4326
     *
4327
     * @return int The table row ID
4328
     * @since 1.12
4329
     */
4330
    public function export_pod_item ( $params, $pod = null ) {
4331
        if ( !is_object( $pod ) || 'Pods' != get_class( $pod ) ) {
4332
            if ( empty( $params ) )
4333
                return false;
4334
4335
            $params = (object) pods_sanitize( $params );
4336
4337
            $pod = pods( $params->pod, $params->id, false );
4338
4339
            if ( empty( $pod ) )
4340
                return false;
4341
        }
4342
4343
        $fields = (array) pods_var_raw( 'fields', $params, array(), null, true );
4344
        $depth = (int) pods_var_raw( 'depth', $params, 2, null, true );
4345
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4346
        $flatten = (boolean) pods_var( 'flatten', $params, false, null, true );
4347
4348
        if ( empty( $fields ) ) {
4349
            $fields = $pod->fields;
4350
            $fields = array_merge( $fields, $object_fields );
4351
        }
4352
4353
        $data = $this->export_pod_item_level( $pod, $fields, $depth, $flatten );
4354
4355
        $data = $this->do_hook( 'export_pod_item', $data, $pod->pod, $pod->id(), $pod, $fields, $depth, $flatten );
4356
4357
        return $data;
4358
    }
4359
4360
    /**
4361
     * Export a pod item by depth level
4362
     *
4363
     * @param Pods $pod Pods object
4364
     * @param array $fields Fields to export
4365
     * @param int $depth Depth limit
4366
     * @param boolean $flatten Whether to flatten arrays for display
4367
     * @param int $current_depth Current depth level
4368
     *
4369
     * @return array Data array
4370
     *
4371
     * @since 2.3
4372
     */
4373
    private function export_pod_item_level ( $pod, $fields, $depth, $flatten = false, $current_depth = 1 ) {
4374
        $tableless_field_types = PodsForm::tableless_field_types();
4375
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4376
4377
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4378
4379
        $export_fields = array();
4380
4381
        foreach ( $fields as $k => $field ) {
4382
            if ( !is_array( $field ) ) {
4383
                $field = array(
4384
                    'id' => 0,
4385
                    'name' => $field
4386
                );
4387
            }
4388
4389
            if ( isset( $pod->fields[ $field[ 'name' ] ] ) ) {
4390
                $field = $pod->fields[ $field[ 'name' ] ];
4391
                $field[ 'lookup_name' ] = $field[ 'name' ];
4392
4393
                if ( in_array( $field[ 'type' ], $tableless_field_types ) && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4394
                    if ( 'pick' == $field[ 'type' ] ) {
4395
                        if ( empty( $field[ 'table_info' ] ) )
4396
                            $field[ 'table_info' ] = $this->get_table_info( pods_var_raw( 'pick_object', $field ), pods_var_raw( 'pick_val', $field ), null, null, $field );
4397
4398
                        if ( !empty( $field[ 'table_info' ] ) )
4399
                            $field[ 'lookup_name' ] .= '.' . $field[ 'table_info' ][ 'field_id' ];
4400
                    }
4401
                    elseif ( in_array( $field[ 'type' ], PodsForm::file_field_types() ) )
4402
                        $field[ 'lookup_name' ] .= '.guid';
4403
                }
4404
4405
                $export_fields[ $field[ 'name' ] ] = $field;
4406
            }
4407
            elseif ( isset( $object_fields[ $field[ 'name' ] ] ) ) {
4408
                $field = $object_fields[ $field[ 'name' ] ];
4409
                $field[ 'lookup_name' ] = $field[ 'name' ];
4410
4411
                $export_fields[ $field[ 'name' ] ] = $field;
4412
            }
4413
            elseif ( $field[ 'name' ] == $pod->pod_data[ 'field_id' ] ) {
4414
                $field[ 'type' ] = 'number';
4415
                $field[ 'lookup_name' ] = $field[ 'name' ];
4416
4417
                $export_fields[ $field[ 'name' ] ] = $field;
4418
            }
4419
        }
4420
4421
        $data = array();
4422
4423
        foreach ( $export_fields as $field ) {
4424
            // Return IDs (or guid for files) if only one level deep
4425
            if ( 1 == $depth )
4426
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'lookup_name' ], 'output' => 'arrays' ) );
4427
            // Recurse depth levels for pick fields if $depth allows
4428
            elseif ( ( -1 == $depth || $current_depth < $depth ) && 'pick' == $field[ 'type' ] && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4429
                $related_data = array();
4430
4431
                $related_ids = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'ids' ) );
4432
4433
                if ( !empty( $related_ids ) ) {
4434
                    $related_ids = (array) $related_ids;
4435
4436
                    $pick_object = pods_var_raw( 'pick_object', $field );
4437
4438
                    $related_pod = pods( pods_var_raw( 'pick_val', $field ), null, false );
4439
4440
                    // If this isn't a Pod, return data exactly as Pods does normally
4441
                    if ( empty( $related_pod ) || ( 'pod' != $pick_object && $pick_object != $related_pod->pod_data[ 'type' ] ) || $related_pod->pod == $pod->pod )
4442
                        $related_data = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4443
                    else {
4444
                        $related_object_fields = (array) pods_var_raw( 'object_fields', $related_pod->pod_data, array(), null, true );
4445
4446
                        $related_fields = array_merge( $related_pod->fields, $related_object_fields );
4447
4448
                        foreach ( $related_ids as $related_id ) {
4449
                            if ( $related_pod->fetch( $related_id ) ) {
4450
                                $related_item = $this->export_pod_item_level( $related_pod, $related_fields, $depth, $flatten, ( $current_depth + 1 ) );
4451
4452
                                $related_data[ $related_id ] = $this->do_hook( 'export_pod_item_level', $related_item, $related_pod->pod, $related_pod->id(), $related_pod, $related_fields, $depth, $flatten, ( $current_depth + 1 ) );
4453
                            }
4454
                        }
4455
4456
                        if ( $flatten && !empty( $related_data ) )
4457
                            $related_data = pods_serial_comma( array_values( $related_data ), array( 'and' => '', 'field_index' => $related_pod->pod_data[ 'field_index' ] ) );
4458
                    }
4459
                }
4460
4461
                $data[ $field[ 'name' ] ] = $related_data;
4462
            }
4463
            // Return data exactly as Pods does normally
4464
            else
4465
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4466
4467
            if ( $flatten && is_array( $data[ $field[ 'name' ] ] ) )
4468
                $data[ $field[ 'name' ] ] = pods_serial_comma( $data[ $field[ 'name' ] ], array( 'field' => $field[ 'name' ], 'fields' => $export_fields, 'and' => '' ) );
4469
        }
4470
4471
	$data[ 'id' ] = (int) $pod->id();
4472
        return $data;
4473
    }
4474
4475
    /**
4476
     * Reorder a Pod
4477
     *
4478
     * $params['pod'] string The Pod name
4479
     * $params['field'] string The field name of the field to reorder
4480
     * $params['order'] array The key => value array of items to reorder (key should be an integer)
4481
     *
4482
     * @param array $params An associative array of parameters
4483
     *
4484
     * @return bool
4485
     *
4486
     * @since 1.9.0
4487
     */
4488
    public function reorder_pod_item ( $params ) {
4489
        $params = (object) pods_sanitize( $params );
4490
4491
        // @deprecated 2.0
4492
        if ( isset( $params->datatype ) ) {
4493
            pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4494
4495
            $params->pod = $params->datatype;
4496
4497
            unset( $params->datatype );
4498
        }
4499
4500
        if ( null === pods_var_raw( 'pod', $params, null, null, true ) )
4501
            return pods_error( __( '$params->pod is required', 'pods' ), $this );
4502
4503
        if ( !is_array( $params->order ) )
4504
            $params->order = explode( ',', $params->order );
4505
4506
        $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
4507
4508
        $params->name = $pod[ 'name' ];
4509
4510
        if ( false === $pod )
4511
            return pods_error( __( 'Pod is required', 'pods' ), $this );
4512
4513
        foreach ( $params->order as $order => $id ) {
4514
            if ( isset( $pod[ 'fields' ][ $params->field ] ) || isset( $pod[ 'object_fields' ][ $params->field ] ) ) {
4515
                if ( 'table' == $pod[ 'storage' ] && ( !pods_tableless() ) ) {
4516
                    if ( isset( $pod[ 'fields' ][ $params->field ] ) )
4517
                        pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" );
4518
                    else
4519
                        pods_query( "UPDATE `{$pod['table']}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `{$pod['field_id']}` = " . pods_absint( $id ) . " LIMIT 1" );
4520
                }
4521
                else
4522
                    $this->save_pod_item( array( 'pod' => $params->pod, 'pod_id' => $params->pod_id, 'id' => $id, 'data' => array( $params->field => pods_absint( $order ) ) ) );
4523
            }
4524
        }
4525
4526
        return true;
4527
    }
4528
4529
    /**
4530
     *
4531
     * Delete all content for a Pod
4532
     *
4533
     * $params['id'] int The Pod ID
4534
     * $params['name'] string The Pod name
4535
     *
4536
     * @param array $params An associative array of parameters
4537
     * @param array $pod Pod data
4538
     *
4539
     * @return bool
4540
     *
4541
     * @uses pods_query
4542
     * @uses pods_cache_clear
4543
     *
4544
     * @since 1.9.0
4545
     */
4546
    public function reset_pod ( $params, $pod = false ) {
4547
        $params = (object) pods_sanitize( $params );
4548
4549
        $params->table_info = true;
4550
4551
        if ( empty( $pod ) )
4552
            $pod = $this->load_pod( $params );
4553
4554
        if ( false === $pod )
4555
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4556
4557
        $params->id = $pod[ 'id' ];
4558
        $params->name = $pod[ 'name' ];
4559
4560 View Code Duplication
        if ( !pods_tableless() ) {
4561
            if ( 'table' == $pod[ 'storage' ] ) {
4562
                try {
4563
                    pods_query( "TRUNCATE `@wp_pods_{$params->name}`", false );
4564
                }
4565
                catch ( Exception $e ) {
4566
                    // Allow pod to be reset if the table doesn't exist
4567
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4568
                        return pods_error( $e->getMessage(), $this );
4569
                }
4570
            }
4571
4572
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4573
        }
4574
4575
        // @todo Delete relationships from tableless relationships
4576
4577
        // Delete all posts/revisions from this post type
4578
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media' ) ) ) {
4579
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4580
4581
            $sql = "
4582
                DELETE `t`, `r`, `m`
4583
                FROM `{$pod['table']}` AS `t`
4584
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4585
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4586
                LEFT JOIN `{$pod['table']}` AS `r`
4587
                    ON `r`.`post_parent` = `t`.`{$pod['field_id']}` AND `r`.`post_status` = 'inherit'
4588
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4589
            ";
4590
4591
            pods_query( $sql, false );
4592
        }
4593
        // Delete all terms from this taxonomy
4594
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
4595
            if ( function_exists( 'get_term_meta' ) ) {
4596
                $sql = "
4597
                    DELETE `t`, `m`, `tt`, `tr`
4598
                    FROM `{$pod['table']}` AS `t`
4599
                    LEFT JOIN `{$pod['meta_table']}` AS `m`
4600
                        ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4601
                    " . $pod['join']['tt'] . "
4602
                    " . $pod['join']['tr'] . "
4603
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4604
                ";
4605
            } else {
4606
                $sql = "
4607
                    DELETE `t`, `tt`, `tr`
4608
                    FROM `{$pod['table']}` AS `t`
4609
                    " . $pod['join']['tt'] . "
4610
                    " . $pod['join']['tr'] . "
4611
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4612
                ";
4613
            }
4614
4615
            pods_query( $sql, false );
4616
        }
4617
        // Delete all users except the current one
4618
        elseif ( 'user' == $pod[ 'type' ] ) {
4619
            $sql = "
4620
                DELETE `t`, `m`
4621
                FROM `{$pod['table']}` AS `t`
4622
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4623
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4624
                WHERE `t`.`{$pod['field_id']}` != " . (int) get_current_user_id() . "
4625
            ";
4626
4627
            pods_query( $sql, false );
4628
        }
4629
        // Delete all comments
4630
        elseif ( 'comment' == $pod[ 'type' ] ) {
4631
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4632
4633
            $sql = "
4634
                DELETE `t`, `m`
4635
                FROM `{$pod['table']}` AS `t`
4636
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4637
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4638
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4639
            ";
4640
4641
            pods_query( $sql, false );
4642
        }
4643
4644
        pods_cache_clear( true ); // only way to reliably clear out cached data across an entire group
4645
4646
        return true;
4647
    }
4648
4649
    /**
4650
     * Delete a Pod and all its content
4651
     *
4652
     * $params['id'] int The Pod ID
4653
     * $params['name'] string The Pod name
4654
     *
4655
     * @param array $params An associative array of parameters
4656
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4657
     * @param bool $delete_all (optional) Whether to delete all content from a WP object
4658
     *
4659
     * @uses PodsAPI::load_pod
4660
     * @uses wp_delete_post
4661
     * @uses pods_query
4662
     *
4663
     * @return bool
4664
     * @since 1.7.9
4665
     */
4666
    public function delete_pod ( $params, $strict = false, $delete_all = false ) {
4667
        /**
4668
         * @var $wpdb wpdb
4669
         */
4670
        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...
4671
4672 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4673
            if ( is_numeric( $params ) )
4674
                $params = array( 'id' => $params );
4675
            else
4676
                $params = array( 'name' => $params );
4677
4678
            $params = (object) pods_sanitize( $params );
4679
        }
4680
        else
4681
            $params = (object) pods_sanitize( $params );
4682
4683
        $params->table_info = false;
4684
4685
        $pod = $this->load_pod( $params, $strict );
4686
4687
        if ( empty( $pod ) ) {
4688
            if ( false !== $strict )
4689
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4690
4691
            return false;
4692
        }
4693
4694
        $params->id = (int) $pod[ 'id' ];
4695
        $params->name = $pod[ 'name' ];
4696
4697
        foreach ( $pod[ 'fields' ] as $field ) {
4698
            $field[ 'pod' ] = $pod;
4699
4700
            $this->delete_field( $field, false );
4701
        }
4702
4703
        // Only delete the post once the fields are taken care of, it's not required anymore
4704
        $success = wp_delete_post( $params->id );
4705
4706
        if ( !$success )
4707
            return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this );
4708
4709
        // Reset content
4710
        if ( $delete_all )
4711
            $this->reset_pod( $params, $pod );
4712
4713 View Code Duplication
        if ( !pods_tableless() ) {
4714
            if ( 'table' == $pod[ 'storage' ] ) {
4715
                try {
4716
                    pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false );
4717
                }
4718
                catch ( Exception $e ) {
4719
                    // Allow pod to be deleted if the table doesn't exist
4720
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4721
                        return pods_error( $e->getMessage(), $this );
4722
                }
4723
            }
4724
4725
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4726
        }
4727
4728
        // @todo Delete relationships from tableless relationships
4729
4730
        // Delete any relationship references
4731
        $sql = "
4732
            DELETE `pm`
4733
            FROM `{$wpdb->postmeta}` AS `pm`
4734
            LEFT JOIN `{$wpdb->posts}` AS `p`
4735
                ON `p`.`post_type` = '_pods_field'
4736
                    AND `p`.`ID` = `pm`.`post_id`
4737
            LEFT JOIN `{$wpdb->postmeta}` AS `pm2`
4738
                ON `pm2`.`meta_key` = 'pick_object'
4739
                    AND `pm2`.`meta_value` = 'pod'
4740
                    AND `pm2`.`post_id` = `pm`.`post_id`
4741
            WHERE
4742
                `p`.`ID` IS NOT NULL
4743
                AND `pm2`.`meta_id` IS NOT NULL
4744
                AND `pm`.`meta_key` = 'pick_val'
4745
                AND `pm`.`meta_value` = '{$params->name}'
4746
        ";
4747
4748
        pods_query( $sql );
4749
4750
        $this->cache_flush_pods( $pod );
4751
4752
        return true;
4753
    }
4754
4755
    /**
4756
     * Drop a field within a Pod
4757
     *
4758
     * $params['id'] int The field ID
4759
     * $params['name'] int The field name
4760
     * $params['pod'] string The Pod name
4761
     * $params['pod_id'] string The Pod name
4762
     *
4763
     * @param array $params An associative array of parameters
4764
     * @param bool $table_operation Whether or not to handle table operations
4765
     *
4766
     * @uses PodsAPI::load_field
4767
     * @uses wp_delete_post
4768
     * @uses pods_query
4769
     *
4770
     * @return bool
4771
     * @since 1.7.9
4772
     */
4773
    public function delete_field ( $params, $table_operation = true ) {
4774
        /**
4775
         * @var $wpdb wpdb
4776
         */
4777
        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...
4778
4779
        $tableless_field_types = PodsForm::tableless_field_types();
4780
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4781
4782
        $params = (object) pods_sanitize( $params );
4783
4784
        if ( !isset( $params->pod ) )
4785
            $params->pod = '';
4786
4787
        if ( !isset( $params->pod_id ) )
4788
            $params->pod_id = 0;
4789
4790
        $pod = $params->pod;
4791
4792
        $save_pod = false;
4793
4794
        if ( !is_array( $pod ) )
4795
            $pod = $this->load_pod( array( 'name' => $pod, 'id' => $params->pod_id, 'table_info' => false ) );
4796
        else
4797
            $save_pod = true;
4798
4799
        if ( empty( $pod ) )
4800
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4801
4802
        $params->pod_id = $pod[ 'id' ];
4803
        $params->pod = $pod[ 'name' ];
4804
4805
        if ( !isset( $params->name ) )
4806
            $params->name = '';
4807
4808
        if ( !isset( $params->id ) )
4809
            $params->id = 0;
4810
4811
        $field = $this->load_field( array( 'name' => $params->name, 'id' => $params->id, 'pod' => $params->pod, 'pod_id' => $params->pod_id ) );
4812
4813
        if ( false === $field )
4814
            return pods_error( __( 'Field not found', 'pods' ), $this );
4815
4816
        $params->id = $field[ 'id' ];
4817
        $params->name = $field[ 'name' ];
4818
4819
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
4820
        $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params );
4821
4822
        if ( $table_operation && 'table' == $pod[ 'storage' ] && ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) )
4823
            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false );
4824
4825
        $success = wp_delete_post( $params->id );
4826
4827
        if ( !$success )
4828
            return pods_error( __( 'Field unable to be deleted', 'pods' ), $this );
4829
4830
        $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm
4831
            LEFT JOIN {$wpdb->posts} AS p
4832
                ON p.post_type = '_pods_field' AND p.ID = pm.post_id
4833
            WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) );
4834
4835
        if ( ( !pods_tableless() ) && $table_operation ) {
4836
            pods_query( "DELETE FROM `@wp_podsrel` WHERE (`pod_id` = {$params->pod_id} AND `field_id` = {$params->id}) OR (`related_pod_id` = {$params->pod_id} AND `related_field_id` = {$params->id})", false );
4837
        }
4838
4839
        // @todo Delete tableless relationship meta
4840
4841
        if ( true === $save_pod )
4842
            $this->cache_flush_pods( $pod );
4843
4844
        return true;
4845
    }
4846
4847
    /**
4848
     * Drop a Pod Object
4849
     *
4850
     * $params['id'] int The object ID
4851
     * $params['name'] string The object name
4852
     * $params['type'] string The object type
4853
     *
4854
     * @param array|object $params An associative array of parameters
4855
     *
4856
     * @uses wp_delete_post
4857
     *
4858
     * @return bool
4859
     * @since 2.0
4860
     */
4861
    public function delete_object ( $params ) {
4862
        $params = (object) $params;
4863
        $object = $this->load_object( $params );
4864
4865 View Code Duplication
        if ( empty( $object ) )
4866
            return pods_error( sprintf( __( "%s Object not found", 'pods' ), ucwords( $params->type ) ), $this );
4867
4868
        $success = wp_delete_post( $params->id );
4869
4870 View Code Duplication
        if ( !$success )
4871
            return pods_error( sprintf( __( "%s Object not deleted", 'pods' ), ucwords( $params->type ) ), $this );
4872
4873
        pods_transient_clear( 'pods_objects_' . $params->type );
4874
4875
        return true;
4876
    }
4877
4878
    /**
4879
     * @see PodsAPI::delete_object
4880
     *
4881
     * Drop a Pod Template
4882
     *
4883
     * $params['id'] int The template ID
4884
     * $params['name'] string The template name
4885
     *
4886
     * @param array $params An associative array of parameters
4887
     *
4888
     * @return bool
4889
     * @since 1.7.9
4890
     */
4891
    public function delete_template ( $params ) {
4892
        $params = (object) $params;
4893
        $params->type = 'template';
4894
        return $this->delete_object( $params );
4895
    }
4896
4897
    /**
4898
     * @see PodsAPI::delete_object
4899
     *
4900
     * Drop a Pod Page
4901
     *
4902
     * $params['id'] int The page ID
4903
     * $params['uri'] string The page URI
4904
     *
4905
     * @param array $params An associative array of parameters
4906
     *
4907
     * @return bool
4908
     * @since 1.7.9
4909
     */
4910
    public function delete_page ( $params ) {
4911
        $params = (object) $params;
4912
        if ( isset( $params->uri ) ) {
4913
            $params->name = $params->uri;
4914
            unset( $params->uri );
4915
        }
4916
        if ( isset( $params->name ) )
4917
            $params->name = trim( $params->name, '/' );
4918
        $params->type = 'page';
4919
        return $this->delete_object( $params );
4920
    }
4921
4922
    /**
4923
     * @see PodsAPI::delete_object
4924
     *
4925
     * Drop a Pod Helper
4926
     *
4927
     * $params['id'] int The helper ID
4928
     * $params['name'] string The helper name
4929
     *
4930
     * @param array $params An associative array of parameters
4931
     *
4932
     * @return bool
4933
     * @since 1.7.9
4934
     */
4935
    public function delete_helper ( $params ) {
4936
        $params = (object) $params;
4937
        $params->type = 'helper';
4938
        return $this->delete_object( $params );
4939
    }
4940
4941
    /**
4942
     * Drop a single pod item
4943
     *
4944
     * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter)
4945
     * $params['pod'] string (optional) The Pod name (used with id parameter)
4946
     * $params['pod_id'] int (optional) The Pod ID (used with id parameter)
4947
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
4948
     *
4949
     * @param array $params An associative array of parameters
4950
     * @param bool $wp Whether to run WP object delete action
4951
     *
4952
     * @return bool
4953
     * @since 1.7.9
4954
     */
4955
    public function delete_pod_item ( $params, $wp = true ) {
4956
        $params = (object) pods_sanitize( $params );
4957
4958
        // @deprecated 2.0
4959
        if ( isset( $params->datatype_id ) || isset( $params->datatype ) || isset( $params->tbl_row_id ) ) {
4960
            if ( isset( $params->tbl_row_id ) ) {
4961
                pods_deprecated( __( '$params->id instead of $params->tbl_row_id', 'pods' ), '2.0' );
4962
                $params->id = $params->tbl_row_id;
4963
                unset( $params->tbl_row_id );
4964
            }
4965
4966 View Code Duplication
            if ( isset( $params->pod_id ) ) {
4967
                pods_deprecated( __( '$params->id instead of $params->pod_id', 'pods' ), '2.0' );
4968
                $params->id = $params->pod_id;
4969
                unset( $params->pod_id );
4970
            }
4971
4972 View Code Duplication
            if ( isset( $params->dataype_id ) ) {
4973
                pods_deprecated( __( '$params->pod_id instead of $params->datatype_id', 'pods' ), '2.0' );
4974
                $params->pod_id = $params->dataype_id;
4975
                unset( $params->dataype_id );
4976
            }
4977
4978
            if ( isset( $params->datatype ) ) {
4979
                pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4980
                $params->pod = $params->datatype;
4981
                unset( $params->datatype );
4982
            }
4983
        }
4984
4985
        if ( !isset( $params->id ) )
4986
            return pods_error( __( 'Pod Item not found', 'pods' ), $this );
4987
4988
        $params->id = pods_absint( $params->id );
4989
4990
        if ( !isset( $params->pod ) )
4991
            $params->pod = '';
4992
4993
        if ( !isset( $params->pod_id ) )
4994
            $params->pod_id = 0;
4995
4996
        $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ) );
4997
4998
        if ( false === $pod )
4999
            return pods_error( __( 'Pod not found', 'pods' ), $this );
5000
5001
        $params->pod_id = $pod[ 'id' ];
5002
        $params->pod = $pod[ 'name' ];
5003
5004
        // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls
5005
        $bypass_helpers = false;
5006
5007
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
5008
            $bypass_helpers = true;
5009
5010
        $pre_delete_helpers = $post_delete_helpers = array();
5011
5012
        if ( false === $bypass_helpers ) {
5013
            // Plugin hook
5014
            $this->do_hook( 'pre_delete_pod_item', $params, $pod );
5015
            $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod );
5016
5017
            // Call any pre-save helpers (if not bypassed)
5018 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
5019
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
5020
                    $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' );
5021
5022
                    foreach ( $helpers as $helper ) {
5023
                        if ( isset( $pod[ 'options' ][ $helper ] ) && !empty( $pod[ 'options' ][ $helper ] ) )
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
5024
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
5025
                    }
5026
                }
5027
5028
                if ( !empty( $pre_delete_helpers ) ) {
5029
                    pods_deprecated( sprintf( __( 'Pre-delete helpers are deprecated, use the action pods_pre_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5030
5031
                    foreach ( $pre_delete_helpers as $helper ) {
5032
                        $helper = $this->load_helper( array( 'name' => $helper ) );
5033
5034
                        if ( false !== $helper )
5035
                            eval( '?>' . $helper[ 'code' ] );
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
5036
                    }
5037
                }
5038
            }
5039
        }
5040
5041
        // Delete object from relationship fields
5042
        $this->delete_object_from_relationships( $params->id, $pod );
5043
5044
        if ( 'table' == $pod[ 'storage' ] )
5045
            pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" );
5046
5047
        if ( $wp ) {
5048
            if ( 'taxonomy' == $pod['type'] ) {
5049
                $taxonomy = $pod['name'];
5050
5051
                if ( ! empty( $pod['object'] ) ) {
5052
                    $taxonomy = $pod['object'];
5053
                }
5054
5055
                wp_delete_term( $params->id, $taxonomy );
5056
            } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) {
5057
                $this->delete_wp_object( $pod['type'], $params->id );
5058
            }
5059
        }
5060
5061
        if ( false === $bypass_helpers ) {
5062
            // Plugin hook
5063
            $this->do_hook( 'post_delete_pod_item', $params, $pod );
5064
            $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod );
5065
5066
            // Call any post-save helpers (if not bypassed)
5067 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
5068
                if ( !empty( $post_delete_helpers ) ) {
5069
                    pods_deprecated( sprintf( __( 'Post-delete helpers are deprecated, use the action pods_post_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5070
5071
                    foreach ( $post_delete_helpers as $helper ) {
5072
                        $helper = $this->load_helper( array( 'name' => $helper ) );
5073
5074
                        if ( false !== $helper )
5075
                            eval( '?>' . $helper[ 'code' ] );
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
5076
                    }
5077
                }
5078
            }
5079
        }
5080
5081
        pods_cache_clear( $params->id, 'pods_items_' . $params->pod );
5082
5083
        return true;
5084
    }
5085
5086
    /**
5087
     * Delete an object from tableless fields
5088
     *
5089
     * @param int $id
5090
     * @param string $type
0 ignored issues
show
Bug introduced by
There is no parameter named $type. Was it maybe removed?

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

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

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

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

Loading history...
5091
     * @param string $name
5092
     *
5093
     * @return bool
5094
     *
5095
     * @since 2.3
5096
     */
5097
    public function delete_object_from_relationships ( $id, $object, $name = null ) {
5098
        /**
5099
         * @var $pods_init \PodsInit
5100
         */
5101
        global $pods_init;
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...
5102
5103
        $pod = false;
5104
5105
        // Run any bidirectional delete operations
5106
        if ( is_array( $object ) )
5107
            $pod = $object;
5108
        elseif ( is_object( $pods_init ) )
5109
            $pod = PodsInit::$meta->get_object( $object, $name );
0 ignored issues
show
Bug introduced by
The property meta cannot be accessed from this context as it is declared private in class PodsInit.

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

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

Loading history...
5110
5111
        if ( !empty( $pod ) ) {
5112
            $object = $pod[ 'type' ];
5113
            $name = $pod[ 'name' ];
5114
5115
            foreach ( $pod[ 'fields' ] as $field ) {
5116
                PodsForm::delete( $field[ 'type' ], $id, $field[ 'name' ], array_merge( $field, $field[ 'options' ] ), $pod );
5117
            }
5118
        }
5119
5120
        // Lookup related fields (non-bidirectional)
5121
        $params = array(
5122
            'where' => array(
5123
                array(
5124
                    'key' => 'type',
5125
                    'value' => 'pick'
5126
                ),
5127
                array(
5128
                    'key' => 'pick_object',
5129
                    'value' => $object
5130
                )
5131
            )
5132
        );
5133
5134
        if ( !empty( $name ) && $name != $object ) {
5135
            $params[ 'where' ][] = array(
5136
                'key' => 'pick_val',
5137
                'value' => $name
5138
            );
5139
        }
5140
5141
        $fields = $this->load_fields( $params, false );
5142
5143
        if ( !empty( $pod ) && 'media' == $pod[ 'type' ] ) {
5144
            $params[ 'where' ] = array(
5145
                array(
5146
                    'key' => 'type',
5147
                    'value' => 'file'
5148
                )
5149
            );
5150
5151
            $fields = array_merge( $fields, $this->load_fields( $params, false ) );
5152
        }
5153
5154
        if ( is_array( $fields ) && !empty( $fields ) ) {
5155
            foreach ( $fields as $related_field ) {
5156
                $related_pod = $this->load_pod( array( 'id' => $related_field[ 'pod_id' ], 'fields' => false ), false );
5157
5158
                if ( empty( $related_pod ) )
5159
                    continue;
5160
5161
                $related_from = $this->lookup_related_items_from( $related_field[ 'id' ], $related_pod[ 'id' ], $id, $related_field, $related_pod );
5162
5163
                $this->delete_relationships( $related_from, $id, $related_pod, $related_field );
5164
            }
5165
        }
5166
5167
        if ( !empty( $pod ) && !pods_tableless() ) {
5168
            pods_query( "
5169
                DELETE FROM `@wp_podsrel`
5170
                WHERE
5171
                (
5172
                    `pod_id` = %d
5173
                    AND `item_id` = %d
5174
                )
5175
                OR (
5176
                    `related_pod_id` = %d
5177
                    AND `related_item_id` = %d
5178
                )
5179
            ", array(
5180
                $pod[ 'id' ],
5181
                $id,
5182
5183
                $pod[ 'id' ],
5184
                $id
5185
            ) );
5186
        }
5187
5188
        return true;
5189
    }
5190
5191
    /**
5192
     * Delete relationships
5193
     *
5194
     * @param int|array $related_id IDs for items to save
5195
     * @param int|array $id ID or IDs to remove
5196
     * @param array $related_pod Pod data
5197
     * @param array $related_field Field data
5198
     *
5199
     * @return void
5200
     *
5201
     * @since 2.3
5202
     */
5203
    public function delete_relationships ( $related_id, $id, $related_pod, $related_field ) {
5204
        if ( is_array( $related_id ) ) {
5205
            foreach ( $related_id as $rid ) {
5206
                $this->delete_relationships( $rid, $id, $related_pod, $related_field );
5207
            }
5208
5209
            return;
5210
        }
5211
5212
        if ( is_array( $id ) ) {
5213
            foreach ( $id as $rid ) {
5214
                $this->delete_relationships( $related_id, $rid, $related_pod, $related_field );
5215
            }
5216
5217
            return;
5218
        }
5219
5220
        $id = (int) $id;
5221
5222
        if ( empty( $id ) )
5223
            return;
5224
5225
        $related_ids = $this->lookup_related_items( $related_field[ 'id' ], $related_pod[ 'id' ], $related_id, $related_field, $related_pod );
5226
5227
        if ( empty( $related_ids ) )
5228
            return;
5229
        elseif ( !in_array( $id, $related_ids ) )
5230
            return;
5231
5232
	    if ( isset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] ) ) {
5233
		    // Delete relationship from cache
5234
		    unset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] );
5235
	    }
5236
        unset( $related_ids[ array_search( $id, $related_ids ) ] );
5237
5238
        $no_conflict = pods_no_conflict_check( $related_pod[ 'type' ] );
5239
5240
        if ( !$no_conflict )
5241
            pods_no_conflict_on( $related_pod[ 'type' ] );
5242
5243
        // Post Types, Media, Users, and Comments (meta-based)
5244 View Code Duplication
        if ( in_array( $related_pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
5245
            $object_type = $related_pod[ 'type' ];
5246
5247
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
5248
                $object_type = 'post';
5249
            elseif ( 'taxonomy' == $object_type )
5250
                $object_type = 'term';
5251
5252
            delete_metadata( $object_type, $related_id, $related_field[ 'name' ] );
5253
5254
            if ( !empty( $related_ids ) ) {
5255
                update_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ], $related_ids );
5256
5257
                foreach ( $related_ids as $rel_id ) {
5258
                    add_metadata( $object_type, $related_id, $related_field[ 'name' ], $rel_id );
5259
                }
5260
            }
5261
            else
5262
                delete_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ] );
5263
        }
5264
        // Custom Settings Pages (options-based)
5265
        elseif ( 'settings' == $related_pod[ 'type' ] ) {
5266
            if ( !empty( $related_ids ) )
5267
                update_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ], $related_ids );
5268
            else
5269
                delete_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ] );
5270
        }
5271
5272
        // Relationships table
5273
        if ( !pods_tableless() ) {
5274
            pods_query( "
5275
                DELETE FROM `@wp_podsrel`
5276
                WHERE
5277
                (
5278
                    `pod_id` = %d
5279
                    AND `field_id` = %d
5280
                    AND `item_id` = %d
5281
                    AND `related_item_id` = %d
5282
                )
5283
                OR (
5284
                    `related_pod_id` = %d
5285
                    AND `related_field_id` = %d
5286
                    AND `related_item_id` = %d
5287
                    AND `item_id` = %d
5288
                )
5289
            ", array(
5290
                $related_pod[ 'id' ],
5291
                $related_field[ 'id' ],
5292
                $related_id,
5293
                $id,
5294
5295
                $related_pod[ 'id' ],
5296
                $related_field[ 'id' ],
5297
                $related_id,
5298
                $id
5299
            ) );
5300
        }
5301
5302
        if ( !$no_conflict )
5303
            pods_no_conflict_off( $related_pod[ 'type' ] );
5304
    }
5305
5306
    /**
5307
     * Check if a Pod exists
5308
     *
5309
     * $params['id'] int Pod ID
5310
     * $params['name'] string Pod name
5311
     *
5312
     * @param array $params An associative array of parameters
5313
     *
5314
     * @return bool True if exists
5315
     *
5316
     * @since 1.12
5317
     */
5318
    public function pod_exists ( $params, $type = null ) {
5319
        if ( is_string( $params ) )
5320
            $params = array( 'name' => $params );
5321
5322
        $params = (object) pods_sanitize( $params );
5323
5324
        if ( !empty( $params->id ) || !empty( $params->name ) ) {
5325 View Code Duplication
            if ( !isset( $params->name ) )
5326
                $pod = get_post( $dummy = (int) $params->id );
5327
            else {
5328
                $pod = get_posts( array(
5329
                    'name' => $params->name,
5330
                    'post_type' => '_pods_pod',
5331
                    'posts_per_page' => 1
5332
                ) );
5333
            }
5334
5335
            if ( !empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) )
5336
                return true;
5337
        }
5338
5339
        return false;
5340
    }
5341
5342
	/**
5343
	 * Get number of pods for a specific pod type
5344
	 *
5345
	 * @param string $type Type to get count
5346
	 *
5347
	 * @return int Total number of pods for a type
5348
	 *
5349
	 * @since 2.6.6
5350
	 */
5351
	public function get_pod_type_count( $type ) {
5352
5353
		$args = array(
5354
			'post_type'      => '_pods_pod',
5355
			'posts_per_page' => - 1,
5356
			'nopaging'       => true,
5357
			'fields'         => 'ids',
5358
			'meta_query'     => array(
5359
				array(
5360
					'key'   => 'type',
5361
					'value' => $type,
5362
				),
5363
			),
5364
		);
5365
5366
		$posts = get_posts( $args );
5367
5368
		$total = count( $posts );
5369
5370
		return $total;
5371
5372
	}
5373
5374
    /**
5375
     * Load a Pod and all of its fields
5376
     *
5377
     * $params['id'] int The Pod ID
5378
     * $params['name'] string The Pod name
5379
     * $params['fields'] bool Whether to load fields (default is true)
5380
     * $params['bypass_cache'] boolean Bypass the cache when getting data
5381
     *
5382
     * @param array|object $params An associative array of parameters or pod name as a string
5383
     * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work
5384
     *
5385
     * @return array|bool|mixed|void
5386
     * @since 1.7.9
5387
     */
5388
    public function load_pod ( $params, $strict = true ) {
5389
5390
        /**
5391
         * @var $sitepress SitePress
5392
		 * @var $wpdb wpdb
5393
         */
5394
        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...
5395
5396
        $current_language = false;
5397
        $load_fields = true;
5398
	    $bypass_cache = false;
5399
5400
	    // Get current language data
5401
		$lang_data = self::get_current_language();
5402
5403
	    if ( $lang_data ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $lang_data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
5404
		    if ( ! empty( $lang_data['language'] ) ) {
5405
			    $current_language = $lang_data['language'];
5406
		    }
5407
	    }
5408
5409
        if ( !is_array( $params ) && !is_object( $params ) )
5410
            $params = array( 'name' => $params, 'table_info' => false, 'fields' => true );
5411
5412
        if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && isset( $params->fields ) && !$params->fields )
5413
            $load_fields = false;
5414
        elseif ( is_array( $params ) && isset( $params[ 'fields' ] ) && !$params[ 'fields' ] )
5415
            $load_fields = false;
5416
5417
	    $table_info = false;
5418
5419
        if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->table_info ) )
5420
            $table_info = true;
5421
        elseif ( is_array( $params ) && ! empty( $params[ 'table_info' ] ) )
5422
            $table_info = true;
5423
5424
        $transient = 'pods_' . $wpdb->prefix . '_pod';
5425
5426
        if ( !empty( $current_language ) )
5427
            $transient .= '_' . $current_language;
5428
5429
        if ( !$load_fields )
5430
            $transient .= '_nofields';
5431
5432
        if ( $table_info )
5433
            $transient .= '_tableinfo';
5434
5435
	    $check_pod = $params;
5436
5437
	    if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->pod ) ) {
5438
		    $check_pod = $params->pod;
5439
	    } elseif ( is_array( $params ) && ! empty( $params['pod'] ) ) {
5440
		    $check_pod = $params['pod'];
5441
	    }
5442
5443
        if ( is_object( $check_pod ) && ( is_a( $check_pod, 'WP_Post' ) || isset( $check_pod->post_name ) ) ) {
5444
            $pod = false;
5445
5446
            if ( pods_api_cache() )
5447
                $pod = pods_transient_get( $transient . '_' . $check_pod->post_name );
5448
5449 View Code Duplication
            if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5450
	            // @todo Is this needed anymore for WPML?
5451
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) )
5452
                     && did_action( 'wpml_loaded' )
5453
                     && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
5454
                    $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
5455
                }
5456
5457
                return $pod;
5458
            }
5459
5460
            $_pod = get_object_vars( $check_pod );
5461
        }
5462
        else {
5463
            $params = (object) pods_sanitize( $params );
5464
5465 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) ) {
5466
                if ( $strict ) {
5467
	                  return pods_error( 'Either Pod ID or Name are required', $this );
5468
                }
5469
5470
                return false;
5471
            }
5472
5473
		    if ( ! empty( $params->bypass_cache ) ) {
5474
		        $bypass_cache = true;
5475
		    }
5476
5477
            if ( isset( $params->name ) ) {
5478
                $pod = false;
5479
5480
				if ( '_pods_pod' == $params->name ) {
5481
					$pod = array(
5482
						'id' => 0,
5483
						'name' => $params->name,
5484
						'label' => __( 'Pods', 'pods' ),
5485
						'type' => 'post_type',
5486
						'storage' => 'meta',
5487
						'options' => array(
5488
							'label_singular' => __( 'Pod', 'pods' )
5489
						),
5490
						'fields' => array()
5491
					);
5492
				}
5493
				elseif ( '_pods_field' == $params->name ) {
5494
					$pod = array(
5495
						'id' => 0,
5496
						'name' => $params->name,
5497
						'label' => __( 'Pod Fields', 'pods' ),
5498
						'type' => 'post_type',
5499
						'storage' => 'meta',
5500
						'options' => array(
5501
							'label_singular' => __( 'Pod Field', 'pods' )
5502
						),
5503
						'fields' => array()
5504
					);
5505
				}
5506 View Code Duplication
                elseif ( ! $bypass_cache & pods_api_cache() )
5507
                    $pod = pods_transient_get( $transient . '_' . $params->name );
5508
5509 View Code Duplication
                if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5510
                    if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && did_action( 'wpml_loaded' )
5511
                        && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) )
5512
                        $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5513
5514
                    return $pod;
5515
                }
5516
            }
5517
5518 View Code Duplication
            if ( !isset( $params->name ) )
5519
                $pod = get_post( $dummy = (int) $params->id );
5520
            else {
5521
                $pod = get_posts( array(
5522
                    'name' => $params->name,
5523
                    'post_type' => '_pods_pod',
5524
                    'posts_per_page' => 1
5525
                ) );
5526
            }
5527
5528
            if ( empty( $pod ) ) {
5529
                if ( $strict )
5530
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
5531
5532
                return false;
5533
            }
5534
5535
            if ( is_array( $pod ) )
5536
                $pod = $pod[ 0 ];
5537
5538
            $_pod = get_object_vars( $pod );
5539
        }
5540
5541
        $pod = false;
5542
5543 View Code Duplication
        if ( ! $bypass_cache || pods_api_cache() )
5544
            $pod = pods_transient_get( $transient . '_' . $_pod[ 'post_name' ] );
5545
5546 View Code Duplication
        if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5547
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) )
5548
                 && did_action( 'wpml_loaded' )
5549
                && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
5550
	            $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
5551
            }
5552
5553
            return $pod;
5554
        }
5555
5556
        $pod = array(
5557
            'id' => $_pod[ 'ID' ],
5558
            'name' => $_pod[ 'post_name' ],
5559
            'label' => $_pod[ 'post_title' ],
5560
            'description' => $_pod[ 'post_content' ]
5561
        );
5562
5563
        if ( strlen( $pod[ 'label' ] ) < 1 )
5564
            $pod[ 'label' ] = $pod[ 'name' ];
5565
5566
        // @todo update with a method to put all options in
5567
        $defaults = array(
5568
            'show_in_menu' => 1,
5569
            'type' => 'post_type',
5570
            'storage' => 'meta',
5571
            'object' => '',
5572
            'alias' => ''
5573
        );
5574
5575
        if ( $bypass_cache ) {
5576
            wp_cache_delete( $pod['id'], 'post_meta' );
5577
5578
            update_postmeta_cache( array( $pod['id'] ) );
5579
        }
5580
5581
        $pod[ 'options' ] = get_post_meta( $pod[ 'id' ] );
5582
5583 View Code Duplication
        foreach ( $pod[ 'options' ] as $option => $value ) {
5584
            if ( is_array( $value ) ) {
5585
                foreach ( $value as $k => $v ) {
5586
                    if ( !is_array( $v ) )
5587
                        $value[ $k ] = maybe_unserialize( $v );
5588
                }
5589
5590
                if ( 1 == count( $value ) )
5591
                    $value = current( $value );
5592
            }
5593
            else
5594
                $value = maybe_unserialize( $value );
5595
5596
            $pod[ 'options' ][ $option ] = $value;
5597
        }
5598
5599
        $pod[ 'options' ] = array_merge( $defaults, $pod[ 'options' ] );
5600
5601
        $pod[ 'type' ] = $pod[ 'options' ][ 'type' ];
5602
        $pod[ 'storage' ] = $pod[ 'options' ][ 'storage' ];
5603
        $pod[ 'object' ] = $pod[ 'options' ][ 'object' ];
5604
        $pod[ 'alias' ] = $pod[ 'options' ][ 'alias' ];
5605
5606
        unset( $pod[ 'options' ][ 'type' ] );
5607
        unset( $pod[ 'options' ][ 'storage' ] );
5608
        unset( $pod[ 'options' ][ 'object' ] );
5609
        unset( $pod[ 'options' ][ 'alias' ] );
5610
5611
        if ( $table_info )
5612
            $pod = array_merge( $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ), $pod );
5613
5614
        // Override old 'none' storage type
5615 View Code Duplication
        if ( 'taxonomy' == $pod['type'] && 'none' == $pod['storage'] && function_exists( 'get_term_meta' ) ) {
5616
            $pod[ 'storage' ] = 'meta';
5617
        }
5618
5619
        if ( isset( $pod[ 'pod' ] ) )
5620
            unset( $pod[ 'pod' ] );
5621
5622
        $pod[ 'fields' ] = array();
5623
5624
        $pod[ 'object_fields' ] = array();
5625
5626
        if ( 'pod' != $pod[ 'type' ] )
5627
            $pod[ 'object_fields' ] = $this->get_wp_object_fields( $pod[ 'type' ], $pod );
5628
5629
        $fields = get_posts( array(
5630
            'post_type' => '_pods_field',
5631
            'posts_per_page' => -1,
5632
            'nopaging' => true,
5633
            'post_parent' => $pod[ 'id' ],
5634
            'orderby' => 'menu_order',
5635
            'order' => 'ASC'
5636
        ) );
5637
5638
        if ( !empty( $fields ) ) {
5639
            foreach ( $fields as $field ) {
5640
                $field->pod = $pod[ 'name' ];
5641
                $field->table_info = $table_info;
5642
                $field->bypass_cache = $bypass_cache;
5643
5644
                if ( $load_fields ) {
5645
                    $field = $this->load_field( $field );
5646
5647
                    $field = PodsForm::field_setup( $field, null, $field[ 'type' ] );
5648
                }
5649
                else {
5650
			        if ( $bypass_cache ) {
5651
                        wp_cache_delete( $field->ID, 'post_meta' );
5652
5653
			            update_postmeta_cache( array( $field->ID ) );
5654
			        }
5655
5656
                    $field = array(
5657
                        'id' => $field->ID,
5658
                        'name' => $field->post_name,
5659
                        'label' => $field->post_title,
5660
                        'type' => get_post_meta( $field->ID, 'type', true )
5661
                    );
5662
                }
5663
5664
                $pod[ 'fields' ][ $field[ 'name' ] ] = $field;
5665
            }
5666
        }
5667
5668 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
5669
            pods_transient_set( $transient . '_' . $pod[ 'name' ], $pod );
5670
5671
        return $pod;
5672
    }
5673
5674
    /**
5675
     * Load a list of Pods based on filters specified.
5676
     *
5677
     * $params['type'] string/array Pod Type(s) to filter by
5678
     * $params['object'] string/array Pod Object(s) to filter by
5679
     * $params['options'] array Pod Option(s) key=>value array to filter by
5680
     * $params['orderby'] string ORDER BY clause of query
5681
     * $params['limit'] string Number of Pods to return
5682
     * $params['where'] string WHERE clause of query
5683
     * $params['ids'] string|array IDs of Objects
5684
     * $params['count'] boolean Return only a count of Pods
5685
     * $params['names'] boolean Return only an array of name => label
5686
     * $params['ids'] boolean Return only an array of ID => label
5687
     * $params['fields'] boolean Return pod fields with Pods (default is true)
5688
     * $params['key_names'] boolean Return pods keyed by name
5689
     * $params['bypass_cache'] boolean Bypass the cache when getting data
5690
     *
5691
     * @param array $params An associative array of parameters
5692
     *
5693
     * @return array|mixed
5694
     *
5695
     * @uses PodsAPI::load_pod
5696
     *
5697
     * @since 2.0
5698
     */
5699
    public function load_pods ( $params = null ) {
5700
5701
        $current_language = false;
5702
5703
	    // Get current language data
5704
		$lang_data = self::get_current_language();
5705
5706
	    if ( $lang_data ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $lang_data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
5707
		    if ( ! empty( $lang_data['language'] ) ) {
5708
			    $current_language = $lang_data['language'];
5709
		    }
5710
	    }
5711
5712
        $params = (object) pods_sanitize( $params );
5713
5714
        $order = 'ASC';
5715
        $orderby = 'menu_order title';
5716
        $limit = -1;
5717
        $ids = false;
5718
5719
        $meta_query = array();
5720
        $cache_key = '';
5721
5722
        $bypass_cache = false;
5723
5724
	    if ( ! empty( $params->bypass_cache ) ) {
5725
	    	$bypass_cache = true;
5726
	    }
5727
5728
        if ( isset( $params->type ) && !empty( $params->type ) ) {
5729
            if ( !is_array( $params->type ) )
5730
                $params->type = array( trim( $params->type ) );
5731
5732
            sort( $params->type );
5733
5734
            $meta_query[] = array(
5735
                'key' => 'type',
5736
                'value' => $params->type,
5737
                'compare' => 'IN'
5738
            );
5739
5740
            if ( 0 < count( $params->type ) )
5741
                $cache_key .= '_type_' . trim( implode( '_', $params->type ) );
5742
        }
5743
5744
        if ( isset( $params->object ) && !empty( $params->object ) ) {
5745
            if ( !is_array( $params->object ) )
5746
                $params->object = array( $params->object );
5747
5748
            $params->object = pods_trim( $params->object );
5749
5750
            sort( $params->object );
5751
5752
            $meta_query[] = array(
5753
                'key' => 'object',
5754
                'value' => $params->object,
5755
                'compare' => 'IN'
5756
            );
5757
5758
            if ( 1 == count( $params->object ) )
5759
                $cache_key .= '_object_' . trim( implode( '', $params->object ) );
5760
        }
5761
5762 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
5763
            foreach ( $params->options as $option => $value ) {
5764
                if ( !is_array( $value ) )
5765
                    $value = array( $value );
5766
5767
                $value = pods_trim( $value );
5768
5769
                sort( $value );
5770
5771
                $meta_query[] = array(
5772
                    'key' => $option,
5773
                    'value' => pods_sanitize( $value ),
5774
                    'compare' => 'IN'
5775
                );
5776
            }
5777
5778
            $cache_key = '';
5779
        }
5780
5781
        if ( isset( $params->where ) && is_array( $params->where ) )
5782
            $meta_query = array_merge( $meta_query, (array) $params->where );
5783
5784 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
5785
            $order = strtoupper( $params->order );
5786
5787
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
5788
            $orderby = strtoupper( $params->orderby );
5789
5790
        if ( isset( $params->limit ) && !empty( $params->limit ) )
5791
            $limit = pods_absint( $params->limit );
5792
5793
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
5794
            $ids = $params->ids;
5795
5796
            if ( !is_array( $ids ) )
5797
                $ids = explode( ',', $ids );
5798
        }
5799
5800
        if ( empty( $ids ) )
5801
            $ids = false;
5802
5803
        $pre_key = '';
5804
5805
        if ( !empty( $current_language ) )
5806
            $pre_key .= '_' . $current_language;
5807
5808
        if ( isset( $params->count ) && $params->count )
5809
            $pre_key .= '_count';
5810
5811
        if ( isset( $params->ids ) && $params->ids && !empty( $ids ) )
5812
            $pre_key .= '_ids_' . implode( '_', $ids );
5813
5814
        if ( isset( $params->names ) && $params->names )
5815
            $pre_key .= '_names';
5816
        elseif ( isset( $params->names_ids ) && $params->names_ids )
5817
            $pre_key .= '_names_ids';
5818
5819
        if ( isset( $params->key_names ) && $params->key_names )
5820
            $pre_key .= '_namekeys';
5821
5822
        if ( isset( $params->fields ) && !$params->fields )
5823
            $pre_key .= '_nofields';
5824
5825
        if ( isset( $params->table_info ) && $params->table_info )
5826
            $pre_key .= '_tableinfo';
5827
5828
5829
        $pre_key .= '_get';
5830
5831
        if ( empty( $cache_key ) )
5832
            $cache_key = 'pods' . $pre_key . '_all';
5833
        else
5834
            $cache_key = 'pods' . $pre_key . $cache_key;
5835
5836
        if ( ! $bypass_cache && pods_api_cache() && !empty( $cache_key ) && ( 'pods' . ( !empty( $current_language ) ? '_' . $current_language : '' ) . '_get_all' != $cache_key || empty( $meta_query ) ) && $limit < 1 && ( empty( $orderby ) || 'menu_order title' == $orderby ) && empty( $ids ) ) {
5837
            $the_pods = pods_transient_get( $cache_key );
5838
5839
            if ( false === $the_pods )
5840
                $the_pods = pods_cache_get( $cache_key, 'pods' );
5841
5842
            if ( !is_array( $the_pods ) && 'none' == $the_pods )
5843
                return array();
5844
            elseif ( false !== $the_pods )
5845
                return $the_pods;
5846
        }
5847
5848
        $the_pods = array();
5849
5850
		$args = array(
5851
			'post_type' => '_pods_pod',
5852
			'nopaging' => true,
5853
			'posts_per_page' => $limit,
5854
			'order' => $order,
5855
			'orderby' => $orderby,
5856
			'meta_query' => $meta_query,
5857
		);
5858
5859
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
5860
		if ( false != $ids ) {
5861
			$args[ 'post__in' ] = $ids;
5862
		}
5863
5864
		$_pods = get_posts( $args );
5865
5866
        $export_ignore = array(
5867
            'object_type',
5868
            'object_name',
5869
            'table',
5870
            'meta_table',
5871
            'pod_table',
5872
            'field_id',
5873
            'field_index',
5874
            'field_slug',
5875
            'field_type',
5876
            'field_parent',
5877
            'field_parent_select',
5878
            'meta_field_id',
5879
            'meta_field_index',
5880
            'meta_field_value',
5881
            'pod_field_id',
5882
            'pod_field_index',
5883
            'object_fields',
5884
            'join',
5885
            'where',
5886
            'where_default',
5887
            'orderby',
5888
            'pod',
5889
            'recurse',
5890
            'table_info',
5891
            'attributes',
5892
            'group',
5893
            'grouped',
5894
            'developer_mode',
5895
            'dependency',
5896
            'depends-on',
5897
            'excludes-on'
5898
        );
5899
5900
        $total_fields = 0;
5901
5902
        if ( isset( $params->count ) && $params->count )
5903
            $the_pods = count( $_pods );
5904
        else {
5905
            foreach ( $_pods as $pod ) {
5906
                if ( isset( $params->names ) && $params->names )
5907
                    $the_pods[ $pod->post_name ] = $pod->post_title;
5908
                elseif ( isset( $params->names_ids ) && $params->names_ids )
5909
                    $the_pods[ $pod->ID ] = $pod->post_name;
5910
                else {
5911
                    if ( isset( $params->fields ) && !$params->fields )
5912
                        $pod->fields = false;
5913
5914
                    $pod = $this->load_pod( array( 'pod' => $pod, 'table_info' => ! empty( $params->table_info ), 'bypass_cache' => $bypass_cache ) );
5915
5916
                    // Remove extra data not needed
5917
                    if ( pods_var( 'export', $params, false ) && ( !isset( $params->fields ) || $params->fields ) ) {
5918
                        foreach ( $export_ignore as $ignore ) {
5919
                            if ( isset( $pod[ $ignore ] ) )
5920
                                unset( $pod[ $ignore ] );
5921
                        }
5922
5923
                        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
5924
                            if ( isset( $pod[ 'fields' ][ $field ][ 'table_info' ] ) )
5925
                                unset( $pod[ 'fields' ][ $field ][ 'table_info' ] );
5926
                        }
5927
                    }
5928
5929
                    $total_fields += count( $pod[ 'fields' ] );
5930
5931
                    if ( isset( $params->key_names ) && $params->key_names )
5932
                        $the_pods[ $pod[ 'name' ] ] = $pod;
5933
                    else
5934
                        $the_pods[ $pod[ 'id' ] ] = $pod;
5935
                }
5936
            }
5937
        }
5938
5939
        if ( ( !function_exists( 'pll_current_language' ) || ( isset( $params->refresh ) && $params->refresh ) ) && !empty( $cache_key ) && ( 'pods' != $cache_key || empty( $meta_query ) ) && $limit < 1 && ( empty( $orderby ) || 'menu_order title' == $orderby ) && empty( $ids ) ) {
5940
            // Too many Pods can cause issues with the DB when caching is not enabled
5941
            if ( 15 < count( $the_pods ) || 75 < count( $total_fields ) ) {
5942
                pods_transient_clear( $cache_key );
5943
5944 View Code Duplication
                if ( pods_api_cache() ) {
5945
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
5946
                        pods_cache_set( $cache_key, 'none', 'pods' );
5947
                    else
5948
                        pods_cache_set( $cache_key, $the_pods, 'pods' );
5949
                }
5950
            }
5951
            else {
5952
                pods_cache_clear( $cache_key, 'pods' );
5953
5954 View Code Duplication
                if ( pods_api_cache() ) {
5955
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
5956
                        pods_transient_set( $cache_key, 'none' );
5957
                    else
5958
                        pods_transient_set( $cache_key, $the_pods );
5959
                }
5960
            }
5961
        }
5962
5963
        return $the_pods;
5964
    }
5965
5966
    /**
5967
     * Check if a Pod's field exists
5968
     *
5969
     * $params['pod_id'] int The Pod ID
5970
     * $params['id'] int The field ID
5971
     * $params['name'] string The field name
5972
     *
5973
     * @param array $params An associative array of parameters
5974
     *
5975
     * @return bool
5976
     *
5977
     * @since 1.12
5978
     */
5979
    public function field_exists ( $params ) {
5980
        $params = (object) pods_sanitize( $params );
5981
5982
        if ( ( !empty( $params->id ) || !empty( $params->name ) ) && isset( $params->pod_id ) && !empty( $params->pod_id ) ) {
5983 View Code Duplication
            if ( !isset( $params->name ) )
5984
                $field = get_post( $dummy = (int) $params->id );
5985
            else {
5986
                $field = get_posts( array(
5987
                    'name' => $params->name,
5988
                    'post_type' => '_pods_field',
5989
                    'posts_per_page' => 1,
5990
                    'post_parent' => $params->pod_id
5991
                ) );
5992
            }
5993
5994
            if ( !empty( $field ) )
5995
                return true;
5996
        }
5997
5998
        return false;
5999
    }
6000
6001
    /**
6002
     * Load a field
6003
     *
6004
     * $params['pod_id'] int The Pod ID
6005
     * $params['pod'] string The Pod name
6006
     * $params['id'] int The field ID
6007
     * $params['name'] string The field name
6008
     * $params['table_info'] boolean Whether to lookup a pick field's table info
6009
     * $params['bypass_cache'] boolean Bypass the cache when getting data
6010
     *
6011
     * @param array $params An associative array of parameters
6012
     * @param boolean $strict Whether to require a field exist or not when loading the info
6013
     *
6014
     * @return array|bool Array with field data, false if field not found
6015
     * @since 1.7.9
6016
     */
6017
    public function load_field ( $params, $strict = false ) {
6018
        $params = (object) $params;
6019
6020
        if ( !isset( $params->table_info ) )
6021
            $params->table_info = false;
6022
6023
        $bypass_cache = false;
6024
6025
        if ( ! empty( $params->bypass_cache ) )
6026
            $bypass_cache = true;
6027
6028
        $pod = array();
6029
        $field = array();
6030
6031
        if ( isset( $params->post_title ) )
6032
            $_field = $params;
6033
        elseif ( isset( $params->id ) && !empty( $params->id ) )
6034
            $_field = get_post( $dumb = (int) $params->id );
6035
        else {
6036
            if ( !isset( $params->pod ) )
6037
                $params->pod = '';
6038
6039
            if ( !isset( $params->pod_id ) )
6040
                $params->pod_id = 0;
6041
6042
            if ( isset( $params->pod_data ) )
6043
                $pod = $params->pod_data;
6044
            else {
6045
                $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false, 'bypass_cache' => $bypass_cache ), false );
6046
6047
                if ( false === $pod ) {
6048
                    if ( $strict )
6049
                        return pods_error( __( 'Pod not found', 'pods' ), $this );
6050
6051
                    return false;
6052
                }
6053
            }
6054
6055
            $params->pod_id = $pod[ 'id' ];
6056
            $params->pod = $pod[ 'name' ];
6057
6058 View Code Duplication
            if ( empty( $params->name ) && empty( $params->pod ) && empty( $params->pod_id ) )
6059
                return pods_error( __( 'Either Field Name or Field ID / Pod ID are required', 'pods' ), $this );
6060
6061
            $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
6062
6063
            if ( isset( $pod[ 'fields' ][ $params->name ] ) && isset( $pod[ 'fields' ][ $params->name ][ 'id' ] ) )
6064
                return $pod[ 'fields' ][ $params->name ];
6065
6066
            $field = false;
6067
6068
            if ( ! $bypass_cache && pods_api_cache() )
6069
                $field = pods_transient_get( 'pods_field_' . $params->pod . '_' . $params->name );
6070
6071
            if ( empty( $field ) ) {
6072
                $field = get_posts( array(
6073
                    'name' => $params->name,
6074
                    'post_type' => '_pods_field',
6075
                    'posts_per_page' => 1,
6076
                    'post_parent' => $params->pod_id
6077
                ) );
6078
6079
                if ( empty( $field ) ) {
6080
                    if ( $strict )
6081
                        return pods_error( __( 'Field not found', 'pods' ), $this );
6082
6083
                    return false;
6084
                }
6085
6086
                $_field = $field[ 0 ];
6087
6088
                $field = array();
6089
            }
6090
        }
6091
6092
        if ( empty( $_field ) ) {
6093
            if ( $strict )
6094
                return pods_error( __( 'Field not found', 'pods' ), $this );
6095
6096
            return false;
6097
        }
6098
6099
        $_field = get_object_vars( $_field );
6100
6101
        if ( !isset( $pod[ 'name' ] ) && !isset( $_field[ 'pod' ] ) ) {
6102
            if ( 0 < $_field[ 'post_parent' ] )
6103
                $pod = $this->load_pod( array( 'id' => $_field[ 'post_parent' ], 'table_info' => false ), false );
6104
6105
            if ( empty( $pod ) ) {
6106
                if ( $strict )
6107
                    return pods_error( __( 'Pod for field not found', 'pods' ), $this );
6108
6109
                return false;
6110
            }
6111
        }
6112
6113
        if ( empty( $field ) ) {
6114 View Code Duplication
            if ( ! $bypass_cache && pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6115
                $field = pods_transient_get( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $_field[ 'post_name' ] );
6116
6117
            if ( empty( $field ) ) {
6118
                $defaults = array(
6119
                    'type' => 'text'
6120
                );
6121
6122
                $field = array(
6123
                    'id' => $_field[ 'ID' ],
6124
                    'name' => $_field[ 'post_name' ],
6125
                    'label' => $_field[ 'post_title' ],
6126
                    'description' => $_field[ 'post_content' ],
6127
                    'weight' => $_field[ 'menu_order' ],
6128
                    'pod_id' => $_field[ 'post_parent' ],
6129
                    'pick_object' => '',
6130
                    'pick_val' => '',
6131
                    'sister_id' => '',
6132
                    'table_info' => array()
6133
                );
6134
6135
                if ( isset( $pod[ 'name' ] ) )
6136
                    $field[ 'pod' ] = $pod[ 'name' ];
6137
                elseif ( isset( $_field[ 'pod' ] ) )
6138
                    $field[ 'pod' ] = $_field[ 'pod' ];
6139
6140
	            if ( $bypass_cache ) {
6141
	                wp_cache_delete( $field['id'], 'post_meta' );
6142
6143
	                update_postmeta_cache( array( $field['id'] ) );
6144
	            }
6145
6146
                $field[ 'options' ] = get_post_meta( $field[ 'id' ] );
6147
6148
                $options_ignore = array(
6149
                    'method',
6150
                    'table_info',
6151
                    'attributes',
6152
                    'group',
6153
                    'grouped',
6154
                    'developer_mode',
6155
                    'dependency',
6156
                    'depends-on',
6157
                    'excludes-on'
6158
                );
6159
6160
                foreach ( $options_ignore as $ignore ) {
6161
                    if ( isset( $field[ 'options' ][ $ignore ] ) )
6162
                        unset( $field[ 'options' ][ $ignore ] );
6163
                }
6164
6165 View Code Duplication
                foreach ( $field[ 'options' ] as $option => $value ) {
6166
                    if ( is_array( $value ) ) {
6167
                        foreach ( $value as $k => $v ) {
6168
                            if ( !is_array( $v ) )
6169
                                $value[ $k ] = maybe_unserialize( $v );
6170
                        }
6171
6172
                        if ( 1 == count( $value ) )
6173
                            $value = current( $value );
6174
                    }
6175
                    else
6176
                        $value = maybe_unserialize( $value );
6177
6178
                    $field[ 'options' ][ $option ] = $value;
6179
                }
6180
6181
                $field[ 'options' ] = array_merge( $defaults, $field[ 'options' ] );
6182
6183
                $field[ 'type' ] = $field[ 'options' ][ 'type' ];
6184
6185
                unset( $field[ 'options' ][ 'type' ] );
6186
6187 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_object' ] ) ) {
6188
                    $field[ 'pick_object' ] = $field[ 'options' ][ 'pick_object' ];
6189
6190
                    unset( $field[ 'options' ][ 'pick_object' ] );
6191
                }
6192
6193 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_val' ] ) ) {
6194
                    $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_val' ];
6195
6196
                    unset( $field[ 'options' ][ 'pick_val' ] );
6197
                }
6198
6199 View Code Duplication
                if ( isset( $field[ 'options' ][ 'sister_id' ] ) ) {
6200
                    $field[ 'sister_id' ] = $field[ 'options' ][ 'sister_id' ];
6201
6202
                    unset( $field[ 'options' ][ 'sister_id' ] );
6203
                }
6204
6205
                if ( isset( $field[ 'options' ][ 'sister_field_id' ] ) )
6206
                    unset( $field[ 'options' ][ 'sister_field_id' ] );
6207
6208 View Code Duplication
                if ( pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6209
                    pods_transient_set( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $field[ 'name' ], $field );
6210
            }
6211
        }
6212
6213
        $field[ 'table_info' ] = array();
6214
6215
        if ( 'pick' == $field[ 'type' ] && $params->table_info )
6216
            $field[ 'table_info' ] = $this->get_table_info( $field[ 'pick_object' ], $field[ 'pick_val' ], null, null, $field );
6217
6218
        return $field;
6219
    }
6220
6221
    /**
6222
     * Load fields by Pod, ID, Name, and/or Type
6223
     *
6224
     * $params['pod_id'] int The Pod ID
6225
     * $params['pod'] string The Pod name
6226
     * $params['id'] array The field IDs
6227
     * $params['name'] array The field names
6228
     * $params['type'] array The field types
6229
     * $params['options'] array Field Option(s) key=>value array to filter by
6230
     * $params['where'] string WHERE clause of query
6231
     *
6232
     * @param array $params An associative array of parameters
6233
     * @param bool $strict  Whether to require a field exist or not when loading the info
6234
     *
6235
     * @return array Array of field data.
6236
     *
6237
     * @since 1.7.9
6238
     */
6239
    public function load_fields ( $params, $strict = false ) {
6240
		// @todo Get away from using md5/serialize, I'm sure we can cache specific parts
6241
	    $cache_key = md5( serialize( $params  ) );
6242
	    if ( isset( $this->fields_cache[ $cache_key ] ) ) {
6243
		    return $this->fields_cache[ $cache_key ];
6244
	    }
6245
6246
        $params = (object) pods_sanitize( $params );
6247
6248
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6249
            $params->pod = '';
6250
6251
        if ( !isset( $params->pod_id ) || empty( $params->pod_id ) )
6252
            $params->pod_id = 0;
6253
6254 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
6255
            $params->name = array();
6256
        else
6257
            $params->name = (array) $params->name;
6258
6259
        if ( !isset( $params->id ) || empty( $params->id ) )
6260
            $params->id = array();
6261
        else {
6262
            $params->id = (array) $params->id;
6263
6264
            foreach ( $params->id as &$id ) {
6265
                $id = pods_absint( $id );
6266
            }
6267
        }
6268
6269 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6270
            $params->type = array();
6271
        else
6272
            $params->type = (array) $params->type;
6273
6274
        $fields = array();
6275
6276
        if ( !empty( $params->pod ) || !empty( $params->pod_id ) ) {
6277
            $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => true ), false );
6278
6279
            if ( false === $pod ) {
6280
                if ( $strict )
6281
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
6282
6283
                return $fields;
6284
            }
6285
6286
			$pod[ 'fields' ] = array_merge( pods_var_raw( 'object_fields', $pod, array() ), $pod[ 'fields' ] );
6287
6288
            foreach ( $pod[ 'fields' ] as $field ) {
6289
                if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6290
                    $fields[ $field[ 'name' ] ] = $field;
6291
				elseif ( in_array( $fields[ 'name' ], $params->name ) || in_array( $fields[ 'id' ], $params->id ) || in_array( $fields[ 'type' ], $params->type ) )
6292
                    $fields[ $field[ 'name' ] ] = $field;
6293
            }
6294
        }
6295
        elseif ( ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) || ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) ) ) {
6296
            $order = 'ASC';
6297
            $orderby = 'menu_order title';
6298
            $limit = -1;
6299
            $ids = false;
6300
6301
            $meta_query = array();
6302
6303 View Code Duplication
            if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6304
                foreach ( $params->options as $option => $value ) {
6305
                    if ( !is_array( $value ) )
6306
                        $value = array( $value );
6307
6308
                    $value = pods_trim( $value );
6309
6310
                    sort( $value );
6311
6312
                    $meta_query[] = array(
6313
                        'key' => $option,
6314
                        'value' => pods_sanitize( $value ),
6315
                        'compare' => 'IN'
6316
                    );
6317
                }
6318
            }
6319
6320
            if ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) )
6321
                $meta_query = array_merge( $meta_query, (array) $params->where );
6322
6323
			$args = array(
6324
				'post_type' => '_pods_field',
6325
				'nopaging' => true,
6326
				'posts_per_page' => $limit,
6327
				'order' => $order,
6328
				'orderby' => $orderby,
6329
				'meta_query' => $meta_query,
6330
			);
6331
6332
			// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6333
			if ( false != $ids ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
6334
				$args[ 'post__in' ] = $ids;
6335
			}
6336
6337
            $fields = array();
6338
6339
            $_fields = get_posts( $args );
6340
6341
            foreach ( $_fields as $field ) {
6342
                $field = $this->load_field( $field, false );
6343
6344
                if ( !empty( $field ) )
6345
                    $fields[ $field[ 'id' ] ] = $field;
6346
            }
6347
        }
6348
        else {
6349 View Code Duplication
            if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6350
                return pods_error( __( 'Either Field Name / Field ID / Field Type, or Pod Name / Pod ID are required', 'pods' ), $this );
6351
6352
            $lookup = array();
6353
6354 View Code Duplication
            if ( !empty( $params->name ) ) {
6355
                $fields = implode( "', '", $params->name );
6356
6357
                $lookup[] = "`post_name` IN ( '{$fields}' )";
6358
            }
6359
6360 View Code Duplication
            if ( !empty( $params->id ) ) {
6361
                $fields = implode( ", ", $params->id );
6362
6363
                $lookup[] = "`ID` IN ( {$fields} )";
6364
            }
6365
6366
            $lookup = implode( ' AND ', $lookup );
6367
6368
            $result = pods_query( "SELECT `ID`, `post_name`, `post_parent` FROM `@wp_posts` WHERE `post_type` = '_pods_field' AND ( {$lookup} )" );
6369
6370
            $fields = array();
6371
6372
            if ( !empty( $result ) ) {
6373
                foreach ( $result as $field ) {
6374
					$field = $this->load_field( array(
6375
                        'id' => $field->ID,
6376
                        'name' => $field->post_name,
6377
                        'pod_id' => $field->post_parent
6378
                    ), false );
6379
6380
                    if ( !empty( $field ) && ( empty( $params->type ) || in_array( $field[ 'type' ], $params->type ) ) )
6381
                        $fields[ $field[ 'id' ] ] = $field;
6382
                }
6383
            }
6384
        }
6385
	    if ( isset( $cache_key ) ) {
6386
		    $this->fields_cache[ $cache_key ] = $fields;
6387
	    }
6388
        return $fields;
6389
    }
6390
6391
    /**
6392
     * Load a Pods Object
6393
     *
6394
     * $params['id'] int The Object ID
6395
     * $params['name'] string The Object name
6396
     * $params['type'] string The Object type
6397
     *
6398
     * @param array|object $params An associative array of parameters
6399
     * @param bool $strict
6400
     *
6401
     * @return array|bool
6402
     * @since 2.0
6403
     */
6404
    public function load_object ( $params, $strict = false ) {
6405
        if ( is_object( $params ) && isset( $params->post_title ) )
6406
            $_object = get_object_vars( $params );
6407
        else {
6408
            $params = (object) pods_sanitize( $params );
6409
6410 View Code Duplication
            if ( !isset( $params->type ) || empty( $params->type ) )
6411
                return pods_error( __( 'Object type is required', 'pods' ), $this );
6412
6413 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) )
6414
                return pods_error( __( 'Either Object ID or Name are required', 'pods' ), $this );
6415
6416
            /**
6417
             * @var $wpdb wpdb
6418
             */
6419
            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...
6420
6421
            if ( isset( $params->name ) )
6422
                $_object = pods_by_title( $params->name, ARRAY_A, '_pods_' . $params->type, 'publish' );
6423
            else {
6424
                $object = $params->id;
6425
6426
                $_object = get_post( $object, ARRAY_A );
6427
            }
6428
6429
            if ( empty( $_object ) ) {
6430
                if ( $strict )
6431
                    return pods_error( __( 'Object not found', 'pods' ), $this );
6432
6433
                return false;
6434
            }
6435
        }
6436
6437
        $object = array(
6438
            'id' => $_object[ 'ID' ],
6439
            'name' => $_object[ 'post_title' ],
6440
            'code' => $_object[ 'post_content' ],
6441
            'type' => str_replace( '_pods_', '', $_object[ 'post_type' ] ),
6442
            'slug' => $_object[ 'post_name' ]
6443
        );
6444
6445
        $object[ 'options' ] = get_post_meta( $object[ 'id' ] );
6446
6447
        foreach ( $object[ 'options' ] as $option => &$value ) {
6448
            if ( is_array( $value ) && 1 == count( $value ) )
6449
                $value = current( $value );
6450
        }
6451
6452
        return $object;
6453
    }
6454
6455
    /**
6456
     * Load Multiple Pods Objects
6457
     *
6458
     * $params['type'] string The Object type
6459
     * $params['options'] array Pod Option(s) key=>value array to filter by
6460
     * $params['orderby'] string ORDER BY clause of query
6461
     * $params['limit'] string Number of objects to return
6462
     * $params['where'] string WHERE clause of query
6463
     * $params['ids'] string|array IDs of Objects
6464
     *
6465
     * @param array|object $params An associative array of parameters
6466
     *
6467
     * @return array
6468
     * @since 2.0
6469
     */
6470
    public function load_objects ( $params ) {
6471
        $params = (object) pods_sanitize( $params );
6472
6473 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6474
            return pods_error( __( 'Pods Object type is required', 'pods' ), $this );
6475
6476
        $order = 'ASC';
6477
        $orderby = 'menu_order';
6478
        $limit = -1;
6479
        $ids = false;
6480
6481
        $meta_query = array();
6482
        $cache_key = '';
6483
6484 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6485
            foreach ( $params->options as $option => $value ) {
6486
                if ( !is_array( $value ) )
6487
                    $value = array( $value );
6488
6489
                $value = pods_trim( $value );
6490
6491
                sort( $value );
6492
6493
                $meta_query[] = array(
6494
                    'key' => $option,
6495
                    'value' => pods_sanitize( $value ),
6496
                    'compare' => 'IN'
6497
                );
6498
            }
6499
        }
6500
6501
        if ( isset( $params->where ) && is_array( $params->where ) )
6502
            $meta_query = array_merge( $meta_query, (array) $params->where );
6503
6504 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
6505
            $order = strtoupper( $params->order );
6506
6507
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
6508
            $orderby = strtoupper( $params->orderby );
6509
6510
        if ( isset( $params->limit ) && !empty( $params->limit ) )
6511
            $limit = pods_absint( $params->limit );
6512
6513
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
6514
            $ids = $params->ids;
6515
6516
            if ( !is_array( $ids ) )
6517
                $ids = explode( ',', $ids );
6518
        }
6519
6520
        if ( empty( $ids ) )
6521
            $ids = false;
6522
6523
        if ( pods_api_cache() && empty( $meta_query ) && empty( $limit ) && ( empty( $orderby ) || 'menu_order' == $orderby ) && empty( $ids ) ) {
6524
            $cache_key = 'pods_objects_' . $params->type;
6525
6526
            $the_objects = pods_transient_get( $cache_key );
6527
6528
            if ( false !== $the_objects )
6529
                return $the_objects;
6530
        }
6531
6532
        $the_objects = array();
6533
6534
		$args = array(
6535
			'post_type' => '_pods_' . $params->type,
6536
			'nopaging' => true,
6537
			'posts_per_page' => $limit,
6538
			'order' => $order,
6539
			'orderby' => $orderby,
6540
			'meta_query' => $meta_query,
6541
		);
6542
6543
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6544
		if ( false != $ids ) {
6545
			$args[ 'post__in' ] = $ids;
6546
		}
6547
6548
		$objects = get_posts( $args );
6549
6550
        foreach ( $objects as $object ) {
6551
            $object = $this->load_object( $object );
6552
6553
            $the_objects[ $object[ 'name' ] ] = $object;
6554
        }
6555
6556
        if ( pods_api_cache() && !empty( $cache_key ) )
6557
            pods_transient_set( $cache_key, $the_objects );
6558
6559
        return $the_objects;
6560
    }
6561
6562
    /**
6563
     * @see PodsAPI::load_object
6564
     *
6565
     * Load a Pod Template
6566
     *
6567
     * $params['id'] int The template ID
6568
     * $params['name'] string The template name
6569
     *
6570
     * @param array $params An associative array of parameters
6571
     *
6572
     * @return array|bool
6573
     * @since 1.7.9
6574
     */
6575
    public function load_template ( $params ) {
6576
        if ( !class_exists( 'Pods_Templates' ) )
6577
            return false;
6578
6579
        $params = (object) $params;
6580
        $params->type = 'template';
6581
        return $this->load_object( $params );
6582
    }
6583
6584
    /**
6585
     * @see PodsAPI::load_objects
6586
     *
6587
     * Load Multiple Pod Templates
6588
     *
6589
     * $params['where'] string The WHERE clause of query
6590
     * $params['options'] array Pod Option(s) key=>value array to filter by
6591
     * $params['orderby'] string ORDER BY clause of query
6592
     * $params['limit'] string Number of templates to return
6593
     *
6594
     * @param array $params (optional) An associative array of parameters
6595
     *
6596
     * @return array
6597
     *
6598
     * @since 2.0
6599
     */
6600
    public function load_templates ( $params = null ) {
6601
        if ( !class_exists( 'Pods_Templates' ) )
6602
            return array();
6603
6604
        $params = (object) $params;
6605
        $params->type = 'template';
6606
        return $this->load_objects( $params );
6607
    }
6608
6609
    /**
6610
     * @see PodsAPI::load_object
6611
     *
6612
     * Load a Pod Page
6613
     *
6614
     * $params['id'] int The page ID
6615
     * $params['name'] string The page URI
6616
     *
6617
     * @param array $params An associative array of parameters
6618
     *
6619
     * @return array|bool
6620
     *
6621
     * @since 1.7.9
6622
     */
6623
    public function load_page ( $params ) {
6624
        if ( !class_exists( 'Pods_Pages' ) )
6625
            return false;
6626
6627
        $params = (object) $params;
6628 View Code Duplication
        if ( !isset( $params->name ) && isset( $params->uri ) ) {
6629
            $params->name = $params->uri;
6630
            unset( $params->uri );
6631
        }
6632
        $params->type = 'page';
6633
        return $this->load_object( $params );
6634
    }
6635
6636
    /**
6637
     * @see PodsAPI::load_objects
6638
     *
6639
     * Load Multiple Pod Pages
6640
     *
6641
     * $params['where'] string The WHERE clause of query
6642
     * $params['options'] array Pod Option(s) key=>value array to filter by
6643
     * $params['orderby'] string ORDER BY clause of query
6644
     * $params['limit'] string Number of pages to return
6645
     *
6646
     * @param array $params (optional) An associative array of parameters
6647
     *
6648
     * @return array
6649
     *
6650
     * @since 2.0
6651
     */
6652
    public function load_pages ( $params = null ) {
6653
        if ( !class_exists( 'Pods_Pages' ) )
6654
            return array();
6655
6656
        $params = (object) $params;
6657
        $params->type = 'page';
6658
        return $this->load_objects( $params );
6659
    }
6660
6661
    /**
6662
     * @see PodsAPI::load_object
6663
     *
6664
     * Load a Pod Helper
6665
     *
6666
     * $params['id'] int The helper ID
6667
     * $params['name'] string The helper name
6668
     *
6669
     * @param array $params An associative array of parameters
6670
     *
6671
     * @return array|bool
6672
     *
6673
     * @since 1.7.9
6674
     */
6675 View Code Duplication
    public function load_helper ( $params ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
6676
        if ( !class_exists( 'Pods_Helpers' ) )
6677
            return false;
6678
6679
        $params = (object) $params;
6680
        $params->type = 'helper';
6681
        return $this->load_object( $params );
6682
    }
6683
6684
    /**
6685
     * @see PodsAPI::load_objects
6686
     *
6687
     * Load Multiple Pod Helpers
6688
     *
6689
     * $params['where'] string The WHERE clause of query
6690
     * $params['options'] array Pod Option(s) key=>value array to filter by
6691
     * $params['orderby'] string ORDER BY clause of query
6692
     * $params['limit'] string Number of pages to return
6693
     *
6694
     * @param array $params (optional) An associative array of parameters
6695
     *
6696
     * @return array
6697
     *
6698
     * @since 2.0
6699
     */
6700 View Code Duplication
    public function load_helpers ( $params = null ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
6701
        if ( !class_exists( 'Pods_Helpers' ) )
6702
            return array();
6703
6704
        $params = (object) $params;
6705
        $params->type = 'helper';
6706
        return $this->load_objects( $params );
6707
    }
6708
6709
    /**
6710
     * Load the pod item object
6711
     *
6712
     * $params['pod'] string The datatype name
6713
     * $params['id'] int (optional) The item's ID
6714
     *
6715
     * @param array $params An associative array of parameters
6716
     *
6717
     * @return bool|\Pods
6718
     *
6719
     * @uses pods()
6720
     *
6721
     * @since 2.0
6722
     */
6723
    public function load_pod_item ( $params ) {
6724
        $params = (object) pods_sanitize( $params );
6725
6726 View Code Duplication
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6727
            return pods_error( __( 'Pod name required', 'pods' ), $this );
6728 View Code Duplication
        if ( !isset( $params->id ) || empty( $params->id ) )
6729
            return pods_error( __( 'Item ID required', 'pods' ), $this );
6730
6731
        $pod = false;
6732
6733
        if ( pods_api_cache() )
6734
            $pod = pods_cache_get( $params->id, 'pods_item_object_' . $params->pod );
6735
6736
        if ( false !== $pod )
6737
            return $pod;
6738
6739
        $pod = pods( $params->pod, $params->id );
6740
6741
        if ( pods_api_cache() )
6742
            pods_cache_set( $params->id, $pod, 'pods_item_object_' . $params->pod );
6743
6744
        return $pod;
6745
    }
6746
6747
    /**
6748
     * Load potential sister fields for a specific field
6749
     *
6750
     * $params['pod'] int The Pod name
6751
     * $params['related_pod'] string The related Pod name
6752
     *
6753
     * @param array $params An associative array of parameters
6754
     * @param array $pod (optional) Array of Pod data to use (to avoid lookup)
6755
     *
6756
     * @return array|bool
6757
     *
6758
     * @since 1.7.9
6759
     *
6760
     * @uses PodsAPI::load_pod
6761
     */
6762
    public function load_sister_fields ( $params, $pod = null ) {
6763
        $params = (object) pods_sanitize( $params );
6764
6765
        if ( empty( $pod ) ) {
6766
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ), false );
6767
6768
            if ( false === $pod )
6769
                return pods_error( __( 'Pod not found', 'pods' ), $this );
6770
        }
6771
6772
        $params->pod_id = $pod[ 'id' ];
6773
        $params->pod = $pod[ 'name' ];
6774
6775
        $type = false;
6776
6777
        if ( 0 === strpos( $params->related_pod, 'pod-' ) ) {
6778
            $params->related_pod = pods_str_replace( 'pod-', '', $params->related_pod, 1 );
6779
            $type = 'pod';
6780
        }
6781 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'post_type-' ) ) {
6782
            $params->related_pod = pods_str_replace( 'post_type-', '', $params->related_pod, 1 );
6783
            $type = 'post_type';
6784
        }
6785 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'taxonomy-' ) ) {
6786
            $params->related_pod = pods_str_replace( 'taxonomy-', '', $params->related_pod, 1 );
6787
            $type = 'taxonomy';
6788
        }
6789
6790
        $related_pod = $this->load_pod( array( 'name' => $params->related_pod, 'table_info' => false ), false );
6791
6792
        if ( false === $related_pod || ( false !== $type && 'pod' != $type && $type != $related_pod[ 'type' ] ) )
6793
            return pods_error( __( 'Related Pod not found', 'pods' ), $this );
6794
6795
        $params->related_pod_id = $related_pod[ 'id' ];
6796
        $params->related_pod = $related_pod[ 'name' ];
6797
6798
        $sister_fields = array();
6799
6800
        foreach ( $related_pod[ 'fields' ] as $field ) {
6801
            if ( 'pick' == $field[ 'type' ] && in_array( $field[ 'pick_object' ], array( $pod[ 'type' ], 'pod' ) ) && ( $params->pod == $field[ 'pick_object' ] || $params->pod == $field[ 'pick_val' ] ) )
6802
                $sister_fields[ $field[ 'id' ] ] = esc_html( $field[ 'label' ] . ' (' . $field[ 'name' ] . ')' );
6803
        }
6804
6805
        return $sister_fields;
6806
    }
6807
6808
    /**
6809
     * Takes a sql field such as tinyint and returns the pods field type, such as num.
6810
     *
6811
     * @param string $sql_field The SQL field to look for
6812
     *
6813
     * @return string The field type
6814
     *
6815
     * @since 2.0
6816
     */
6817
    public static function detect_pod_field_from_sql_data_type ( $sql_field ) {
6818
        $sql_field = strtolower( $sql_field );
6819
6820
        $field_to_field_map = array(
6821
            'tinyint' => 'number',
6822
            'smallint' => 'number',
6823
            'mediumint' => 'number',
6824
            'int' => 'number',
6825
            'bigint' => 'number',
6826
            'float' => 'number',
6827
            'double' => 'number',
6828
            'decimal' => 'number',
6829
            'date' => 'date',
6830
            'datetime' => 'datetime',
6831
            'timestamp' => 'datetime',
6832
            'time' => 'time',
6833
            'year' => 'date',
6834
            'varchar' => 'text',
6835
            'text' => 'paragraph',
6836
            'mediumtext' => 'paragraph',
6837
            'longtext' => 'paragraph'
6838
        );
6839
6840
        return ( array_key_exists( $sql_field, $field_to_field_map ) ) ? $field_to_field_map[ $sql_field ] : 'paragraph';
6841
    }
6842
6843
    /**
6844
     * Gets all field types
6845
     *
6846
     * @return array Array of field types
6847
     *
6848
     * @uses PodsForm::field_loader
6849
     *
6850
     * @since 2.0
6851
     * @deprecated
6852
     */
6853
    public function get_field_types () {
6854
        return PodsForm::field_types();
6855
    }
6856
6857
    /**
6858
     * Gets the schema definition of a field.
6859
     *
6860
     * @param string $type Field type to look for
6861
     * @param array $options (optional) Options of the field to pass to the schema function.
6862
     *
6863
     * @return array|bool|mixed|null
6864
     *
6865
     * @since 2.0
6866
     */
6867
    private function get_field_definition ( $type, $options = null ) {
6868
        $definition = PodsForm::field_method( $type, 'schema', $options );
6869
6870
        return $this->do_hook( 'field_definition', $definition, $type, $options );
6871
    }
6872
6873
    /**
6874
     * @see PodsForm:validate
6875
     *
6876
     * Validates the value of a field.
6877
     *
6878
     * @param mixed $value The value to validate
6879
     * @param string $field Field to use for validation
6880
     * @param array $object_fields Fields of the object we're validating
6881
     * @param array $fields Array of all fields data
6882
     * @param array|Pods $pod Array of pod data (or Pods object)
6883
     * @param array|object $params Extra parameters to pass to the validation function of the field.
6884
     *
6885
     * @return array|bool
6886
     *
6887
     * @uses PodsForm::validate
6888
     *
6889
     * @since 2.0
6890
     */
6891
    public function handle_field_validation ( &$value, $field, $object_fields, $fields, $pod, $params ) {
6892
        $tableless_field_types = PodsForm::tableless_field_types();
6893
6894
        $fields = array_merge( $fields, $object_fields );
6895
6896
        $options = $fields[ $field ];
6897
6898
        $id = ( is_object( $params ) ? $params->id : ( is_object( $pod ) ? $pod->id() : 0 ) );
6899
6900
        if ( is_object( $pod ) )
6901
            $pod = $pod->pod_data;
6902
6903
        $type = $options[ 'type' ];
6904
        $label = $options[ 'label' ];
6905
        $label = empty( $label ) ? $field : $label;
6906
6907
        // Verify required fields
6908
        if ( 1 == pods_var( 'required', $options[ 'options' ], 0 ) && 'slug' != $type ) {
6909
            if ( '' == $value || null === $value || array() === $value )
6910
                return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this );
6911
6912
            if ( 'multi' == pods_var( 'pick_format_type', $options[ 'options' ] ) && 'autocomplete' != pods_var( 'pick_format_multi', $options[ 'options' ] ) ) {
6913
                $has_value = false;
6914
6915
                $check_value = (array) $value;
6916
6917
                foreach ( $check_value as $val ) {
6918
                    if ( '' != $val && null !== $val && 0 !== $val && '0' !== $val ) {
6919
                        $has_value = true;
6920
6921
                        continue;
6922
                    }
6923
                }
6924
6925
                if ( !$has_value )
6926
                    return pods_error( sprintf( __( '%s is required', 'pods' ), $label ), $this );
6927
            }
6928
6929
        }
6930
6931
        // @todo move this to after pre-save preparations
6932
        // Verify unique fields
6933
        if ( 1 == pods_var( 'unique', $options[ 'options' ], 0 ) && '' !== $value && null !== $value && array() !== $value ) {
6934
            if ( empty( $pod ) )
6935
                return false;
6936
6937
            if ( !in_array( $type, $tableless_field_types ) ) {
6938
                $exclude = '';
6939
6940
                if ( !empty( $id ) )
6941
                    $exclude = "AND `id` != {$id}";
6942
6943
                $check = false;
6944
6945
                $check_value = pods_sanitize( $value );
6946
6947
                // @todo handle meta-based fields
6948
                // Trigger an error if not unique
6949
                if ( 'table' == $pod[ 'storage' ] )
6950
                    $check = pods_query( "SELECT `id` FROM `@wp_pods_" . $pod[ 'name' ] . "` WHERE `{$field}` = '{$check_value}' {$exclude} LIMIT 1", $this );
6951
6952
                if ( !empty( $check ) )
6953
                    return pods_error( sprintf( __( '%s needs to be unique', 'pods' ), $label ), $this );
6954
            }
6955
            else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

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

These else branches can be removed.

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

could be turned into

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

This is much more concise to read.

Loading history...
6956
                // @todo handle tableless check
6957
            }
6958
        }
6959
6960
        $validate = PodsForm::validate( $options[ 'type' ], $value, $field, array_merge( $options, pods_var( 'options', $options, array() ) ), $fields, $pod, $id, $params );
6961
6962
        $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params );
6963
6964
        return $validate;
6965
    }
6966
6967
    /**
6968
     * Find items related to a parent field
6969
     *
6970
     * @param int $field_id The Field ID
6971
     * @param int $pod_id The Pod ID
6972
     * @param mixed $ids A comma-separated string (or array) of item IDs
6973
     * @param array $field Field data array
6974
     * @param array $pod Pod data array
6975
     *
6976
     * @return array
6977
     *
6978
     * @since 2.0
6979
     *
6980
     * @uses pods_query()
6981
     */
6982
    public function lookup_related_items ( $field_id, $pod_id, $ids, $field = null, $pod = null ) {
6983
        $related_ids = array();
6984
6985
        if ( !is_array( $ids ) )
6986
            $ids = explode( ',', $ids );
6987
6988
        foreach ( $ids as $k => $id ) {
6989
            $ids[ $k ] = (int) $id;
6990
        }
6991
6992
        $ids = array_unique( array_filter( $ids ) );
6993
6994
	    $idstring = implode( ',', $ids );
6995
	    if ( 0 != $pod_id && 0 != $field_id && isset( self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] ) ) {
6996
		    // Check cache first, no point in running the same query multiple times
6997
		    return self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ];
6998
	    }
6999
7000
        $tableless_field_types = PodsForm::tableless_field_types();
7001
7002
		$field_type = pods_v( 'type', $field );
7003
7004
        if ( empty( $ids ) || !in_array( $field_type, $tableless_field_types ) )
7005
            return array();
7006
7007
        $related_pick_limit = 0;
7008
7009
		if ( empty( $field ) ) {
7010
			$field = $this->load_field( array( 'id' => $field_id ) );
7011
		}
7012
7013
        if ( !empty( $field ) ) {
7014
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7015
7016
            $related_pick_limit = (int) pods_v( $field_type . '_limit', $options, 0 );
7017
7018
            if ( 'single' == pods_var_raw( $field_type . '_format_type', $options ) )
7019
                $related_pick_limit = 1;
7020
7021
            // Temporary hack until there's some better handling here
7022
            $related_pick_limit = $related_pick_limit * count( $ids );
7023
        }
7024
7025
		if ( 'taxonomy' == $field_type ) {
7026
			$related = wp_get_object_terms( $ids, pods_v( 'name', $field ), array( 'fields' => 'ids' ) );
7027
7028
			if ( !is_wp_error( $related ) ) {
7029
				$related_ids = $related;
7030
			}
7031
		}
7032
		elseif ( !pods_tableless() ) {
7033
            $ids = implode( ', ', $ids );
7034
7035
            $field_id = (int) $field_id;
7036
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7037
7038
            $related_where = "
7039
                `field_id` = {$field_id}
7040
                AND `item_id` IN ( {$ids} )
7041
            ";
7042
7043
            $sql = "
7044
                SELECT item_id, related_item_id, related_field_id
7045
                FROM `@wp_podsrel`
7046
                WHERE
7047
                    {$related_where}
7048
                ORDER BY `weight`
7049
            ";
7050
7051
            $relationships = pods_query( $sql );
7052
7053
            if ( !empty( $relationships ) ) {
7054
                foreach ( $relationships as $relation ) {
7055
                    if ( !in_array( $relation->related_item_id, $related_ids ) )
7056
                        $related_ids[] = (int) $relation->related_item_id;
7057
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->item_id, $related_ids ) )
7058
                        $related_ids[] = (int) $relation->item_id;
7059
                }
7060
            }
7061
        }
7062 View Code Duplication
        else {
7063
            if ( !is_array( $pod ) )
7064
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7065
7066
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
7067
                $meta_type = $pod[ 'type' ];
7068
7069
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
7070
                    $meta_type = 'post';
7071
                elseif ( 'taxonomy' == $meta_type )
7072
                    $meta_type = 'term';
7073
7074
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7075
7076
                if ( !$no_conflict )
7077
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7078
7079
                foreach ( $ids as $id ) {
7080
                    if ( 'settings' == $meta_type ) {
7081
                        $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7082
7083
                        if ( empty( $related_id ) )
7084
                            $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7085
7086
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
7087
                            foreach ( $related_id as $related ) {
7088
                                if ( is_array( $related ) && !empty( $related ) ) {
7089
                                    if ( isset( $related[ 'id' ] ) )
7090
                                        $related_ids[] = (int) $related[ 'id' ];
7091
                                    else {
7092
                                        foreach ( $related as $r ) {
7093
                                            $related_ids[] = (int) $r;
7094
                                        }
7095
                                    }
7096
                                }
7097
                                else
7098
                                    $related_ids[] = (int) $related;
7099
                            }
7100
                        }
7101
                    }
7102
                    else {
7103
                        $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7104
7105
                        if ( empty( $related_id ) )
7106
                            $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7107
7108
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
7109
                            foreach ( $related_id as $related ) {
7110
                                if ( is_array( $related ) && !empty( $related ) ) {
7111
                                    if ( isset( $related[ 'id' ] ) )
7112
                                        $related_ids[] = (int) $related[ 'id' ];
7113
                                    else {
7114
                                        foreach ( $related as $r ) {
7115
                                            if ( isset( $related[ 'id' ] ) )
7116
                                                $related_ids[] = (int) $r[ 'id' ];
7117
                                            else
7118
                                                $related_ids[] = (int) $r;
7119
                                        }
7120
                                    }
7121
                                }
7122
                                else
7123
                                    $related_ids[] = (int) $related;
7124
                            }
7125
                        }
7126
                    }
7127
                }
7128
7129
                if ( !$no_conflict )
7130
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7131
            }
7132
        }
7133
7134
        if ( is_array( $related_ids ) ) {
7135
            $related_ids = array_unique( array_filter( $related_ids ) );
7136
7137
            if ( 0 < $related_pick_limit && !empty( $related_ids ) )
7138
                $related_ids = array_slice( $related_ids, 0, $related_pick_limit );
7139
        }
7140
	    if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) {
7141
                    // Only cache if $pod_id and $field_id were passed
7142
		    self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] = $related_ids;
7143
	    }
7144
7145
        return $related_ids;
7146
    }
7147
7148
    /**
7149
     * Find related items related to an item
7150
     *
7151
     * @param int $field_id The Field ID
7152
     * @param int $pod_id The Pod ID
7153
     * @param int $id Item ID to get related IDs from
7154
     * @param array $field Field data array
7155
     * @param array $pod Pod data array
7156
     *
7157
     * @return array|bool
7158
     *
7159
     * @since 2.3
7160
     *
7161
     * @uses pods_query()
7162
     */
7163
    public function lookup_related_items_from ( $field_id, $pod_id, $id, $field = null, $pod = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $pod_id is not used and could be removed.

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

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

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

Loading history...
7164
        $related_ids = false;
7165
7166
        $id = (int) $id;
7167
7168
        $tableless_field_types = PodsForm::tableless_field_types();
7169
7170
        if ( empty( $id ) || !in_array( pods_v( 'type', $field ), $tableless_field_types ) )
7171
            return false;
7172
7173
        $related_pick_limit = 0;
7174
7175
        if ( !empty( $field ) ) {
7176
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7177
7178
            $related_pick_limit = (int) pods_v( 'pick_limit', $options, 0 );
7179
7180
            if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
7181
                $related_pick_limit = 1;
7182
        }
7183
7184
        if ( !pods_tableless() ) {
7185
            $field_id = (int) $field_id;
7186
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7187
7188
            $related_where = "
7189
                `field_id` = {$field_id}
7190
                AND `related_item_id` = {$id}
7191
            ";
7192
7193
            $sql = "
7194
                SELECT *
7195
                FROM `@wp_podsrel`
7196
                WHERE
7197
                    {$related_where}
7198
                ORDER BY `weight`
7199
            ";
7200
7201
            $relationships = pods_query( $sql );
7202
7203
            if ( !empty( $relationships ) ) {
7204
                $related_ids = array();
7205
7206
                foreach ( $relationships as $relation ) {
7207
                    if ( $field_id == $relation->field_id && !in_array( $relation->item_id, $related_ids ) )
7208
                        $related_ids[] = (int) $relation->item_id;
7209
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->related_item_id, $related_ids ) )
7210
                        $related_ids[] = (int) $relation->related_item_id;
7211
                }
7212
            }
7213
        }
7214 View Code Duplication
        else {
7215
            // @todo handle meta-based lookups
7216
            return false;
7217
7218
            if ( !is_array( $pod ) )
0 ignored issues
show
Unused Code introduced by
if (!is_array($pod)) { ...o' => false), false); } does not seem to be reachable.

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

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

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

    return false;
}

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

Loading history...
7219
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7220
7221
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
7222
                $related_ids = array();
7223
7224
                $meta_type = $pod[ 'type' ];
7225
7226
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
7227
                    $meta_type = 'post';
7228
                elseif ( 'taxonomy' == $meta_type )
7229
                    $meta_type = 'term';
7230
7231
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7232
7233
                if ( !$no_conflict )
7234
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7235
7236
                if ( 'settings' == $meta_type ) {
7237
                    $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7238
7239
                    if ( empty( $related_id ) )
7240
                        $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7241
7242
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7243
                        foreach ( $related_id as $related ) {
7244
                            if ( is_array( $related ) && !empty( $related ) ) {
7245
                                if ( isset( $related[ 'id' ] ) )
7246
                                    $related_ids[] = (int) $related[ 'id' ];
7247
                                else {
7248
                                    foreach ( $related as $r ) {
7249
                                        $related_ids[] = (int) $r;
7250
                                    }
7251
                                }
7252
                            }
7253
                            else
7254
                                $related_ids[] = (int) $related;
7255
                        }
7256
                    }
7257
                }
7258
                else {
7259
                    $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7260
7261
                    if ( empty( $related_id ) )
7262
                        $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7263
7264
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7265
                        foreach ( $related_id as $related ) {
7266
                            if ( is_array( $related ) && !empty( $related ) ) {
7267
                                if ( isset( $related[ 'id' ] ) )
7268
                                    $related_ids[] = (int) $related[ 'id' ];
7269
                                else {
7270
                                    foreach ( $related as $r ) {
7271
                                        if ( isset( $related[ 'id' ] ) )
7272
                                            $related_ids[] = (int) $r[ 'id' ];
7273
                                        else
7274
                                            $related_ids[] = (int) $r;
7275
                                    }
7276
                                }
7277
                            }
7278
                            else
7279
                                $related_ids[] = (int) $related;
7280
                        }
7281
                    }
7282
                }
7283
7284
                if ( !$no_conflict )
7285
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7286
            }
7287
        }
7288
7289
        if ( is_array( $related_ids ) )
7290
            $related_ids = array_unique( array_filter( $related_ids ) );
7291
7292
        return $related_ids;
7293
    }
7294
7295
	/**
7296
	 *
7297
	 * Load the information about an objects MySQL table
7298
	 *
7299
	 * @param $object_type
7300
	 * @param string $object The object to look for
7301
	 * @param null $name (optional) Name of the pod to load
7302
	 * @param array $pod (optional) Array with pod information
7303
	 *
7304
	 * @return array
7305
	 *
7306
	 * @since 2.5
7307
	 */
7308
	public function get_table_info_load ( $object_type, $object, $name = null, $pod = null ) {
7309
7310
		$info = array();
7311
7312
		if ( 'pod' == $object_type && null === $pod ) {
7313 View Code Duplication
			if ( empty( $name ) ) {
7314
				$prefix = 'pod-';
7315
7316
				// Make sure we actually have the prefix before trying anything with the name
7317
				if ( 0 === strpos( $object_type, $prefix ) )
7318
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7319
			}
7320
7321
			if ( empty( $name ) && !empty( $object ) )
7322
				$name = $object;
7323
7324
			$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7325
7326
			if ( !empty( $pod ) ) {
7327
				$object_type = $pod[ 'type' ];
7328
				$name = $pod[ 'name' ];
7329
				$object = $pod[ 'object' ];
7330
7331
				$info[ 'pod' ] = $pod;
7332
			}
7333
		}
7334
		elseif ( null === $pod ) {
7335
			if ( empty( $name ) ) {
7336
				$prefix = $object_type . '-';
7337
7338
				// Make sure we actually have the prefix before trying anything with the name
7339
				if ( 0 === strpos( $object_type, $prefix ) )
7340
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7341
			}
7342
7343
			if ( empty( $name ) && !empty( $object ) )
7344
				$name = $object;
7345
7346
			if ( !empty( $name ) ) {
7347
				$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7348
7349
				if ( !empty( $pod ) && ( null === $object_type || $object_type == $pod[ 'type' ] ) ) {
7350
					$object_type = $pod[ 'type' ];
7351
					$name = $pod[ 'name' ];
7352
					$object = $pod[ 'object' ];
7353
7354
					$info[ 'pod' ] = $pod;
7355
				}
7356
			}
7357
		}
7358
		elseif ( !empty( $pod ) )
7359
			$info[ 'pod' ] = $pod;
7360
7361
		if ( 0 === strpos( $object_type, 'pod' ) ) {
7362 View Code Duplication
			if ( empty( $name ) ) {
7363
				$prefix = 'pod-';
7364
7365
				// Make sure we actually have the prefix before trying anything with the name
7366
				if ( 0 === strpos( $object_type, $prefix ) )
7367
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7368
			}
7369
7370
			$info[ 'type' ] = 'pod';
7371
			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...
7372
7373
			$info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object );
7374
7375
			if ( is_array( $info[ 'pod' ] ) && 'pod' == pods_v( 'type', $info[ 'pod' ] ) ) {
7376
				$info[ 'pod_field_index' ] = $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_v( 'pod_index', $info[ 'pod' ][ 'options' ], 'id', true );
7377
7378
				$slug_field = get_posts( array(
7379
					'post_type' => '_pods_field',
7380
					'posts_per_page' => 1,
7381
					'nopaging' => true,
7382
					'post_parent' => $info[ 'pod' ][ 'id' ],
7383
					'orderby' => 'menu_order',
7384
					'order' => 'ASC',
7385
					'meta_query' => array(
7386
						array(
7387
							'key' => 'type',
7388
							'value' => 'slug',
7389
						)
7390
					)
7391
				) );
7392
7393
				if ( !empty( $slug_field ) ) {
7394
					$slug_field = $slug_field[ 0 ];
7395
7396
					$info[ 'field_slug' ] = $info[ 'pod_field_slug' ] = $slug_field->post_name;
7397
				}
7398
7399
				if ( 1 == pods_v( 'hierarchical', $info[ 'pod' ][ 'options' ], 0 ) ) {
7400
					$parent_field = pods_v( 'pod_parent', $info[ 'pod' ][ 'options' ], 'id', true );
7401
7402
					if ( !empty( $parent_field ) && isset( $info[ 'pod' ][ 'fields' ][ $parent_field ] ) ) {
7403
						$info[ 'object_hierarchical' ] = true;
7404
7405
						$info[ 'pod_field_parent' ] = $info[ 'field_parent' ] = $parent_field . '_select';
7406
						$info[ 'field_parent_select' ] = '`' . $parent_field . '`.`id` AS `' . $info[ 'field_parent' ] . '`';
7407
					}
7408
				}
7409
			}
7410
		}
7411
		return $info;
7412
	}
7413
7414
    /**
7415
     * Get information about an objects MySQL table
7416
     *
7417
     * @param string $object_type
7418
     * @param string $object The object to look for
7419
     * @param null $name (optional) Name of the pod to load
7420
     * @param array $pod (optional) Array with pod information
7421
     * @param array $field (optional) Array with field information
7422
     *
7423
     * @return array|bool
7424
     *
7425
     * @since 2.0
7426
     */
7427
    public function get_table_info ( $object_type, $object, $name = null, $pod = null, $field = null ) {
7428
7429
	    /**
7430
	     * @var $wpdb                         wpdb
7431
	     * @var $sitepress                    SitePress
7432
	     * @var $polylang                     object
7433
	     */
7434
	    /*
7435
	     * @todo wpml-comp Remove global object usage
7436
	     */
7437
        global $wpdb, $sitepress, $polylang;
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...
7438
7439
		// @todo Handle $object arrays for Post Types, Taxonomies, Comments (table pulled from first object in array)
7440
7441
        $info = array(
7442
            //'select' => '`t`.*',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
7443
            'object_type' => $object_type,
7444
            'type' => null,
7445
            'object_name' => $object,
7446
            'object_hierarchical' => false,
7447
7448
            'table' => $object,
7449
            'meta_table' => $object,
7450
            'pod_table' => $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object ),
7451
7452
            'field_id' => 'id',
7453
            'field_index' => 'name',
7454
            'field_slug' => null,
7455
            'field_type' => null,
7456
            'field_parent' => null,
7457
            'field_parent_select' => null,
7458
7459
            'meta_field_id' => 'id',
7460
            'meta_field_index' => 'name',
7461
            'meta_field_value' => 'name',
7462
7463
            'pod_field_id' => 'id',
7464
            'pod_field_index' => 'name',
7465
            'pod_field_slug' => null,
7466
            'pod_field_parent' => null,
7467
7468
            'join' => array(),
7469
7470
            'where' => null,
7471
            'where_default' => null,
7472
7473
            'orderby' => null,
7474
7475
            'pod' => null,
7476
            'recurse' => false
7477
        );
7478
7479
        if ( empty( $object_type ) ) {
7480
            $object_type = 'post_type';
7481
            $object = 'post';
7482
        }
7483
	    elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ) ) ) {
7484
		    $object = $object_type;
7485
	    }
7486
7487
        $pod_name = $pod;
7488
7489 View Code Duplication
        if ( is_array( $pod_name ) )
7490
            $pod_name = pods_var_raw( 'name', $pod_name, ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $pod_name, JSON_UNESCAPED_UNICODE ) : json_encode( $pod_name ) ), null, true );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

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

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

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

Loading history...
7491
	    else {
7492
		    $pod_name = $object;
7493
	    }
7494
7495
        $field_name = $field;
7496
7497 View Code Duplication
        if ( is_array( $field_name ) )
7498
            $field_name = pods_var_raw( 'name', $field_name, ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $pod_name, JSON_UNESCAPED_UNICODE ) : json_encode( $field_name ) ), null, true );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

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

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

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

Loading history...
7499
7500
        $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7501
7502
        $current_language = false;
7503
        $current_language_t_id = $current_language_tt_id = 0;
7504
7505
	    // Get current language data
7506
		$lang_data = self::get_current_language();
7507
7508
	    if ( $lang_data ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $lang_data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
7509
		    if ( ! empty( $lang_data['language'] ) ) {
7510
			    $current_language = $lang_data['language'];
7511
		    }
7512
7513
		    if ( ! empty( $lang_data['t_id'] ) ) {
7514
			    $current_language_t_id = $lang_data['t_id'];
7515
		    }
7516
7517
		    if ( ! empty( $lang_data['tt_id'] ) ) {
7518
			    $current_language_tt_id = $lang_data['tt_id'];
7519
		    }
7520
7521
		    if ( ! empty( $lang_data['tl_t_id'] ) ) {
7522
			    $current_language_tl_t_id = $lang_data['tl_t_id'];
7523
		    }
7524
7525
		    if ( ! empty( $lang_data['tl_tt_id'] ) ) {
7526
			    $current_language_tl_tt_id = $lang_data['tl_tt_id'];
7527
		    }
7528
	    }
7529
7530
        if ( !empty( $current_language ) )
7531
            $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7532
7533
        $_info = false;
7534
7535
	    if ( isset( self::$table_info_cache[ $transient ] ) ) {
7536
		    // Prefer info from the object internal cache
7537
		    $_info = self::$table_info_cache[ $transient ];
7538
	    } elseif ( pods_api_cache() ) {
7539
		    $_info = pods_transient_get( $transient );
7540
		    if ( false === $_info && ! did_action( 'init' ) ) {
7541
			    $_info = pods_transient_get( $transient . '_pre_init' );
7542
		    }
7543
	    }
7544
7545
	    if ( false !== $_info && is_array( $_info ) ) {
7546
		    // Data was cached, use that
7547
		    $info = $_info;
7548
	    } else {
7549
	        // Data not cached, load it up
7550
		    $_info = $this->get_table_info_load( $object_type, $object, $name, $pod );
7551
		    if ( isset( $_info[ 'type' ] ) ) {
7552
			    // Allow function to override $object_type
7553
			    $object_type = $_info[ 'type' ];
7554
		    }
7555
		    $info = array_merge( $info, $_info );
7556
	    }
7557
7558
	    if ( 0 === strpos( $object_type, 'post_type' ) || 'media' == $object_type || in_array( pods_var_raw( 'type', $info[ 'pod' ] ), array( 'post_type', 'media' ) ) ) {
7559
		    $info[ 'table' ] = $wpdb->posts;
7560
		    $info[ 'meta_table' ] = $wpdb->postmeta;
7561
7562
		    $info[ 'field_id' ] = 'ID';
7563
		    $info[ 'field_index' ] = 'post_title';
7564
		    $info[ 'field_slug' ] = 'post_name';
7565
		    $info[ 'field_type' ] = 'post_type';
7566
		    $info[ 'field_parent' ] = 'post_parent';
7567
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7568
7569
		    $info[ 'meta_field_id' ] = 'post_id';
7570
		    $info[ 'meta_field_index' ] = 'meta_key';
7571
		    $info[ 'meta_field_value' ] = 'meta_value';
7572
7573
		    if ( 'media' == $object_type )
7574
			    $object = 'attachment';
7575
7576
		    if ( empty( $name ) ) {
7577
			    $prefix = 'post_type-';
7578
7579
			    // Make sure we actually have the prefix before trying anything with the name
7580
			    if ( 0 === strpos( $object_type, $prefix ) )
7581
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7582
		    }
7583
7584
		    if ( 'media' != $object_type )
7585
			    $object_type = 'post_type';
7586
7587
		    $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7588
7589
		    if ( 'attachment' == $post_type || 'media' == $object_type )
7590
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_media';
7591
		    else
7592
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $post_type, true, false );
7593
7594
		    $post_type_object = get_post_type_object( $post_type );
7595
7596
		    if ( is_object( $post_type_object ) && $post_type_object->hierarchical )
7597
			    $info[ 'object_hierarchical' ] = true;
7598
7599
            // Post Status default
7600
            $post_status = array( 'publish' );
7601
7602
            // Pick field post_status option
7603
            if ( ! empty( $field['pick_post_status'] ) ) {
7604
                $post_status = (array) $field['pick_post_status'];
7605
            }
7606
7607
		    /**
7608
		     * Default Post Status to query for.
7609
		     *
7610
		     * Use to change "default" post status from publish to any other status or statuses.
7611
		     *
7612
		     * @param  array $post_status List of post statuses. Default is 'publish' or field setting (if available)
7613
		     * @param  string $post_type Post type of current object
7614
		     * @param  array $info Array of information about the object.
7615
		     * @param  string $object	Type of object
7616
		     * @param  string $name Name of pod to load
7617
		     * @param  array $pod Array with Pod information. Result of PodsAPI::load_pod()
7618
		     * @param  array $field		Array with field information
7619
		     *
7620
		     * @since unknown
7621
		     */
7622
		    $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', $post_status, $post_type, $info, $object_type, $object, $name, $pod, $field );
7623
7624
		    $info[ 'where' ] = array(
7625
			    //'post_status' => '`t`.`post_status` IN ( "inherit", "publish" )', // @todo Figure out what statuses Attachments can be
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
7626
			    'post_type' => '`t`.`' . $info[ 'field_type' ] . '` = "' . $post_type . '"'
7627
		    );
7628
7629
		    if ( 'post_type' == $object_type )
7630
			    $info[ 'where_default' ] = '`t`.`post_status` IN ( "' . implode( '", "', $post_status ) . '" )';
7631
7632
		    $info[ 'orderby' ] = '`t`.`menu_order`, `t`.`' . $info[ 'field_index' ] . '`, `t`.`post_date`';
7633
7634
            /*
7635
             * @todo wpml-comp Check if WPML filters can be applied afterwards
7636
             */
7637
		    // WPML support
7638
		    if ( did_action( 'wpml_loaded' ) && !empty( $current_language ) && apply_filters( 'wpml_is_translated_post_type', false, $post_type ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' )) {
7639
			    $info[ 'join' ][ 'wpml_translations' ] = "
7640
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7641
                            ON `wpml_translations`.`element_id` = `t`.`ID`
7642
                                AND `wpml_translations`.`element_type` = 'post_{$post_type}'
7643
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7644
                    ";
7645
7646
			    $info[ 'join' ][ 'wpml_languages' ] = "
7647
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7648
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7649
                    ";
7650
7651
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7652
		    }
7653
		    // Polylang support
7654 View Code Duplication
		    elseif( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && !empty( $current_language ) && function_exists( 'pll_is_translated_post_type' ) && pll_is_translated_post_type( $post_type ) ) {
7655
			    $info[ 'join' ][ 'polylang_languages' ] = "
7656
                        LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7657
                            ON `polylang_languages`.`object_id` = `t`.`ID`
7658
                                AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id}
7659
                    ";
7660
7661
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7662
		    }
7663
7664
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7665
	    }
7666
	    elseif ( 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, array( 'nav_menu', 'post_format' ) ) || 'taxonomy' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7667
		    $info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->terms;
7668
7669
		    $info[ 'join' ][ 'tt' ] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`";
7670
		    $info[ 'join' ][ 'tr' ] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`";
7671
		    $info[ 'field_id' ] = $info[ 'meta_field_id' ] = 'term_id';
7672
		    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = 'name';
7673
		    $info[ 'field_slug' ] = 'slug';
7674
		    $info[ 'field_type' ] = 'taxonomy';
7675
		    $info[ 'field_parent' ] = 'parent';
7676
		    $info[ 'field_parent_select' ] = '`tt`.`' . $info[ 'field_parent' ] . '`';
7677
7678
            if ( ! empty( $wpdb->termmeta ) ) {
7679
                $info[ 'meta_table' ] = $wpdb->termmeta;
7680
7681
                $info[ 'meta_field_id' ] = 'term_id';
7682
                $info[ 'meta_field_index' ] = 'meta_key';
7683
                $info[ 'meta_field_value' ] = 'meta_value';
7684
            }
7685
7686
		    if ( 'nav_menu' == $object_type )
7687
			    $object = 'nav_menu';
7688
		    elseif ( 'post_format' == $object_type )
7689
			    $object = 'post_format';
7690
7691
		    if ( empty( $name ) ) {
7692
			    $prefix = 'taxonomy-';
7693
7694
			    // Make sure we actually have the prefix before trying anything with the name
7695
			    if ( 0 === strpos( $object_type, $prefix ) )
7696
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7697
		    }
7698
7699
		    if ( !in_array( $object_type, array( 'nav_menu', 'post_format' ) ) )
7700
			    $object_type = 'taxonomy';
7701
7702
		    $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7703
7704
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $taxonomy, true, false );
7705
7706
		    $taxonomy_object = get_taxonomy( $taxonomy );
7707
7708
		    if ( is_object( $taxonomy_object ) && $taxonomy_object->hierarchical )
7709
			    $info[ 'object_hierarchical' ] = true;
7710
7711
		    $info[ 'where' ] = array(
7712
			    'tt.taxonomy' => '`tt`.`' . $info[ 'field_type' ] . '` = "' . $taxonomy . '"'
7713
		    );
7714
7715
            /*
7716
             * @todo wpml-comp WPML API call for is_translated_taxononomy
7717
             * @todo wpml-comp Check if WPML filters can be applied afterwards
7718
             */
7719
		    // WPML Support
7720
		    if ( is_object( $sitepress ) && !empty( $current_language ) && $sitepress->is_translated_taxonomy( $taxonomy ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
7721
			    $info[ 'join' ][ 'wpml_translations' ] = "
7722
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7723
                            ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id`
7724
                                AND `wpml_translations`.`element_type` = 'tax_{$taxonomy}'
7725
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7726
                    ";
7727
7728
			    $info[ 'join' ][ 'wpml_languages' ] = "
7729
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7730
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7731
                    ";
7732
7733
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7734
		    }
7735
		    // Polylang support
7736 View Code Duplication
		    elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && !empty( $current_language ) && !empty( $current_language_tl_tt_id ) && function_exists( 'pll_is_translated_taxonomy' ) && pll_is_translated_taxonomy( $taxonomy ) ) {
7737
				$info[ 'join' ][ 'polylang_languages' ] = "
7738
					LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7739
						ON `polylang_languages`.`object_id` = `t`.`term_id`
7740
							AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tl_tt_id}
7741
				";
7742
7743
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7744
		    }
7745
7746
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7747
	    }
7748
	    elseif ( 'user' == $object_type || 'user' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7749
		    $info[ 'table' ] = $wpdb->users;
7750
		    $info[ 'meta_table' ] = $wpdb->usermeta;
7751
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_user';
7752
7753
		    $info[ 'field_id' ] = 'ID';
7754
		    $info[ 'field_index' ] = 'display_name';
7755
		    $info[ 'field_slug' ] = 'user_nicename';
7756
7757
		    $info[ 'meta_field_id' ] = 'user_id';
7758
		    $info[ 'meta_field_index' ] = 'meta_key';
7759
		    $info[ 'meta_field_value' ] = 'meta_value';
7760
7761
		    $info[ 'where' ] = array(
7762
			    'user_status' => '`t`.`user_status` = 0'
7763
		    );
7764
7765
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7766
	    }
7767
	    elseif ( 'comment' == $object_type || 'comment' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7768
		    //$info[ 'object_hierarchical' ] = true;
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
7769
7770
		    $info[ 'table' ] = $wpdb->comments;
7771
		    $info[ 'meta_table' ] = $wpdb->commentmeta;
7772
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_comment';
7773
7774
		    $info[ 'field_id' ] = 'comment_ID';
7775
		    $info[ 'field_index' ] = 'comment_date';
7776
		    $info[ 'field_type' ] = 'comment_type';
7777
		    $info[ 'field_parent' ] = 'comment_parent';
7778
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7779
7780
		    $info[ 'meta_field_id' ] = 'comment_id';
7781
		    $info[ 'meta_field_index' ] = 'meta_key';
7782
		    $info[ 'meta_field_value' ] = 'meta_value';
7783
7784
		    $object = 'comment';
7785
7786
		    $comment_type = ( empty( $object ) ? $name : $object );
7787
7788
		    $comment_type_clause = '`t`.`' . $info[ 'field_type' ] . '` = "' . $comment_type . '"';
7789
7790
		    if ( 'comment' == $comment_type ) {
7791
			    $comment_type_clause = '( ' . $comment_type_clause . ' OR `t`.`' . $info[ 'field_type' ] . '` = "" )';
7792
		    }
7793
7794
		    $info[ 'where' ] = array(
7795
			    'comment_approved' => '`t`.`comment_approved` = 1',
7796
			    'comment_type' => $comment_type_clause
7797
		    );
7798
7799
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` DESC, `t`.`' . $info[ 'field_id' ] . '`';
7800
	    }
7801 View Code Duplication
	    elseif ( in_array( $object_type, array( 'option', 'settings' ) ) || 'settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7802
		    $info[ 'table' ] = $wpdb->options;
7803
		    $info[ 'meta_table' ] = $wpdb->options;
7804
7805
		    $info[ 'field_id' ] = 'option_id';
7806
		    $info[ 'field_index' ] = 'option_name';
7807
7808
		    $info[ 'meta_field_id' ] = 'option_id';
7809
		    $info[ 'meta_field_index' ] = 'option_name';
7810
		    $info[ 'meta_field_value' ] = 'option_value';
7811
7812
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7813
	    }
7814 View Code Duplication
	    elseif ( is_multisite() && ( in_array( $object_type, array( 'site_option', 'site_settings' ) ) || 'site_settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) ) {
7815
		    $info[ 'table' ] = $wpdb->sitemeta;
7816
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7817
7818
		    $info[ 'field_id' ] = 'site_id';
7819
		    $info[ 'field_index' ] = 'meta_key';
7820
7821
		    $info[ 'meta_field_id' ] = 'site_id';
7822
		    $info[ 'meta_field_index' ] = 'meta_key';
7823
		    $info[ 'meta_field_value' ] = 'meta_value';
7824
7825
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7826
	    }
7827
	    elseif ( is_multisite() && 'network' == $object_type ) { // Network = Site
7828
		    $info[ 'table' ] = $wpdb->site;
7829
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7830
7831
		    $info[ 'field_id' ] = 'id';
7832
		    $info[ 'field_index' ] = 'domain';
7833
7834
		    $info[ 'meta_field_id' ] = 'site_id';
7835
		    $info[ 'meta_field_index' ] = 'meta_key';
7836
		    $info[ 'meta_field_value' ] = 'meta_value';
7837
7838
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7839
	    }
7840
	    elseif ( is_multisite() && 'site' == $object_type ) { // Site = Blog
7841
		    $info[ 'table' ] = $wpdb->blogs;
7842
7843
		    $info[ 'field_id' ] = 'blog_id';
7844
		    $info[ 'field_index' ] = 'domain';
7845
		    $info[ 'field_type' ] = 'site_id';
7846
7847
		    $info[ 'where' ] = array(
7848
			    'archived' => '`t`.`archived` = 0',
7849
			    'spam' => '`t`.`spam` = 0',
7850
			    'deleted' => '`t`.`deleted` = 0',
7851
			    'site_id' => '`t`.`' . $info[ 'field_type' ] . '` = ' . (int) get_current_site()->id
7852
		    );
7853
7854
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7855
	    }
7856
	    elseif ( 'table' == $object_type || 'table' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7857
		    $info[ 'table' ] = ( empty( $object ) ? $name : $object );
7858
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . $info[ 'table' ];
7859
7860
		    if ( !empty( $field ) && is_array( $field ) ) {
7861
			    $info[ 'table' ] = pods_var_raw( 'pick_table', pods_var_raw( 'options', $field, $field ) );
7862
			    $info[ 'field_id' ] = pods_var_raw( 'pick_table_id', pods_var_raw( 'options', $field, $field ) );
7863
			    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_var_raw( 'pick_table_index', pods_var_raw( 'options', $field, $field ) );
7864
		    }
7865
	    }
7866
7867
	    $info[ 'table' ] = pods_clean_name( $info[ 'table' ], false, false );
7868
	    $info[ 'meta_table' ] = pods_clean_name( $info[ 'meta_table' ], false, false );
7869
	    $info[ 'pod_table' ] = pods_clean_name( $info[ 'pod_table' ], false, false );
7870
7871
	    $info[ 'field_id' ] = pods_clean_name( $info[ 'field_id' ], false, false );
7872
	    $info[ 'field_index' ] = pods_clean_name( $info[ 'field_index' ], false, false );
7873
	    $info[ 'field_slug' ] = pods_clean_name( $info[ 'field_slug' ], false, false );
7874
7875
	    $info[ 'meta_field_id' ] = pods_clean_name( $info[ 'meta_field_id' ], false, false );
7876
	    $info[ 'meta_field_index' ] = pods_clean_name( $info[ 'meta_field_index' ], false, false );
7877
	    $info[ 'meta_field_value' ] = pods_clean_name( $info[ 'meta_field_value' ], false, false );
7878
7879 View Code Duplication
	    if ( empty( $info[ 'orderby' ] ) )
7880
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '`, `t`.`' . $info[ 'field_id' ] . '`';
7881
7882
	    if ( 'table' == pods_var_raw( 'storage', $info[ 'pod' ] ) && !in_array( $object_type, array( 'pod', 'table' ) ) ) {
7883
		    $info[ 'join' ][ 'd' ] = 'LEFT JOIN `' . $info[ 'pod_table' ] . '` AS `d` ON `d`.`id` = `t`.`' . $info[ 'field_id' ] . '`';
7884
		    //$info[ 'select' ] .= ', `d`.*';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
7885
	    }
7886
7887
	    if ( !empty( $info[ 'pod' ] ) && is_array( $info[ 'pod' ] ) )
7888
		    $info[ 'recurse' ] = true;
7889
7890
	    $info[ 'type' ] = $object_type;
7891
	    $info[ 'object_name' ] = $object;
7892
7893
	    if ( pods_api_cache() ) {
7894
		    if ( ! did_action( 'init' ) ) {
7895
			    $transient .= '_pre_init';
7896
		    }
7897
		    pods_transient_set( $transient, $info );
7898
	    }
7899
7900
7901
	    self::$table_info_cache[ $transient ] = apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
7902
7903
        return self::$table_info_cache[ $transient ];
7904
    }
7905
7906
    /**
7907
     * Export a package
7908
     *
7909
     * $params['pod'] string Pod Type IDs to export
7910
     * $params['template'] string Template IDs to export
7911
     * $params['podpage'] string Pod Page IDs to export
7912
     * $params['helper'] string Helper IDs to export
7913
     *
7914
     * @param array $params An associative array of parameters
7915
     *
7916
     * @return array|bool
7917
     *
7918
     * @since 1.9.0
7919
     * @deprecated 2.0
7920
     */
7921
    public function export_package ( $params ) {
7922
        if ( class_exists( 'Pods_Migrate_Packages' ) )
7923
            return Pods_Migrate_Packages::export( $params );
7924
7925
        return false;
7926
    }
7927
7928
    /**
7929
     * Replace an existing package
7930
     *
7931
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
7932
     *
7933
     * @return bool
7934
     *
7935
     * @since 1.9.8
7936
     * @deprecated 2.0
7937
     */
7938
    public function replace_package ( $data = false ) {
7939
        return $this->import_package( $data, true );
0 ignored issues
show
Deprecated Code introduced by
The method PodsAPI::import_package() has been deprecated with message: 2.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
7940
    }
7941
7942
    /**
7943
     * Import a package
7944
     *
7945
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
7946
     * @param bool $replace (optional) Replace existing items when found
7947
     *
7948
     * @return bool
7949
     *
7950
     * @since 1.9.0
7951
     * @deprecated 2.0
7952
     */
7953
    public function import_package ( $data = false, $replace = false ) {
7954
        if ( class_exists( 'Pods_Migrate_Packages' ) )
7955
            return Pods_Migrate_Packages::import( $data, $replace );
7956
7957
        return false;
7958
    }
7959
7960
    /**
7961
     * Validate a package
7962
     *
7963
     * @param array|string $data (optional) An associative array containing a package, or the json encoded package
7964
     * @param bool $output (optional)
7965
     *
7966
     * @return array|bool
7967
     *
7968
     * @since 1.9.0
7969
     * @deprecated 2.0
7970
     */
7971
    public function validate_package ( $data = false, $output = false ) {
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

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

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

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

Loading history...
7972
        return true;
7973
    }
7974
7975
    /**
7976
     * Import data from an array or a CSV file.
7977
     *
7978
     * @param mixed $import_data PHP associative array or CSV input
7979
     * @param bool $numeric_mode Use IDs instead of the name field when matching
7980
     * @param string $format Format of import data, options are php or csv
7981
     *
7982
     * @return array IDs of imported items
7983
     *
7984
     * @since 1.7.1
7985
     * @todo This needs some love and use of table_info etc for relationships
7986
     */
7987
    public function import ( $import_data, $numeric_mode = false, $format = null ) {
7988
        /**
7989
         * @var $wpdb wpdb
7990
         */
7991
        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...
7992
7993
        if ( null === $format && null !== $this->format )
0 ignored issues
show
Deprecated Code introduced by
The property PodsAPI::$format has been deprecated with message: 2.0

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
7994
            $format = $this->format;
0 ignored issues
show
Deprecated Code introduced by
The property PodsAPI::$format has been deprecated with message: 2.0

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
7995
7996
        if ( 'csv' == $format && !is_array( $import_data ) ) {
7997
            $data = pods_migrate( 'sv', ',' )->parse( $import_data );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $data is correct as pods_migrate('sv', ',')->parse($import_data) (which targets PodsMigrate::parse()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
7998
7999
            $import_data = $data[ 'items' ];
8000
        }
8001
8002
        pods_query( "SET NAMES utf8" );
8003
        pods_query( "SET CHARACTER SET utf8" );
8004
8005
        // Loop through the array of items
8006
        $ids = array();
8007
8008
        // Test to see if it's an array of arrays
8009
        if ( !is_array( @current( $import_data ) ) )
8010
            $import_data = array( $import_data );
8011
8012
        $pod = $this->load_pod( array( 'name' => $this->pod ) );
8013
8014
        if ( false === $pod )
8015
            return pods_error( __( 'Pod not found', 'pods' ), $this );
8016
8017
        $fields = array_merge( $pod[ 'fields' ], $pod[ 'object_fields' ] );
8018
8019
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
8020
8021
        foreach ( $import_data as $key => $data_row ) {
8022
            $data = array();
8023
8024
            // Loop through each field (use $fields so only valid fields get parsed)
8025
            foreach ( $fields as $field_name => $field_data ) {
8026
                if ( !isset( $data_row[ $field_name ] ) && !isset( $data_row[ $field_data[ 'label' ] ] ) )
8027
                    continue;
8028
8029
                $field_id = $field_data[ 'id' ];
8030
                $type = $field_data[ 'type' ];
8031
                $pick_object = isset( $field_data[ 'pick_object' ] ) ? $field_data[ 'pick_object' ] : '';
8032
                $pick_val = isset( $field_data[ 'pick_val' ] ) ?  $field_data[ 'pick_val' ] : '';
8033
8034
                if ( isset( $data_row[ $field_name] ) )
8035
                    $field_value = $data_row[ $field_name ];
8036
                else
8037
                    $field_value = $data_row[ $field_data[ 'label' ] ];
8038
8039
                if ( null !== $field_value && false !== $field_value && '' !== $field_value ) {
8040
                    if ( 'pick' == $type || in_array( $type, PodsForm::file_field_types() ) ) {
8041
                        $field_values = is_array( $field_value ) ? $field_value : array( $field_value );
8042
                        $pick_values = array();
8043
8044
                        foreach ( $field_values as $pick_value ) {
8045
                            if ( in_array( $type, PodsForm::file_field_types() ) || 'media' == $pick_object ) {
8046
                                $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'";
8047
8048 View Code Duplication
                                if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8049
                                    $where = "`ID` = " . pods_absint( $pick_value );
8050
8051
                                $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = 'attachment' AND {$where} ORDER BY `ID`", $this );
8052
8053
                                if ( !empty( $result ) )
8054
                                    $pick_values[] = $result[ 0 ]->id;
8055
                            }
8056
                            // @todo This could and should be abstracted better and simplified
8057
                            elseif ( 'pick' == $type ) {
8058
                                $related_pod = false;
8059
8060
                                if ( 'pod' == $pick_object )
8061
                                    $related_pod = $this->load_pod( array( 'name' => $pick_val, 'table_info' => true ), false );
8062
8063
                                if ( empty( $related_pod ) ) {
8064
                                    $related_pod = array(
8065
                                        'id' => 0,
8066
                                        'type' => $pick_object
8067
                                    );
8068
                                }
8069
8070
                                if ( in_array( 'taxonomy', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8071
                                    $where = "`t`.`name` = '" . pods_sanitize( $pick_value ) . "'";
8072
8073 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8074
                                        $where = "`tt`.`term_id` = " . pods_absint( $pick_value );
8075
8076
                                    $result = pods_query( "SELECT `t`.`term_id` AS `id` FROM `{$wpdb->term_taxonomy}` AS `tt` LEFT JOIN `{$wpdb->terms}` AS `t` ON `t`.`term_id` = `tt`.`term_id` WHERE `taxonomy` = '{$pick_val}' AND {$where} ORDER BY `t`.`term_id`", $this );
8077
8078
                                    if ( !empty( $result ) )
8079
                                        $pick_values[] = $result[ 0 ]->id;
8080
                                }
8081
                                elseif ( in_array( 'post_type', array( $pick_object, $related_pod[ 'type' ] ) ) || in_array( 'media', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8082
                                    $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'";
8083
8084 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8085
                                        $where = "`ID` = " . pods_absint( $pick_value );
8086
8087
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = '{$pick_val}' AND {$where} ORDER BY `ID`", $this );
8088
8089
                                    if ( !empty( $result ) )
8090
                                        $pick_values[] = $result[ 0 ]->id;
8091
                                }
8092
                                elseif ( in_array( 'user', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8093
                                    $where = "`user_login` = '" . pods_sanitize( $pick_value ) . "'";
8094
8095 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8096
                                        $where = "`ID` = " . pods_absint( $pick_value );
8097
8098
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->users}` WHERE {$where} ORDER BY `ID`", $this );
8099
8100
                                    if ( !empty( $result ) )
8101
                                        $pick_values[] = $result[ 0 ]->id;
8102
                                }
8103
                                elseif ( in_array( 'comment', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8104
                                    $where = "`comment_ID` = " . pods_absint( $pick_value );
8105
8106
                                    $result = pods_query( "SELECT `comment_ID` AS `id` FROM `{$wpdb->comments}` WHERE {$where} ORDER BY `ID`", $this );
8107
8108
                                    if ( !empty( $result ) )
8109
                                        $pick_values[] = $result[ 0 ]->id;
8110
                                }
8111
                                elseif ( in_array( $pick_object, $simple_tableless_objects ) )
8112
                                    $pick_values[] = $pick_value;
8113
                                elseif ( !empty( $related_pod[ 'id' ] ) ) {
8114
                                    $where = "`" . $related_pod[ 'field_index' ] . "` = '" . pods_sanitize( $pick_value ) . "'";
8115
8116
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8117
                                        $where = "`" . $related_pod[ 'field_id' ] . "` = " . pods_absint( $pick_value );
8118
8119
                                    $result = pods_query( "SELECT `" . $related_pod[ 'field_id' ] . "` AS `id` FROM `" . $related_pod[ 'table' ] . "` WHERE {$where} ORDER BY `" . $related_pod[ 'field_id' ] . "`", $this );
8120
8121
                                    if ( !empty( $result ) )
8122
                                        $pick_values[] = $result[ 0 ]->id;
8123
                                }
8124
                            }
8125
                        }
8126
8127
                        $field_value = implode( ',', $pick_values );
8128
                    }
8129
8130
                    $data[ $field_name ] = $field_value;
8131
                }
8132
            }
8133
8134
            if ( !empty( $data ) ) {
8135
                $params = array(
8136
                    'pod' => $this->pod,
8137
                    'data' => $data
8138
                );
8139
8140
                $ids[] = $this->save_pod_item( $params );
8141
            }
8142
        }
8143
8144
        return $ids;
8145
    }
8146
8147
    /**
8148
     * Export data from a Pod
8149
     *
8150
     * @param string|object $pod The pod name or Pods object
8151
     * @param array $params An associative array of parameters
8152
     *
8153
     * @return array Data arrays of all exported pod items
8154
     * @since 1.7.1
8155
     */
8156
    public function export ( $pod = null, $params = null ) {
8157
8158
        if ( empty( $pod ) ) {
8159
            $pod = $this->pod;
8160
        }
8161
8162
        $find = array(
8163
            'limit' => -1,
8164
            'search' => false,
8165
            'pagination' => false
8166
        );
8167
8168
        if ( !empty( $params ) && isset( $params[ 'params' ] ) ) {
8169
            $find = array_merge( $find, (array) $params[ 'params' ] );
8170
8171
            unset( $params[ 'params' ] );
8172
8173
            $pod = pods( $pod, $find );
8174
        }
8175
        elseif ( !is_object( $pod ) ) {
8176
            $pod = pods( $pod, $find );
8177
        }
8178
8179
        $data = array();
8180
8181
        while ( $pod->fetch() ) {
8182
            $data[ $pod->id() ] = $this->export_pod_item( $params, $pod );
8183
        }
8184
8185
        $data = $this->do_hook( 'export', $data, $pod->pod, $pod );
8186
8187
        return $data;
8188
    }
8189
8190
    /**
8191
     * Convert CSV to a PHP array
8192
     *
8193
     * @param string $data The CSV input
8194
     *
8195
     * @return array
8196
     * @since 1.7.1
8197
     *
8198
     * @deprecated 2.3.5
8199
     */
8200
    public function csv_to_php ( $data, $delimiter = ',' ) {
8201
        pods_deprecated( "PodsAPI->csv_to_php", '2.3.5' );
8202
8203
        $data = pods_migrate( 'sv', $delimiter, $data )->parse();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $data is correct as pods_migrate('sv', $delimiter, $data)->parse() (which targets PodsMigrate::parse()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
8204
8205
        return $data[ 'items' ];
8206
    }
8207
8208
    /**
8209
     * Clear Pod-related cache
8210
     *
8211
     * @param array $pod
8212
     *
8213
     * @return void
8214
     *
8215
     * @since 2.0
8216
     */
8217
    public function cache_flush_pods ( $pod = null ) {
8218
        /**
8219
         * @var $wpdb wpdb
8220
         */
8221
        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...
8222
8223
        pods_transient_clear( 'pods' );
8224
        pods_transient_clear( 'pods_components' );
8225
8226
        if ( null !== $pod && is_array( $pod ) ) {
8227
            pods_transient_clear( 'pods_pod_' . $pod[ 'name' ] );
8228
            pods_cache_clear( $pod[ 'name' ], 'pods-class' );
8229
8230
            foreach ( $pod[ 'fields' ] as $field ) {
8231
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
8232
            }
8233
8234
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) )
8235
                pods_transient_clear( 'pods_wp_cpt_ct' );
8236
        }
8237
        else
8238
            pods_transient_clear( 'pods_wp_cpt_ct' );
8239
8240
        // Delete transients in the database
8241
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" );
8242
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" );
8243
8244
        // Delete Pods Options Cache in the database
8245
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_pods_option_%'" );
8246
8247
        pods_cache_clear( true );
8248
8249
        pods_transient_set( 'pods_flush_rewrites', 1 );
8250
8251
        do_action( 'pods_cache_flushed' );
8252
    }
8253
8254
    /**
8255
     * Process a Pod-based form
8256
     *
8257
     * @param mixed $params
8258
     * @param object $obj Pod object
8259
     * @param array $fields Fields being submitted in form ( key => settings )
8260
     * @param string $thank_you URL to send to upon success
8261
     *
8262
     * @return mixed
8263
     *
8264
     * @since 2.0
8265
     */
8266
    public function process_form ( $params, $obj = null, $fields = null, $thank_you = null ) {
8267
        $this->display_errors = false;
8268
8269
        $form = null;
8270
8271
        $nonce = pods_var( '_pods_nonce', $params );
8272
        $pod = pods_var( '_pods_pod', $params );
8273
        $id = pods_var( '_pods_id', $params );
8274
        $uri = pods_var( '_pods_uri', $params );
8275
        $form = pods_var( '_pods_form', $params );
8276
        $location = pods_var( '_pods_location', $params );
8277
8278
        if ( is_object( $obj ) ) {
8279
            $pod = $obj->pod;
8280
            $id = $obj->id();
8281
        }
8282
8283
        if ( !empty( $fields ) ) {
8284
            $fields = array_keys( $fields );
8285
            $form = implode( ',', $fields );
8286
        }
8287
        else
8288
            $fields = explode( ',', $form );
8289
8290
        if ( empty( $nonce ) || empty( $pod ) || empty( $uri ) || empty( $fields ) )
8291
            return pods_error( __( 'Invalid submission', 'pods' ), $this );
8292
8293
        $uid = @session_id();
8294
8295
        if ( is_user_logged_in() )
8296
            $uid = 'user_' . get_current_user_id();
8297
8298
		$field_hash = wp_create_nonce( 'pods_fields_' . $form );
8299
8300
        $action = 'pods_form_' . $pod . '_' . $uid . '_' . $id . '_' . $uri . '_' . $field_hash;
8301
8302
        if ( empty( $uid ) )
8303
            return pods_error( __( 'Access denied for your session, please refresh and try again.', 'pods' ), $this );
8304
8305
        if ( false === wp_verify_nonce( $nonce, $action ) )
8306
            return pods_error( __( 'Access denied, please refresh and try again.', 'pods' ), $this );
8307
8308
        $data = array();
8309
8310
        foreach ( $fields as $field ) {
8311
            $data[ $field ] = pods_var_raw( 'pods_field_' . $field, $params, '' );
8312
        }
8313
8314
        $params = array(
8315
            'pod' => $pod,
8316
            'id' => $id,
8317
            'data' => $data,
8318
            'from' => 'process_form',
8319
			'location' => $location
8320
        );
8321
8322
        $id = $this->save_pod_item( $params );
8323
8324
        if ( 0 < $id && !empty( $thank_you ) ) {
8325
            $thank_you = str_replace( 'X_ID_X', $id, $thank_you );
8326
8327
            pods_redirect( $thank_you );
8328
        }
8329
8330
        return $id;
8331
    }
8332
8333
	/**
8334
	 * Get current language information from Multilingual plugins
8335
	 *
8336
	 * @since 2.6.6
8337
	 *
8338
	 * @return array
8339
	 */
8340
	public static function get_current_language() {
8341
8342
		/**
8343
		 * @var $sitepress                    SitePress object
8344
		 * @var $polylang                     object
8345
		 */
8346
        /*
8347
         * @todo wpml-comp Remove global object usage
8348
         */
8349
		global $sitepress, $polylang;
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...
8350
8351
		$lang_data        = false;
8352
		$translator       = false;
8353
		$current_language = false;
8354
8355
		// Multilingual support
8356
		if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
8357
			// WPML support
8358
			$translator = 'WPML';
8359
8360
			// Get the global current language (if set)
8361
            $wpml_language = apply_filters( 'wpml_current_language', null );
8362
			$current_language = ( $wpml_language != 'all' ) ? $wpml_language : '';
8363
8364
		} elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && function_exists( 'pll_current_language' ) ) {
8365
			// Polylang support
8366
			$translator = 'PLL';
8367
8368
			// Get the global current language (if set)
8369
			$current_language = pll_current_language( 'slug' );
8370
		}
8371
8372
		/**
8373
		 * Admin functions that overwrite the current language
8374
		 *
8375
		 * @since 2.6.6
8376
		 */
8377
		if ( is_admin() && ! empty( $translator ) ) {
8378
			if ( $translator == 'PLL' ) {
8379
				/**
8380
				 * Polylang support
8381
				 * Get the current user's perferred language.
8382
				 * This is a user meta setting that will overwrite the language returned from pll_current_language()
8383
				 * @see polylang/admin/admin-base.php -> init_user()
8384
				 */
8385
				$current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true );
8386
			}
8387
8388
			// Get current language based on the object language if available
8389
			if ( function_exists( 'get_current_screen' ) ) {
8390
				$current_screen = get_current_screen();
8391
8392
				/**
8393
				 * Overwrite the current language if needed for post types
8394
				 */
8395
				if ( isset( $current_screen->base ) && ( $current_screen->base == 'post' || $current_screen->base == 'edit' ) ) {
8396
					if ( ! empty( $_GET['post'] ) ) {
8397
						/**
8398
						 * WPML support
8399
						 * In WPML the current language is always set to default on an edit screen
8400
						 * We need to overwrite this when the current object is not-translatable to enable relationships with different languages
8401
						 */
8402
						if (   $translator == 'WPML'
8403
							&& ! apply_filters( 'wpml_is_translated_post_type', false, ( get_post_type( $_GET['post'] ) ) )
8404
						) {
8405
							// Overwrite the current language to nothing if this is a NOT-translatable post_type
8406
							$current_language = '';
8407
						}
8408
8409
						/**
8410
						 * Polylang support (1.5.4+)
8411
						 * In polylang the preferred language could be anything.
8412
						 * We only want the related objects if they are not translatable OR the same language as the current object
8413
						 */
8414
						if (   $translator == 'PLL'
8415
							&& function_exists( 'pll_get_post_language' )
8416
							&& pll_is_translated_post_type( get_post_type( $_GET['post'] ) )
8417
						) {
8418
							// Overwrite the current language if this is a translateable post_type
8419
							$current_language = pll_get_post_language( (int) $_GET['post'] );
8420
						}
8421
					}
8422
8423
					/**
8424
					 * Polylang support (1.0.1+)
8425
					 * In polylang the preferred language could be anything.
8426
					 * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language
8427
					 */
8428 View Code Duplication
					if (   $translator == 'PLL'
8429
						&& ! empty( $_GET['new_lang'] )
8430
						&& ! empty( $_GET['post_type'] )
8431
						&& pll_is_translated_post_type( sanitize_text_field( $_GET['post_type'] ) )
8432
					) {
8433
						$current_language = $_GET['new_lang'];
8434
					}
8435
8436
				/**
8437
				 * Overwrite the current language if needed for taxonomies
8438
				 */
8439
				} elseif ( isset( $current_screen->base ) && ( $current_screen->base == 'term' || $current_screen->base == 'edit-tags' ) ) {
8440
					// @todo MAYBE: Similar function like get_post_type for taxonomies so we don't need to check for $_GET['taxonomy']
8441
					if ( ! empty( $_GET['taxonomy'] ) ) {
8442
					    /*
8443
					     * @todo wpml-comp API call for taxonomy needed!
8444
					     * Suggested API call:
8445
					     * add_filter( 'wpml_is_translated_taxonomy', $_GET['taxonomy'], 10, 2 );
8446
					     */
8447
						/**
8448
						 * WPML support
8449
						 * In WPML the current language is always set to default on an edit screen
8450
						 * We need to overwrite this when the current object is not-translatable to enable relationships with different languages
8451
						 */
8452
						if (   $translator == 'WPML'
8453
							&& method_exists( $sitepress, 'is_translated_taxonomy')
8454
							&& ! $sitepress->is_translated_taxonomy( $_GET['taxonomy'] )
8455
						) {
8456
							// Overwrite the current language to nothing if this is a NOT-translatable taxonomy
8457
							$current_language = '';
8458
						}
8459
8460
						/**
8461
						 * Polylang support (1.5.4+)
8462
						 * In polylang the preferred language could be anything.
8463
						 * We only want the related objects if they are not translatable OR the same language as the current object
8464
						 */
8465
						if (   $translator == 'PLL'
8466
							&& ! empty( $_GET['tag_ID'] )
8467
							&& function_exists( 'pll_get_term_language' )
8468
							&& pll_is_translated_taxonomy( sanitize_text_field( $_GET['taxonomy'] ) )
8469
						) {
8470
							// Overwrite the current language if this is a translatable taxonomy
8471
							$current_language = pll_get_term_language( (int) $_GET['tag_ID'] );
8472
						}
8473
					}
8474
8475
					/**
8476
					 * Polylang support (1.0.1+)
8477
					 * In polylang the preferred language could be anything.
8478
					 * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language
8479
					 */
8480 View Code Duplication
					if (   $translator == 'PLL'
8481
						&& ! empty( $_GET['new_lang'] )
8482
						&& ! empty( $_GET['taxonomy'] )
8483
						&& pll_is_translated_taxonomy( sanitize_text_field( $_GET['taxonomy'] ) )
8484
					) {
8485
						$current_language = $_GET['new_lang'];
8486
					}
8487
				}
8488
			}
8489
		}
8490
8491
		$current_language = pods_sanitize( sanitize_text_field( $current_language ) );
8492
8493
		if ( ! empty( $current_language ) ) {
8494
			// We need to return language data
8495
			$lang_data = array(
8496
				'language' => $current_language,
8497
				't_id'     => 0,
8498
				'tt_id'    => 0,
8499
				'term'     => null,
8500
			);
8501
8502
			/**
8503
			 * Polylang support
8504
			 * Get the language taxonomy object for the current language
8505
			 */
8506
			if ( $translator == 'PLL' ) {
8507
				$current_language_t = false;
8508
8509
				// Get the language term object
8510
				if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) {
8511
					// Polylang 1.8 and newer
8512
					$current_language_t = PLL()->model->get_language( $current_language );
8513
				} elseif ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) {
8514
					// Polylang 1.2 - 1.7.x
8515
					$current_language_t = $polylang->model->get_language( $current_language );
8516
				} elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) {
8517
					// Polylang 1.1.x and older
8518
					$current_language_t = $polylang->get_language( $current_language );
8519
				}
8520
8521
				// If the language object exists, add it!
8522
				if ( $current_language_t && ! empty( $current_language_t->term_id ) ) {
8523
					$lang_data['t_id']  = (int) $current_language_t->term_id;
8524
					$lang_data['tt_id'] = (int) $current_language_t->term_taxonomy_id;
8525
					$lang_data['tl_t_id'] = (int) $current_language_t->tl_term_id;
8526
					$lang_data['tl_tt_id'] = (int) $current_language_t->tl_term_taxonomy_id;
8527
					$lang_data['term']  = $current_language_t;
8528
				}
8529
			}
8530
		}
8531
8532
		/**
8533
		 * Override language data used by Pods.
8534
		 *
8535
		 * @since 2.6.6
8536
		 *
8537
		 * @param array|false    $lang_data {
8538
		 *      Language data
8539
		 *
8540
		 *      @type string       $language  Language slug
8541
		 *      @type int          $t_id      Language term_id
8542
		 *      @type int          $tt_id     Language term_taxonomy_id
8543
		 *      @type WP_Term      $term      Language term object
8544
		 * }
8545
		 * @param string|boolean $translator Language plugin used
8546
		 */
8547
		$lang_data = apply_filters( 'pods_get_current_language', $lang_data, $translator );
8548
8549
		return $lang_data;
8550
8551
	}
8552
8553
    /**
8554
     * Handle filters / actions for the class
8555
     *
8556
     * @since 2.0
8557
     */
8558 View Code Duplication
    private function do_hook () {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
8559
        $args = func_get_args();
8560
        if ( empty( $args ) )
8561
            return false;
8562
        $name = array_shift( $args );
8563
        return pods_do_hook( "api", $name, $args, $this );
8564
    }
8565
8566
    /**
8567
     * Handle variables that have been deprecated
8568
     *
8569
     * @since 2.0
8570
     */
8571
    public function __get ( $name ) {
8572
        $name = (string) $name;
8573
8574 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8575
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8576
            $this->deprecated = new PodsAPI_Deprecated( $this );
8577
        }
8578
8579
        $var = null;
8580
8581
        if ( isset( $this->deprecated->{$name} ) ) {
8582
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8583
8584
            $var = $this->deprecated->{$name};
8585
        }
8586
        else
8587
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8588
8589
        return $var;
8590
    }
8591
8592
    /**
8593
     * Handle methods that have been deprecated
8594
     *
8595
     * @since 2.0
8596
     */
8597
    public function __call ( $name, $args ) {
8598
        $name = (string) $name;
8599
8600 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8601
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8602
            $this->deprecated = new PodsAPI_Deprecated( $this );
8603
        }
8604
8605
        if ( method_exists( $this->deprecated, $name ) )
8606
            return call_user_func_array( array( $this->deprecated, $name ), $args );
8607
        else
8608
            pods_deprecated( "PodsAPI::{$name}", '2.0' );
8609
    }
8610
}
8611