Completed
Pull Request — 2.x (#4187)
by Scott Kingsley
06:00
created

PodsAPI::export_pod_item_level()   F

Complexity

Conditions 29
Paths 273

Size

Total Lines 101
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 29
eloc 59
nc 273
nop 5
dl 0
loc 101
rs 3.4833
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @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
                'comments' => array(
1078
                    'name' => 'comments',
1079
                    'label' => 'Comments',
1080
                    'type' => 'comment',
1081
					'pick_object' => 'comment',
1082
					'pick_val' => 'comment',
1083
                    'alias' => array(),
1084
                    'hidden' => true,
1085
					'options' => array(
1086
						'comment_format_type' => 'multi'
1087
					)
1088
                )
1089
            );
1090
1091
            if ( !empty( $pod ) ) {
1092
                $taxonomies = get_object_taxonomies( $pod_name, 'objects' );
1093
1094
                foreach ( $taxonomies as $taxonomy ) {
1095
                    $fields[ $taxonomy->name ] = array(
1096
                        'name' => $taxonomy->name,
1097
                        'label' => $taxonomy->labels->name,
1098
                        'type' => 'taxonomy',
1099
						'pick_object' => 'taxonomy',
1100
						'pick_val' => $taxonomy->name,
1101
                        'alias' => array(),
1102
                        'hidden' => true,
1103
						'options' => array(
1104
							'taxonomy_format_type' => 'multi'
1105
						)
1106
                    );
1107
                }
1108
            }
1109
        }
1110
        elseif ( 'user' == $object ) {
1111
            $fields = array(
1112
	            'ID' => array(
1113
		            'name' => 'ID',
1114
		            'label' => 'ID',
1115
		            'type' => 'number',
1116
		            'alias' => array( 'id' ),
1117
	                'options' => array(
1118
                        'number_format' => '9999.99'
1119
	                )
1120
	            ),
1121
                'user_login' => array(
1122
                    'name' => 'user_login',
1123
                    'label' => 'Title',
1124
                    'type' => 'text',
1125
                    'alias' => array( 'login' ),
1126
                    'options' => array(
1127
                        'required' => 1
1128
                    )
1129
                ),
1130
                'user_nicename' => array(
1131
                    'name' => 'user_nicename',
1132
                    'label' => 'Permalink',
1133
                    'type' => 'slug',
1134
                    'alias' => array( 'nicename', 'slug', 'permalink' )
1135
                ),
1136
                'display_name' => array(
1137
                    'name' => 'display_name',
1138
                    'label' => 'Display Name',
1139
                    'type' => 'text',
1140
                    'alias' => array( 'title', 'name' )
1141
                ),
1142
                'user_pass' => array(
1143
                    'name' => 'user_pass',
1144
                    'label' => 'Password',
1145
                    'type' => 'text',
1146
                    'alias' => array( 'password', 'pass' ),
1147
                    'options' => array(
1148
                        'required' => 1,
1149
                        'text_format_type' => 'password'
1150
                    )
1151
                ),
1152
                'user_email' => array(
1153
                    'name' => 'user_email',
1154
                    'label' => 'E-mail',
1155
                    'type' => 'text',
1156
                    'alias' => array( 'email' ),
1157
                    'options' => array(
1158
                        'required' => 1,
1159
                        'text_format_type' => 'email'
1160
                    )
1161
                ),
1162
                'user_url' => array(
1163
                    'name' => 'user_url',
1164
                    'label' => 'URL',
1165
                    'type' => 'text',
1166
                    'alias' => array( 'url', 'website' ),
1167
                    'options' => array(
1168
                        'required' => 0,
1169
                        'text_format_type' => 'website',
1170
                        'text_format_website' => 'normal'
1171
                    )
1172
                ),
1173
                'user_registered' => array(
1174
                    'name' => 'user_registered',
1175
                    'label' => 'Registration Date',
1176
                    'type' => 'date',
1177
                    'alias' => array( 'created', 'date', 'registered' ),
1178
                    'options' => array(
1179
                        'date_format_type' => 'datetime'
1180
                    )
1181
                )
1182
            );
1183
        }
1184
        elseif ( 'comment' == $object ) {
1185
            $fields = array(
1186
	            'comment_ID' => array(
1187
		            'name' => 'comment_ID',
1188
		            'label' => 'ID',
1189
		            'type' => 'number',
1190
		            'alias' => array( 'id', 'ID', 'comment_id' ),
1191
	                'options' => array(
1192
                        'number_format' => '9999.99'
1193
	                )
1194
	            ),
1195
                'comment_content' => array(
1196
                    'name' => 'comment_content',
1197
                    'label' => 'Content',
1198
                    'type' => 'wysiwyg',
1199
                    'alias' => array( 'content' )
1200
                ),
1201
                'comment_approved' => array(
1202
                    'name' => 'comment_approved',
1203
                    'label' => 'Approved',
1204
                    'type' => 'number',
1205
                    'alias' => array( 'approved' ),
1206
	                'options' => array(
1207
                        'number_format' => '9999.99'
1208
	                )
1209
                ),
1210
                'comment_post_ID' => array(
1211
                    'name' => 'comment_post_ID',
1212
                    'label' => 'Post',
1213
                    'type' => 'pick',
1214
                    'alias' => array( 'post', 'post_id' ),
1215
                    'data' => array()
1216
                ),
1217
                'user_id' => array(
1218
                    'name' => 'user_id',
1219
                    'label' => 'Author',
1220
                    'type' => 'pick',
1221
                    'alias' => array( 'author' ),
1222
                    'pick_object' => 'user',
1223
                    'data' => array()
1224
                ),
1225
                'comment_date' => array(
1226
                    'name' => 'comment_date',
1227
                    'label' => 'Date',
1228
                    'type' => 'date',
1229
                    'alias' => array( 'created', 'date' ),
1230
                    'options' => array(
1231
                        'date_format_type' => 'datetime'
1232
                    )
1233
                ),
1234
                'comment_author' => array(
1235
                    'name' => 'comment_author',
1236
                    'label' => 'Author',
1237
                    'type' => 'text',
1238
                    'alias' => array( 'author' )
1239
                ),
1240
                'comment_author_email' => array(
1241
                    'name' => 'comment_author_email',
1242
                    'label' => 'Author E-mail',
1243
                    'type' => 'email',
1244
                    'alias' => array( 'author_email' )
1245
                ),
1246
                'comment_author_url' => array(
1247
                    'name' => 'comment_author_url',
1248
                    'label' => 'Author URL',
1249
                    'type' => 'text',
1250
                    'alias' => array( 'author_url' )
1251
                ),
1252
                'comment_author_IP' => array(
1253
                    'name' => 'comment_author_IP',
1254
                    'label' => 'Author IP',
1255
                    'type' => 'text',
1256
                    'alias' => array( 'author_IP' )
1257
                ),
1258
                'comment_type' => array(
1259
                    'name' => 'comment_type',
1260
                    'label' => 'Type',
1261
                    'type' => 'text',
1262
                    'alias' => array( 'type' ),
1263
                    'hidden' => true
1264
                ),
1265
                'comment_parent' => array(
1266
                    'name' => 'comment_parent',
1267
                    'label' => 'Parent',
1268
                    'type' => 'pick',
1269
                    'pick_object' => 'comment',
1270
                    'pick_val' => '__current__',
1271
                    'alias' => array( 'parent' ),
1272
                    'data' => array(),
1273
                    'hidden' => true
1274
                )
1275
            );
1276
        }
1277
        elseif ( 'taxonomy' == $object ) {
1278
            $fields = array(
1279
	            'term_id' => array(
1280
		            'name' => 'term_id',
1281
		            'label' => 'ID',
1282
		            'type' => 'number',
1283
		            'alias' => array( 'id', 'ID' ),
1284
	                'options' => array(
1285
                        'number_format' => '9999.99'
1286
	                )
1287
	            ),
1288
                'name' => array(
1289
                    'name' => 'name',
1290
                    'label' => 'Title',
1291
                    'type' => 'text',
1292
                    'alias' => array( 'title' )
1293
                ),
1294
                'slug' => array(
1295
                    'name' => 'slug',
1296
                    'label' => 'Permalink',
1297
                    'type' => 'slug',
1298
                    'alias' => array( 'permalink' )
1299
                ),
1300
                'description' => array(
1301
                    'name' => 'description',
1302
                    'label' => 'Description',
1303
                    'type' => 'wysiwyg',
1304
                    'alias' => array( 'content' )
1305
                ),
1306
                'taxonomy' => array(
1307
                    'name' => 'taxonomy',
1308
                    'label' => 'Taxonomy',
1309
                    'type' => 'text',
1310
                    'alias' => array()
1311
                ),
1312
                'parent' => array(
1313
                    'name' => 'parent',
1314
                    'label' => 'Parent',
1315
                    'type' => 'pick',
1316
                    'pick_object' => 'taxonomy',
1317
                    'pick_val' => '__current__',
1318
                    'alias' => array( 'parent' ),
1319
                    'data' => array(),
1320
                    'hidden' => true
1321
                ),
1322
                'term_taxonomy_id' => array(
1323
                    'name' => 'term_taxonomy_id',
1324
                    'label' => 'Term Taxonomy ID',
1325
                    'type' => 'number',
1326
                    'alias' => array(),
1327
                    'hidden' => true,
1328
	                'options' => array(
1329
                        'number_format' => '9999.99'
1330
	                )
1331
                ),
1332
                'term_group' => array(
1333
                    'name' => 'term_group',
1334
                    'label' => 'Term Group',
1335
                    'type' => 'number',
1336
                    'alias' => array( 'group' ),
1337
                    'hidden' => true,
1338
	                'options' => array(
1339
                        'number_format' => '9999.99'
1340
	                )
1341
                ),
1342
                'count' => array(
1343
                    'name' => 'count',
1344
                    'label' => 'Count',
1345
                    'type' => 'number',
1346
                    'alias' => array(),
1347
                    'hidden' => true,
1348
	                'options' => array(
1349
                        'number_format' => '9999.99'
1350
	                )
1351
                )
1352
            );
1353
        }
1354
1355
        $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
1356
1357
        foreach ( $fields as $field => $options ) {
1358
            if ( !isset( $options[ 'alias' ] ) )
1359
                $options[ 'alias' ] = array();
1360
            else
1361
                $options[ 'alias' ] = (array) $options[ 'alias' ];
1362
1363
            if ( !isset( $options[ 'name' ] ) )
1364
                $options[ 'name' ] = $field;
1365
1366
            $fields[ $field ] = $options;
1367
        }
1368
1369
        $fields = PodsForm::fields_setup( $fields );
1370
1371 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
1372
            pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields );
1373
1374
        return $fields;
1375
    }
1376
1377
    /**
1378
     *
1379
     * @see PodsAPI::save_pod
1380
     *
1381
     * Add a Pod via the Wizard
1382
     *
1383
     * $params['create_extend'] string Create or Extend a Content Type
1384
     * $params['create_pod_type'] string Pod Type (for Creating)
1385
     * $params['create_name'] string Pod Name (for Creating)
1386
     * $params['create_label_plural'] string Plural Label (for Creating)
1387
     * $params['create_label_singular'] string Singular Label (for Creating)
1388
     * $params['create_storage'] string Storage Type (for Creating Post Types)
1389
     * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies)
1390
     * $params['extend_pod_type'] string Pod Type (for Extending)
1391
     * $params['extend_post_type'] string Post Type (for Extending Post Types)
1392
     * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies)
1393
     * $params['extend_storage'] string Storage Type (for Extending Post Types / Users / Comments)
1394
     *
1395
     * @param array $params An associative array of parameters
1396
     *
1397
     * @return bool|int Pod ID
1398
     * @since 2.0
1399
     */
1400
    public function add_pod ( $params ) {
1401
        $defaults = array(
1402
            'create_extend' => 'create',
1403
            'create_pod_type' => 'post_type',
1404
1405
            'create_name' => '',
1406
            'create_label_singular' => '',
1407
            'create_label_plural' => '',
1408
            'create_storage' => 'meta',
1409
            'create_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' ),
1410
1411
            'create_setting_name' => '',
1412
            'create_label_title' => '',
1413
            'create_label_menu' => '',
1414
            'create_menu_location' => 'settings',
1415
1416
            'extend_pod_type' => 'post_type',
1417
            'extend_post_type' => 'post',
1418
            'extend_taxonomy' => 'category',
1419
            'extend_table' => '',
1420
            'extend_storage' => 'meta',
1421
            'extend_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'table' ),
1422
        );
1423
1424
        $params = (object) array_merge( $defaults, (array) $params );
1425
1426
        if ( empty( $params->create_extend ) || !in_array( $params->create_extend, array( 'create', 'extend' ) ) )
1427
            return pods_error( __( 'Please choose whether to Create or Extend a Content Type', 'pods' ), $this );
1428
1429
        $pod_params = array(
1430
            'name' => '',
1431
            'label' => '',
1432
            'type' => '',
1433
            'storage' => 'table',
1434
            'object' => '',
1435
            'options' => array()
1436
        );
1437
1438
        if ( 'create' == $params->create_extend ) {
1439
            $label = ucwords( str_replace( '_', ' ', $params->create_name ) );
1440
1441
            if ( !empty( $params->create_label_singular ) )
1442
                $label = $params->create_label_singular;
1443
1444
            $pod_params[ 'name' ] = $params->create_name;
1445
            $pod_params[ 'label' ] = ( !empty( $params->create_label_plural ) ? $params->create_label_plural : $label );
1446
            $pod_params[ 'type' ] = $params->create_pod_type;
1447
            $pod_params[ 'options' ] = array(
1448
                'label_singular' => ( !empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params[ 'label' ] ),
1449
                'public' => 1,
1450
                'show_ui' => 1
1451
            );
1452
1453
            // Auto-generate name if not provided
1454
            if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'options' ][ 'label_singular' ] ) )
1455
                $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'options' ][ 'label_singular' ] );
1456
1457
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1458
                if ( empty(  $pod_params[ 'name' ] ) )
1459
                    return pods_error( 'Please enter a Name for this Pod', $this );
1460
1461
                $pod_params[ 'storage' ] = $params->create_storage;
1462
1463
                if ( pods_tableless() )
1464
                    $pod_params[ 'storage' ] = 'meta';
1465
            }
1466
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1467
                if ( empty(  $pod_params[ 'name' ] ) )
1468
                    return pods_error( 'Please enter a Name for this Pod', $this );
1469
1470
                $pod_params[ 'storage' ] = $params->create_storage_taxonomy;
1471
1472
                if ( pods_tableless() )
1473
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1474
1475
				$pod_params['options']['hierarchical'] = 1;
1476
            }
1477
            elseif ( 'pod' == $pod_params[ 'type' ] ) {
1478
                if ( empty(  $pod_params[ 'name' ] ) )
1479
                    return pods_error( 'Please enter a Name for this Pod', $this );
1480
1481
                if ( pods_tableless() ) {
1482
                    $pod_params[ 'type' ] = 'post_type';
1483
                    $pod_params[ 'storage' ] = 'meta';
1484
                }
1485
            }
1486
            elseif ( 'settings' == $pod_params[ 'type' ] ) {
1487
                $pod_params[ 'name' ] = $params->create_setting_name;
1488
                $pod_params[ 'label' ] = ( !empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) );
1489
                $pod_params[ 'options' ] = array(
1490
                    'menu_name' => ( !empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params[ 'label' ] ),
1491
                    'menu_location' => $params->create_menu_location
1492
                );
1493
                $pod_params[ 'storage' ] = 'none';
1494
1495
                // Auto-generate name if not provided
1496
                if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'label' ] ) )
1497
                    $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'label' ] );
1498
1499
                if ( empty( $pod_params[ 'name' ] ) )
1500
                    return pods_error( 'Please enter a Name for this Pod', $this );
1501
            }
1502
        }
1503
        elseif ( 'extend' == $params->create_extend ) {
1504
            $pod_params[ 'type' ] = $params->extend_pod_type;
1505
1506
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1507
                $pod_params[ 'storage' ] = $params->extend_storage;
1508
1509
                if ( pods_tableless() )
1510
                    $pod_params[ 'storage' ] = 'meta';
1511
1512
                $pod_params[ 'name' ] = $params->extend_post_type;
1513
            }
1514
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1515
                $pod_params[ 'storage' ] = $params->extend_storage_taxonomy;
1516
1517
                if ( pods_tableless() )
1518
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1519
1520
                $pod_params[ 'name' ] = $params->extend_taxonomy;
1521
            }
1522
            elseif ( 'table' == $pod_params[ 'type' ] ) {
1523
                $pod_params[ 'storage' ] = 'table';
1524
                $pod_params[ 'name' ] = $params->extend_table;
1525
            }
1526
            else {
1527
                $pod_params[ 'storage' ] = $params->extend_storage;
1528
1529
                if ( pods_tableless() )
1530
                    $pod_params[ 'storage' ] = 'meta';
1531
1532
                $pod_params[ 'name' ] = $params->extend_pod_type;
1533
            }
1534
1535
            $pod_params[ 'label' ] = ucwords( str_replace( '_', ' ', $pod_params[ 'name' ] ) );
1536
            $pod_params[ 'object' ] = $pod_params[ 'name' ];
1537
        }
1538
1539
        if ( empty( $pod_params[ 'object' ] ) ) {
1540
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1541
                $check = get_post_type_object( $pod_params[ 'name' ] );
1542
1543 View Code Duplication
                if ( !empty( $check ) )
1544
                    return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1545
1546
                $pod_params[ 'options' ][ 'supports_title' ] = 1;
1547
                $pod_params[ 'options' ][ 'supports_editor' ] = 1;
1548
            }
1549
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1550
                $check = get_taxonomy( $pod_params[ 'name' ] );
1551
1552 View Code Duplication
                if ( !empty( $check ) )
1553
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1554
            }
1555
        }
1556
1557
        if ( !empty( $pod_params ) )
1558
            return $this->save_pod( $pod_params );
1559
1560
        return false;
1561
    }
1562
1563
    /**
1564
     * Add or edit a Pod
1565
     *
1566
     * $params['id'] int The Pod ID
1567
     * $params['name'] string The Pod name
1568
     * $params['label'] string The Pod label
1569
     * $params['type'] string The Pod type
1570
     * $params['object'] string The object being extended (if any)
1571
     * $params['storage'] string The Pod storage
1572
     * $params['options'] array Options
1573
     *
1574
     * @param array $params An associative array of parameters
1575
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
1576
     * @param bool|int $db (optional) Whether to save into the DB or just return Pod array.
1577
     *
1578
     * @return int Pod ID
1579
     * @since 1.7.9
1580
     */
1581
    public function save_pod ( $params, $sanitized = false, $db = true ) {
1582
        $tableless_field_types = PodsForm::tableless_field_types();
1583
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
1584
1585
        $load_params = (object) $params;
1586
1587
        if ( isset( $load_params->id ) && isset( $load_params->name ) )
1588
            unset( $load_params->name );
1589
1590
        if ( isset( $load_params->old_name ) )
1591
            $load_params->name = $load_params->old_name;
1592
1593
        $load_params->table_info = true;
1594
1595
        $pod = $this->load_pod( $load_params, false );
1596
1597
        $params = (object) $params;
1598
1599
        if ( false === $sanitized )
1600
            $params = pods_sanitize( $params );
1601
1602
        $old_id = $old_name = $old_storage = null;
1603
1604
        $old_fields = $old_options = array();
1605
1606
		if ( isset( $params->name ) && ! isset( $params->object ) ) {
1607
			$params->name = pods_clean_name( $params->name );
1608
		}
1609
1610
        if ( !empty( $pod ) ) {
1611
            if ( isset( $params->id ) && 0 < $params->id )
1612
                $old_id = $params->id;
1613
1614
            $params->id = $pod[ 'id' ];
1615
1616
            $old_name = $pod[ 'name' ];
1617
            $old_storage = $pod[ 'storage' ];
1618
            $old_fields = $pod[ 'fields' ];
1619
            $old_options = $pod[ 'options' ];
1620
1621
            if ( !isset( $params->name ) && empty( $params->name ) )
1622
                $params->name = $pod[ 'name' ];
1623
1624
            if ( $old_name != $params->name && false !== $this->pod_exists( array( 'name' => $params->name ) ) )
1625
                return pods_error( sprintf( __( 'Pod %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1626
1627
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'user', 'comment', 'media' ) ) && in_array( $pod[ 'object' ], array( 'user', 'comment', 'media' ) ) )
1628
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1629
1630
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && !empty( $pod[ 'object' ] ) && $pod[ 'object' ] == $old_name )
1631
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1632
1633
            if ( $old_id != $params->id ) {
1634
                if ( $params->type == $pod[ 'type' ] && isset( $params->object ) && $params->object == $pod[ 'object' ] )
1635
                    return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this );
1636
                else
1637
                    return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this );
1638
            }
1639
        }
1640
		elseif ( in_array( $params->name, array( 'order','orderby','post_type' ) ) && 'post_type' == pods_var( 'type', $params ) ) {
1641
			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 );
1642
		}
1643
        else {
1644
            $pod = array(
1645
                'id' => 0,
1646
                'name' => $params->name,
1647
                'label' => $params->name,
1648
                'description' => '',
1649
                'type' => 'pod',
1650
                'storage' => 'table',
1651
                'object' => '',
1652
                'alias' => '',
1653
                'options' => array(),
1654
                'fields' => array()
1655
            );
1656
        }
1657
1658
        // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite)
1659
        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1660
            $pod[ 'fields' ] = array();
1661
            $pod[ 'options' ] = array();
1662
        }
1663
1664
        // Setup options
1665
        $options = get_object_vars( $params );
1666
1667
        if ( isset( $options[ 'method' ] ) )
1668
            unset( $options[ 'method' ] );
1669
1670
        $options_ignore = array(
1671
            'object_type',
1672
            'object_name',
1673
            'table',
1674
            'meta_table',
1675
            'pod_table',
1676
            'field_id',
1677
            'field_index',
1678
            'field_slug',
1679
            'field_type',
1680
            'field_parent',
1681
            'field_parent_select',
1682
            'meta_field_id',
1683
            'meta_field_index',
1684
            'meta_field_value',
1685
            'pod_field_id',
1686
            'pod_field_index',
1687
            'object_fields',
1688
            'join',
1689
            'where',
1690
            'where_default',
1691
            'orderby',
1692
            'pod',
1693
            'recurse',
1694
            'table_info',
1695
            'attributes',
1696
            'group',
1697
            'grouped',
1698
            'developer_mode',
1699
            'dependency',
1700
            'depends-on',
1701
            'excludes-on'
1702
        );
1703
1704
        foreach ( $options_ignore as $ignore ) {
1705
            if ( isset( $options[ $ignore ] ) )
1706
                unset( $options[ $ignore ] );
1707
        }
1708
1709
        $exclude = array(
1710
            'id',
1711
            'name',
1712
            'label',
1713
            'description',
1714
            'type',
1715
            'storage',
1716
            'object',
1717
            'alias',
1718
            'options',
1719
            'fields'
1720
        );
1721
1722 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
1723
            $aliases = array( $exclude_field );
1724
1725
            if ( is_array( $exclude_field ) ) {
1726
                $aliases = array_merge( array( $k ), $exclude_field );
1727
                $exclude_field = $k;
1728
            }
1729
1730
            foreach ( $aliases as $alias ) {
1731
                if ( isset( $options[ $alias ] ) ) {
1732
                    $pod[ $exclude_field ] = pods_trim( $options[ $alias ] );
1733
1734
                    unset( $options[ $alias ] );
1735
                }
1736
            }
1737
        }
1738
1739
        if ( pods_tableless() && !in_array( $pod[ 'type' ], array( 'settings', 'table' ) ) ) {
1740
            if ( 'pod' == $pod[ 'type' ] )
1741
                $pod[ 'type' ] = 'post_type';
1742
1743 View Code Duplication
            if ( 'table' == $pod[ 'storage' ] ) {
1744
                if ( 'taxonomy' == $pod[ 'type' ] && ! function_exists( 'get_term_meta' ) )
1745
                    $pod[ 'storage' ] = 'none';
1746
                else
1747
                    $pod[ 'storage' ] = 'meta';
1748
            }
1749
        }
1750
1751
        $pod[ 'options' ][ 'type' ] = $pod[ 'type' ];
1752
        $pod[ 'options' ][ 'storage' ] = $pod[ 'storage' ];
1753
        $pod[ 'options' ][ 'object' ] = $pod[ 'object' ];
1754
        $pod[ 'options' ][ 'alias' ] = $pod[ 'alias' ];
1755
1756
        $pod[ 'options' ] = array_merge( $pod[ 'options' ], $options );
1757
1758
		/**
1759
		 * @var WP_Query
1760
		 */
1761
		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...
1762
1763
		$reserved_query_vars = array(
1764
			'post_type',
1765
			'taxonomy',
1766
			'output'
1767
		);
1768
1769
		if ( is_object( $wp_query ) ) {
1770
			$reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
1771
		}
1772
1773 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var_string' ] ) ) {
1774
			if ( in_array( $pod[ 'options' ][ 'query_var_string' ], $reserved_query_vars ) ) {
1775
				$pod[ 'options' ][ 'query_var_string' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var_string' ];
1776
			}
1777
		}
1778
1779 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var' ] ) ) {
1780
			if ( in_array( $pod[ 'options' ][ 'query_var' ], $reserved_query_vars ) ) {
1781
				$pod[ 'options' ][ 'query_var' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var' ];
1782
			}
1783
		}
1784
1785
        if ( strlen( $pod[ 'label' ] ) < 1 )
1786
            $pod[ 'label' ] = $pod[ 'name' ];
1787
1788
        if ( 'post_type' == $pod[ 'type' ] ) {
1789
            // Max length for post types are 20 characters
1790
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 20 );
1791
        }
1792
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1793
            // Max length for taxonomies are 32 characters
1794
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 32 );
1795
        }
1796
1797
        $params->id = $pod[ 'id' ];
1798
        $params->name = $pod[ 'name' ];
1799
1800
        if ( null !== $old_name && $old_name != $params->name && empty( $pod[ 'object' ] ) ) {
1801
            if ( 'post_type' == $pod[ 'type' ] ) {
1802
                $check = get_post_type_object( $params->name );
1803
1804 View Code Duplication
                if ( !empty( $check ) )
1805
                    return pods_error( sprintf( __( 'Post Type %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1806
            }
1807
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1808
                $check = get_taxonomy( $params->name );
1809
1810 View Code Duplication
                if ( !empty( $check ) )
1811
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1812
            }
1813
        }
1814
1815
        $field_table_operation = true;
1816
1817
        // Add new pod
1818
        if ( empty( $params->id ) ) {
1819
            if ( strlen( $params->name ) < 1 )
1820
                return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this );
1821
1822
            $post_data = array(
1823
                'post_name' => $pod[ 'name' ],
1824
                'post_title' => $pod[ 'label' ],
1825
                'post_content' => $pod[ 'description' ],
1826
                'post_type' => '_pods_pod',
1827
                'post_status' => 'publish'
1828
            );
1829
1830
            if ( 'pod' == $pod[ 'type' ] && ( !is_array( $pod[ 'fields' ] ) || empty( $pod[ 'fields' ] ) ) ) {
1831
                $pod[ 'fields' ] = array();
1832
1833
                $pod[ 'fields' ][ 'name' ] = array(
1834
                    'name' => 'name',
1835
                    'label' => 'Name',
1836
                    'type' => 'text',
1837
                    'options' => array(
1838
                        'required' => '1'
1839
                    )
1840
                );
1841
1842
                $pod[ 'fields' ][ 'created' ] = array(
1843
                    'name' => 'created',
1844
                    'label' => 'Date Created',
1845
                    'type' => 'datetime',
1846
                    'options' => array(
1847
                        'datetime_format' => 'ymd_slash',
1848
                        'datetime_time_type' => '12',
1849
                        'datetime_time_format' => 'h_mm_ss_A'
1850
                    )
1851
                );
1852
1853
                $pod[ 'fields' ][ 'modified' ] = array(
1854
                    'name' => 'modified',
1855
                    'label' => 'Date Modified',
1856
                    'type' => 'datetime',
1857
                    'options' => array(
1858
                        'datetime_format' => 'ymd_slash',
1859
                        'datetime_time_type' => '12',
1860
                        'datetime_time_format' => 'h_mm_ss_A'
1861
                    )
1862
                );
1863
1864
                $pod[ 'fields' ][ 'author' ] = array(
1865
                    'name' => 'author',
1866
                    'label' => 'Author',
1867
                    'type' => 'pick',
1868
                    'pick_object' => 'user',
1869
                    'options' => array(
1870
                        'pick_format_type' => 'single',
1871
                        'pick_format_single' => 'autocomplete',
1872
                        'default_value' => '{@user.ID}'
1873
                    )
1874
                );
1875
1876
                $pod[ 'fields' ][ 'permalink' ] = array(
1877
                    'name' => 'permalink',
1878
                    'label' => 'Permalink',
1879
                    'type' => 'slug',
1880
                    'description' => 'Leave blank to auto-generate from Name'
1881
                );
1882
1883
                if ( !isset( $pod[ 'options' ][ 'pod_index' ] ) )
1884
                    $pod[ 'options' ][ 'pod_index' ] = 'name';
1885
            }
1886
1887
            $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db );
1888
1889
            $field_table_operation = false;
1890
        }
1891
        else {
1892
            $post_data = array(
1893
                'ID' => $pod[ 'id' ],
1894
                'post_name' => $pod[ 'name' ],
1895
                'post_title' => $pod[ 'label' ],
1896
                'post_content' => $pod[ 'description' ],
1897
                'post_status' => 'publish'
1898
            );
1899
        }
1900
1901
        if ( true === $db ) {
1902
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
1903
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
1904
1905
            $conflicted = false;
1906
1907
            // Headway compatibility fix
1908
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
1909
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1910
1911
                $conflicted = true;
1912
            }
1913
1914
            $params->id = $this->save_wp_object( 'post', $post_data, $pod[ 'options' ], true, true );
1915
1916
            if ( $conflicted )
1917
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1918
1919
            if ( false === $params->id )
1920
                return pods_error( __( 'Cannot save Pod', 'pods' ), $this );
1921
        }
1922
        elseif ( empty( $params->id ) )
1923
            $params->id = (int) $db;
1924
1925
        $pod[ 'id' ] = $params->id;
1926
1927
        // Setup / update tables
1928
        if ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $old_storage != $pod[ 'storage' ] && $db ) {
1929
            $definitions = array( "`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY" );
1930
1931
            $defined_fields = array();
1932
1933
            foreach ( $pod[ 'fields' ] as $field ) {
1934
                if ( !is_array( $field ) || !isset( $field[ 'name' ] ) || in_array( $field[ 'name' ], $defined_fields ) )
1935
                    continue;
1936
1937
                $defined_fields[] = $field[ 'name' ];
1938
1939
                if ( !in_array( $field[ 'type' ], $tableless_field_types ) || ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) ) {
1940
                    $definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, pods_var_raw( 'options', $field, array() ) ) );
1941
1942
                    if ( 0 < strlen( $definition ) )
1943
                        $definitions[] = "`{$field['name']}` " . $definition;
1944
                }
1945
            }
1946
1947
            pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`" );
1948
1949
            $result = pods_query( "CREATE TABLE `@wp_pods_{$params->name}` (" . implode( ', ', $definitions ) . ") DEFAULT CHARSET utf8", $this );
1950
1951
            if ( empty( $result ) )
1952
                return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this );
1953
1954
        }
1955
        elseif ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $pod[ 'storage' ] == $old_storage && null !== $old_name && $old_name != $params->name && $db ) {
1956
            $result = pods_query( "ALTER TABLE `@wp_pods_{$old_name}` RENAME `@wp_pods_{$params->name}`", $this );
1957
1958
            if ( empty( $result ) )
1959
                return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this );
1960
        }
1961
1962
        /**
1963
         * @var $wpdb wpdb
1964
         */
1965
        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...
1966
1967
		if ( null !== $old_name && $old_name != $params->name && $db ) {
1968
        	// Rename items in the DB pointed at the old WP Object names
1969
			if ( 'post_type' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1970
				$this->rename_wp_object_type( 'post', $old_name, $params->name );
1971
			}
1972 View Code Duplication
			elseif ( 'taxonomy' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1973
				$this->rename_wp_object_type( 'taxonomy', $old_name, $params->name );
1974
			}
1975 View Code Duplication
			elseif ( 'comment' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1976
				$this->rename_wp_object_type( 'comment', $old_name, $params->name );
1977
			}
1978
			elseif ( 'settings' == $pod[ 'type' ] ) {
1979
				$this->rename_wp_object_type( 'settings', $old_name, $params->name );
1980
			}
1981
1982
        	// Sync any related fields if the name has changed
1983
            $fields = pods_query( "
1984
                SELECT `p`.`ID`
1985
                FROM `{$wpdb->posts}` AS `p`
1986
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1987
                LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID`
1988
                WHERE
1989
                    `p`.`post_type` = '_pods_field'
1990
                    AND `pm`.`meta_key` = 'pick_object'
1991
                    AND (
1992
                    	`pm`.`meta_value` = 'pod'
1993
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "'
1994
					)
1995
                    AND `pm2`.`meta_key` = 'pick_val'
1996
                    AND `pm2`.`meta_value` = '{$old_name}'
1997
            " );
1998
1999 View Code Duplication
            if ( !empty( $fields ) ) {
2000
                foreach ( $fields as $field ) {
2001
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
2002
                    update_post_meta( $field->ID, 'pick_val', $params->name );
2003
                }
2004
            }
2005
2006
            $fields = pods_query( "
2007
                SELECT `p`.`ID`
2008
                FROM `{$wpdb->posts}` AS `p`
2009
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
2010
                WHERE
2011
                    `p`.`post_type` = '_pods_field'
2012
                    AND `pm`.`meta_key` = 'pick_object'
2013
                    AND (
2014
                    	`pm`.`meta_value` = 'pod-{$old_name}'
2015
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "-{$old_name}'
2016
					)
2017
            " );
2018
2019 View Code Duplication
            if ( !empty( $fields ) ) {
2020
                foreach ( $fields as $field ) {
2021
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
2022
                    update_post_meta( $field->ID, 'pick_val', $params->name );
2023
                }
2024
            }
2025
        }
2026
2027
        // Sync built-in options for post types and taxonomies
2028
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) && $db ) {
2029
            // Build list of 'built_in' for later
2030
            $built_in = array();
2031
2032
            foreach ( $pod[ 'options' ] as $key => $val ) {
2033
                if ( false === strpos( $key, 'built_in_' ) )
2034
                    continue;
2035
                elseif ( false !== strpos( $key, 'built_in_post_types_' ) )
2036
                    $built_in_type = 'post_type';
2037
                elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) )
2038
                    $built_in_type = 'taxonomy';
2039
                else
2040
                    continue;
2041
2042
                if ( $built_in_type == $pod[ 'type' ] )
2043
                    continue;
2044
2045
                if ( !isset( $built_in[ $built_in_type ] ) )
2046
                    $built_in[ $built_in_type ] = array();
2047
2048
                $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key );
2049
2050
                $built_in[ $built_in_type ][ $built_in_object ] = (int) $val;
2051
            }
2052
2053
            $lookup_option = $lookup_built_in = false;
2054
2055
            $lookup_name = $pod[ 'name' ];
2056
2057
            if ( 'post_type' == $pod[ 'type' ] ) {
2058
                $lookup_option = 'built_in_post_types_' . $lookup_name;
2059
                $lookup_built_in = 'taxonomy';
2060
            }
2061
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
2062
                $lookup_option = 'built_in_taxonomies_' . $lookup_name;
2063
                $lookup_built_in = 'post_type';
2064
            }
2065
2066
            if ( !empty( $lookup_option ) && !empty( $lookup_built_in ) && isset( $built_in[ $lookup_built_in ] ) ) {
2067
                foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) {
2068
                    $search_val = 1;
2069
2070
                    if ( 1 == $val )
2071
                        $search_val = 0;
2072
2073
                    $query = "SELECT p.ID FROM {$wpdb->posts} AS p
2074
                                LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}'
2075
                                LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}'
2076
                                LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = ''
2077
                                WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}'
2078
                                    AND pm2.meta_id IS NOT NULL
2079
                                    AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )";
2080
2081
                    $results = pods_query( $query );
2082
2083
                    if ( !empty( $results ) ) {
2084
                        foreach ( $results as $the_pod ) {
2085
                            delete_post_meta( $the_pod->ID, $lookup_option );
2086
2087
                            add_post_meta( $the_pod->ID, $lookup_option, $val );
2088
                        }
2089
                    }
2090
                }
2091
            }
2092
        }
2093
2094
        $saved = array();
2095
        $errors = array();
2096
2097
        $field_index_change = false;
2098
        $field_index_id = 0;
2099
2100
        $id_required = false;
2101
2102
        $field_index = pods_var( 'pod_index', $pod[ 'options' ], 'id', null, true );
2103
2104
        if ( 'pod' == $pod[ 'type' ] && !empty( $pod[ 'fields' ] ) && isset( $pod[ 'fields' ][ $field_index ] ) )
2105
            $field_index_id = $pod[ 'fields' ][ $field_index ];
2106
2107
        if ( isset( $params->fields ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
2108
            $fields = array();
2109
2110
            if ( isset( $params->fields ) ) {
2111
                $params->fields = (array) $params->fields;
2112
2113
                $weight = 0;
2114
2115
                foreach ( $params->fields as $field ) {
2116
                    if ( !is_array( $field ) || !isset( $field[ 'name' ] ) )
2117
                        continue;
2118
2119
                    if ( !isset( $field[ 'weight' ] ) ) {
2120
                        $field[ 'weight' ] = $weight;
2121
2122
                        $weight++;
2123
                    }
2124
2125
                    $fields[ $field[ 'name' ] ] = $field;
2126
                }
2127
            }
2128
2129
            $weight = 0;
2130
2131
            $saved_field_ids = array();
2132
2133
            foreach ( $pod[ 'fields' ] as $k => $field ) {
2134
                if ( !empty( $old_id ) && ( !is_array( $field ) || !isset( $field[ 'name' ] ) || !isset( $fields[ $field[ 'name' ] ] ) ) ) {
2135
                    // Iterative change handling for setup-edit.php
2136
                    if ( !is_array( $field ) && isset( $old_fields[ $k ] ) )
2137
                        $saved[ $old_fields[ $k ][ 'name' ] ] = true;
2138
2139
                    continue;
2140
                }
2141
2142
                if ( !empty( $old_id ) )
2143
                    $field = array_merge( $field, $fields[ $field[ 'name' ] ] );
2144
2145
                $field[ 'pod' ] = $pod;
2146
2147
                if ( !isset( $field[ 'weight' ] ) ) {
2148
                    $field[ 'weight' ] = $weight;
2149
2150
                    $weight++;
2151
                }
2152
2153
                if ( 0 < $field_index_id && pods_var( 'id', $field ) == $field_index_id )
2154
                    $field_index_change = $field[ 'name' ];
2155
2156
                if ( 0 < pods_var( 'id', $field ) )
2157
                    $id_required = true;
2158
2159
                if ( $id_required )
2160
                    $field[ 'id_required' ] = true;
2161
2162
                $field_data = $field;
2163
2164
                $field = $this->save_field( $field_data, $field_table_operation, true, $db );
2165
2166
                if ( true !== $db ) {
2167
                    $pod[ 'fields' ][ $k ] = $field;
2168
                    $saved_field_ids[] = $field[ 'id' ];
2169
                }
2170
                else {
2171
                    if ( !empty( $field ) && 0 < $field ) {
2172
                        $saved[ $field_data[ 'name' ] ] = true;
2173
                        $saved_field_ids[] = $field;
2174
                    }
2175
                    else
2176
                        $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data[ 'name' ] );
2177
                }
2178
            }
2179
2180
            if ( true === $db ) {
2181
                foreach ( $old_fields as $field ) {
2182
                    if ( isset( $pod[ 'fields' ][ $field[ 'name' ] ] ) || isset( $saved[ $field[ 'name' ] ] ) || in_array( $field[ 'id' ], $saved_field_ids ) )
2183
                        continue;
2184
2185
                    if ( $field[ 'id' ] == $field_index_id )
2186
                        $field_index_change = 'id';
2187
                    elseif ( $field[ 'name' ] == $field_index )
2188
                        $field_index_change = 'id';
2189
2190
                    $this->delete_field( array(
2191
                        'id' => (int) $field[ 'id' ],
2192
                        'name' => $field[ 'name' ],
2193
                        'pod' => $pod
2194
                    ), $field_table_operation );
2195
                }
2196
            }
2197
2198
            // Update field index if the name has changed or the field has been removed
2199
            if ( false !== $field_index_change && true === $db )
2200
                update_post_meta( $pod[ 'id' ], 'pod_index', $field_index_change );
2201
        }
2202
2203
        if ( !empty( $errors ) )
2204
            return pods_error( $errors, $this );
2205
2206
        $this->cache_flush_pods( $pod );
2207
2208
		$refresh_pod = $this->load_pod( array( 'name' => $pod['name'] ), false );
2209
2210
		if ( $refresh_pod ) {
2211
			$pod = $refresh_pod;
2212
		}
2213
2214
		if ( 'post_type' == $pod['type'] ) {
2215
			PodsMeta::$post_types[ $pod['id'] ] = $pod;
2216
		} elseif ( 'taxonomy' == $pod['type'] ) {
2217
			PodsMeta::$taxonomies[ $pod['id'] ] = $pod;
2218
		} elseif ( 'media' == $pod['type'] ) {
2219
			PodsMeta::$media[ $pod['id'] ] = $pod;
2220
		} elseif ( 'user' == $pod['type'] ) {
2221
			PodsMeta::$user[ $pod['id'] ] = $pod;
2222
		} elseif ( 'comment' == $pod['type'] ) {
2223
			PodsMeta::$comment[ $pod['id'] ] = $pod;
2224
		}
2225
2226
        // Register Post Types / Taxonomies post-registration from PodsInit
2227
        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...
2228
            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...
2229
2230
            $pods_init->setup_content_types( true );
2231
        }
2232
2233
        if ( true === $db )
2234
            return $pod[ 'id' ];
2235
        else
2236
            return $pod;
2237
    }
2238
2239
    /**
2240
     * Add or edit a field within a Pod
2241
     *
2242
     * $params['id'] int Field ID (id OR pod_id+pod+name required)
2243
     * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
2244
     * $params['pod'] string Pod name (id OR pod_id+pod+name required)
2245
     * $params['name'] string Field name (id OR pod_id+pod+name required)
2246
     * $params['label'] string (optional) Field label
2247
     * $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)
2248
     * $params['pick_object'] string (optional) Related Object (for relationships)
2249
     * $params['pick_val'] string (optional) Related Object name (for relationships)
2250
     * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
2251
     * $params['weight'] int (optional) Order in which the field appears
2252
     * $params['options'] array (optional) Options
2253
     *
2254
     * @param array $params An associative array of parameters
2255
     * @param bool $table_operation (optional) Whether or not to handle table operations
2256
     * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2257
     * @param bool|int $db (optional) Whether to save into the DB or just return field array.
2258
     *
2259
     * @return int|array The field ID or field array (if !$db)
2260
     * @since 1.7.9
2261
     */
2262
    public function save_field ( $params, $table_operation = true, $sanitized = false, $db = true ) {
2263
        /**
2264
         * @var $wpdb wpdb
2265
         */
2266
        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...
2267
2268
        if ( true !== $db )
2269
            $table_operation = false;
2270
2271
        $tableless_field_types = PodsForm::tableless_field_types();
2272
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
2273
2274
        $params = (object) $params;
2275
2276
        if ( false === $sanitized )
2277
            $params = pods_sanitize( $params );
2278
2279
        if ( isset( $params->pod_id ) )
2280
            $params->pod_id = pods_absint( $params->pod_id );
2281
2282
        if ( true !== $db )
2283
            $params->pod_id = (int) $db;
2284
2285
        $pod = null;
2286
        $save_pod = false;
2287
        $id_required = false;
2288
2289
        if ( isset( $params->id_required ) ) {
2290
            unset( $params->id_required );
2291
2292
            $id_required = true;
2293
        }
2294
2295 View Code Duplication
        if ( ( !isset( $params->pod ) || empty( $params->pod ) ) && ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) )
2296
            return pods_error( __( 'Pod ID or name is required', 'pods' ), $this );
2297
2298
        if ( isset( $params->pod ) && is_array( $params->pod ) ) {
2299
            $pod = $params->pod;
2300
2301
            $save_pod = true;
2302
        }
2303 View Code Duplication
        elseif ( ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) )
2304
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
2305 View Code Duplication
        elseif ( !isset( $params->pod ) && ( true === $db || 0 < $db ) )
2306
            $pod = $this->load_pod( array( 'id' => $params->pod_id, 'table_info' => true ) );
2307 View Code Duplication
        elseif ( true === $db || 0 < $db )
2308
            $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
2309
2310
        if ( empty( $pod ) && true === $db )
2311
            return pods_error( __( 'Pod not found', 'pods' ), $this );
2312
2313
        $params->pod_id = $pod[ 'id' ];
2314
        $params->pod = $pod[ 'name' ];
2315
        $params->pod_data = $pod;
2316
2317
        $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2318
2319
        if ( !isset( $params->id ) )
2320
            $params->id = 0;
2321
2322
        if ( empty( $params->name ) )
2323
            return pods_error( 'Pod field name is required', $this );
2324
2325
        $field = $this->load_field( $params );
2326
2327
        unset( $params->pod_data );
2328
2329
        $old_id = $old_name = $old_type = $old_definition = $old_simple = $old_options = $old_sister_id = null;
2330
2331
        if ( !empty( $field ) ) {
2332
            $old_id = pods_var( 'id', $field );
2333
            $old_name = pods_clean_name( $field[ 'name' ], true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2334
            $old_type = $field[ 'type' ];
2335
            $old_options = $field[ 'options' ];
2336
            $old_sister_id = (int) pods_var( 'sister_id', $old_options, 0 );
2337
2338
            $old_simple = ( 'pick' == $old_type && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
2339
2340
            if ( isset( $params->name ) && !empty( $params->name ) )
2341
                $field[ 'name' ] = $params->name;
2342
2343
            if ( $old_name != $field[ 'name' ] && false !== $this->field_exists( $params ) )
2344
                return pods_error( sprintf( __( 'Field %s already exists, you cannot rename %s to that', 'pods' ), $field[ 'name' ], $old_name ), $this );
2345
2346
            if ( ( $id_required || !empty( $params->id ) ) && ( empty( $old_id ) || $old_id != $params->id ) )
2347
                return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field[ 'name' ] ), $this );
2348
2349
            if ( empty( $params->id ) )
2350
                $params->id = $old_id;
2351
2352
            if ( !in_array( $old_type, $tableless_field_types ) || $old_simple ) {
2353
                $definition = $this->get_field_definition( $old_type, array_merge( $field, $old_options ) );
2354
2355
                if ( 0 < strlen( $definition ) )
2356
                    $old_definition = "`{$old_name}` " . $definition;
2357
            }
2358
        }
2359
        else {
2360
            $field = array(
2361
                'id' => 0,
2362
                'pod_id' => $params->pod_id,
2363
                'name' => $params->name,
2364
                'label' => $params->name,
2365
                'description' => '',
2366
                'type' => 'text',
2367
                'pick_object' => '',
2368
                'pick_val' => '',
2369
                'sister_id' => '',
2370
                'weight' => null,
2371
                'options' => array()
2372
            );
2373
        }
2374
2375
        // Setup options
2376
        $options = get_object_vars( $params );
2377
2378
        $options_ignore = array(
2379
            'method',
2380
            'table_info',
2381
            'attributes',
2382
            'group',
2383
            'grouped',
2384
            'developer_mode',
2385
            'dependency',
2386
            'depends-on',
2387
            'excludes-on'
2388
        );
2389
2390
        foreach ( $options_ignore as $ignore ) {
2391
            if ( isset( $options[ $ignore ] ) )
2392
                unset( $options[ $ignore ] );
2393
        }
2394
2395
        if ( isset( $options[ 'method' ] ) )
2396
            unset( $options[ 'method' ] );
2397
        elseif ( isset( $options[ 'table_info' ] ) )
2398
            unset( $options[ 'table_info' ] );
2399
2400
        $exclude = array(
2401
            'id',
2402
            'pod_id',
2403
            'pod',
2404
            'name',
2405
            'label',
2406
            'description',
2407
            'type',
2408
            'pick_object',
2409
            'pick_val',
2410
            'sister_id',
2411
            'weight',
2412
            'options'
2413
        );
2414
2415 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2416
            $aliases = array( $exclude_field );
2417
2418
            if ( is_array( $exclude_field ) ) {
2419
                $aliases = array_merge( array( $k ), $exclude_field );
2420
                $exclude_field = $k;
2421
            }
2422
2423
            foreach ( $aliases as $alias ) {
2424
                if ( isset( $options[ $alias ] ) ) {
2425
                    $field[ $exclude_field ] = pods_trim( $options[ $alias ] );
2426
2427
                    unset( $options[ $alias ] );
2428
                }
2429
            }
2430
        }
2431
2432
        if ( strlen( $field[ 'label' ] ) < 1 )
2433
            $field[ 'label' ] = $field[ 'name' ];
2434
2435
        $field[ 'options' ][ 'type' ] = $field[ 'type' ];
2436
2437
        if ( in_array( $field[ 'options' ][ 'type' ], $tableless_field_types ) ) {
2438
            // Clean up special drop-down in field editor and save out pick_val
2439
            $field[ 'pick_object' ] = pods_var( 'pick_object', $field, '', null, true );
2440
2441
            if ( 0 === strpos( $field[ 'pick_object' ], 'pod-' ) ) {
2442
                $field[ 'pick_val' ] = pods_str_replace( 'pod-', '', $field[ 'pick_object' ], 1 );
2443
                $field[ 'pick_object' ] = 'pod';
2444
            }
2445 View Code Duplication
            elseif ( 0 === strpos( $field[ 'pick_object' ], 'post_type-' ) ) {
2446
                $field[ 'pick_val' ] = pods_str_replace( 'post_type-', '', $field[ 'pick_object' ], 1 );
2447
                $field[ 'pick_object' ] = 'post_type';
2448
            }
2449 View Code Duplication
            elseif ( 0 === strpos( $field[ 'pick_object' ], 'taxonomy-' ) ) {
2450
                $field[ 'pick_val' ] = pods_str_replace( 'taxonomy-', '', $field[ 'pick_object' ], 1 );
2451
                $field[ 'pick_object' ] = 'taxonomy';
2452
            }
2453
            elseif ( 'table' == $field[ 'pick_object' ] && 0 < strlen( pods_var_raw( 'pick_table', $field[ 'options' ] ) ) ) {
2454
                $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_table' ];
2455
                $field[ 'pick_object' ] = 'table';
2456
            }
2457
            elseif ( false === strpos( $field[ 'pick_object' ], '-' ) && !in_array( $field[ 'pick_object' ], array( 'pod', 'post_type', 'taxonomy' ) ) ) {
2458
                $field[ 'pick_val' ] = '';
2459
			}
2460
			elseif ( 'custom-simple' == $field[ 'pick_object' ] ) {
2461
                $field[ 'pick_val' ] = '';
2462
			}
2463
2464
            $field[ 'options' ][ 'pick_object' ] = $field[ 'pick_object' ];
2465
            $field[ 'options' ][ 'pick_val' ] = $field[ 'pick_val' ];
2466
            $field[ 'options' ][ 'sister_id' ] = pods_var( 'sister_id', $field );
2467
2468
            unset( $field[ 'pick_object' ] );
2469
            unset( $field[ 'pick_val' ] );
2470
2471
            if ( isset( $field[ 'sister_id' ] ) )
2472
                unset( $field[ 'sister_id' ] );
2473
        }
2474
2475
        $field[ 'options' ] = array_merge( $field[ 'options' ], $options );
2476
2477
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
2478
2479
        if ( 0 < $old_id && defined( 'PODS_FIELD_STRICT' ) && !PODS_FIELD_STRICT )
2480
            $params->id = $field[ 'id' ] = $old_id;
2481
2482
        // Add new field
2483
        if ( !isset( $params->id ) || empty( $params->id ) || empty( $field ) ) {
2484
            if ( $table_operation && in_array( $field[ 'name' ], array( 'created', 'modified' ) ) && !in_array( $field[ 'type' ], array( 'date', 'datetime' ) ) && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2485
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2486
2487
            if ( $table_operation && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2488
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2489
2490 View Code Duplication
            if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) )
2491
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2492
2493
            foreach ( $object_fields as $object_field => $object_field_opt ) {
2494
                if ( $object_field == $field[ 'name' ] || in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2495
                    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 );
2496
            }
2497
2498
            if ( in_array( $field[ 'name' ], array( 'rss' ) ) ) // Reserved post_name values that can't be used as field names
2499
                $field[ 'name' ] .= '2';
2500
2501
            if ( 'slug' == $field[ 'type' ] && true === $db ) {
2502 View Code Duplication
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy', 'user' ) ) )
2503
                    return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this );
2504
2505
                $slug_field = get_posts( array(
2506
                    'post_type' => '_pods_field',
2507
                    'orderby' => 'menu_order',
2508
                    'order' => 'ASC',
2509
                    'posts_per_page' => 1,
2510
                    'post_parent' => $field[ 'pod_id' ],
2511
                    'meta_query' => array(
2512
                        array(
2513
                            'key' => 'type',
2514
                            'value' => 'slug'
2515
                        )
2516
                    )
2517
                ) );
2518
2519
                if ( !empty( $slug_field ) )
2520
                    return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this );
2521
            }
2522
2523
            // Sink the new field to the bottom of the list
2524
            if ( null === $field[ 'weight' ] ) {
2525
                $field[ 'weight' ] = 0;
2526
2527
                $bottom_most_field = get_posts( array(
2528
                    'post_type' => '_pods_field',
2529
                    'orderby' => 'menu_order',
2530
                    'order' => 'DESC',
2531
                    'posts_per_page' => 1,
2532
                    'post_parent' => $field[ 'pod_id' ]
2533
                ) );
2534
2535
                if ( !empty( $bottom_most_field ) )
2536
                    $field[ 'weight' ] = pods_absint( $bottom_most_field[ 0 ]->menu_order ) + 1;
2537
            }
2538
2539
            $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2540
2541
            $post_data = array(
2542
                'post_name' => $field[ 'name' ],
2543
                'post_title' => $field[ 'label' ],
2544
                'post_content' => $field[ 'description' ],
2545
                'post_type' => '_pods_field',
2546
                'post_parent' => $field[ 'pod_id' ],
2547
                'post_status' => 'publish',
2548
                'menu_order' => $field[ 'weight' ]
2549
            );
2550
        }
2551
        else {
2552
            if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) ) {
2553 View Code Duplication
                if ( null !== $old_name )
2554
                    return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2555
                else
2556
                    return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2557
            }
2558
2559
            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 ) )
2560
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2561
2562
            if ( null !== $old_name && $field[ 'name' ] != $old_name && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2563
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2564
2565
            foreach ( $object_fields as $object_field => $object_field_opt ) {
2566
                if ( $object_field != $field[ 'name' ] && !in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2567
                    continue;
2568
2569 View Code Duplication
                if ( null !== $old_name )
2570
                    return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2571
                else
2572
                    return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2573
            }
2574
2575
            $post_data = array(
2576
                'ID' => $field[ 'id' ],
2577
                'post_name' => $field[ 'name' ],
2578
                'post_title' => $field[ 'label' ],
2579
                'post_content' => $field[ 'description' ]
2580
            );
2581
2582
            if ( null !== $field[ 'weight' ] ) {
2583
                $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2584
2585
                $post_data[ 'menu_order' ] = $field[ 'weight' ];
2586
            }
2587
        }
2588
2589
        if ( true === $db ) {
2590
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
2591
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
2592
2593
            $conflicted = false;
2594
2595
            // Headway compatibility fix
2596
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
2597
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2598
2599
                $conflicted = true;
2600
            }
2601
2602
            // Store the old field name
2603
            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...
2604
	            $field['options']['old_name'] = $old_name;
2605
            }
2606
2607
            $params->id = $this->save_wp_object( 'post', $post_data, $field[ 'options' ], true, true );
2608
2609
            if ( $conflicted )
2610
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2611
2612
            if ( false === $params->id )
2613
                return pods_error( __( 'Cannot save Field', 'pods' ), $this );
2614
        }
2615
        else
2616
            $params->id = $field[ 'name' ];
2617
2618
        $field[ 'id' ] = $params->id;
2619
2620
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field[ 'options' ] ), $simple_tableless_objects ) );
2621
2622
        $definition = false;
2623
2624
        if ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) {
2625
            $field_definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, $field[ 'options' ] ) );
2626
2627
            if ( 0 < strlen( $field_definition ) )
2628
                $definition = '`' . $field[ 'name' ] . '` ' . $field_definition;
2629
        }
2630
2631
        $sister_id = (int) pods_var( 'sister_id', $field[ 'options' ], 0 );
2632
2633
        if ( $table_operation && 'table' == $pod[ 'storage' ] && !pods_tableless() ) {
2634
            if ( !empty( $old_id ) ) {
2635
                if ( ( $field[ 'type' ] != $old_type || $old_simple != $simple ) && empty( $definition ) )
2636
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false );
2637
                elseif ( 0 < strlen( $definition ) ) {
2638
                    if ( $old_name != $field[ 'name' ] || $old_simple != $simple ) {
2639
                        $test = false;
2640
2641 View Code Duplication
                        if ( 0 < strlen( $old_definition ) )
2642
                            $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2643
2644
                        // If the old field doesn't exist, continue to add a new field
2645
                        if ( false === $test )
2646
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2647
                    }
2648
                    elseif ( null !== $old_definition && $definition != $old_definition ) {
2649
                        $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_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
            elseif ( 0 < strlen( $definition ) ) {
2658
                $test = false;
2659
2660 View Code Duplication
                if ( 0 < strlen( $old_definition ) )
2661
                    $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `" . $field[ 'name' ] . "` {$definition}", false );
2662
2663
                // If the old field doesn't exist, continue to add a new field
2664
                if ( false === $test )
2665
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2666
            }
2667
        }
2668
2669
        if ( !empty( $old_id ) && 'meta' == $pod[ 'storage' ] && $old_name != $field[ 'name' ] && $pod[ 'meta_table' ] != $pod[ 'table' ] ) {
2670
            $prepare = array(
2671
                $field[ 'name' ],
2672
                $old_name
2673
            );
2674
2675
            // Users don't have a type
2676
            if ( !empty( $pod[ 'field_type' ] ) )
2677
                $prepare[] = $pod[ 'name' ];
2678
2679
            pods_query( "
2680
                UPDATE `{$pod[ 'meta_table' ]}` AS `m`
2681
                LEFT JOIN `{$pod[ 'table' ]}` AS `t`
2682
                    ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}`
2683
                SET
2684
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2685
                WHERE
2686
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2687
            " . ( !empty( $pod[ 'field_type' ] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ),
2688
                $prepare
2689
            );
2690
        }
2691
2692
        if ( $field[ 'type' ] != $old_type && in_array( $old_type, $tableless_field_types ) ) {
2693
            delete_post_meta( $old_sister_id, 'sister_id' );
2694
2695
            if ( true === $db ) {
2696
                pods_query( "
2697
                        DELETE pm
2698
                        FROM {$wpdb->postmeta} AS pm
2699
                        LEFT JOIN {$wpdb->posts} AS p
2700
                            ON p.post_type = '_pods_field'
2701
                            AND p.ID = pm.post_id
2702
                        WHERE
2703
                            p.ID IS NOT NULL
2704
                            AND pm.meta_key = 'sister_id'
2705
                            AND pm.meta_value = %d
2706
                    ", array(
2707
                        $params->id
2708
                    )
2709
                );
2710
2711
                if ( !pods_tableless() ) {
2712
                    pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false );
2713
2714
                    pods_query( "
2715
                            UPDATE `@wp_podsrel`
2716
                            SET `related_field_id` = 0
2717
                            WHERE `field_id` = %d
2718
                        ", array(
2719
                            $old_sister_id
2720
                        )
2721
                    );
2722
                }
2723
            }
2724
        }
2725 View Code Duplication
        elseif ( 0 < $sister_id ) {
2726
            update_post_meta( $sister_id, 'sister_id', $params->id );
2727
2728
            if ( true === $db && ( !pods_tableless() ) ) {
2729
                pods_query( "
2730
                        UPDATE `@wp_podsrel`
2731
                        SET `related_field_id` = %d
2732
                        WHERE `field_id` = %d
2733
                    ",
2734
                    array(
2735
                        $params->id,
2736
                        $sister_id
2737
                    )
2738
                );
2739
            }
2740
        }
2741 View Code Duplication
        elseif ( 0 < $old_sister_id ) {
2742
            delete_post_meta( $old_sister_id, 'sister_id' );
2743
2744
            if ( true === $db && ( !pods_tableless() ) ) {
2745
                pods_query( "
2746
                        UPDATE `@wp_podsrel`
2747
                        SET `related_field_id` = 0
2748
                        WHERE `field_id` = %d
2749
                    ", array(
2750
                        $old_sister_id
2751
                    )
2752
                );
2753
            }
2754
        }
2755
2756
        if ( !empty( $old_id ) && $old_name != $field[ 'name' ] && true === $db ) {
2757
            pods_query( "
2758
                    UPDATE `@wp_postmeta`
2759
                    SET `meta_value` = %s
2760
                    WHERE
2761
                        `post_id` = %d
2762
                        AND `meta_key` = 'pod_index'
2763
                        AND `meta_value` = %s
2764
                ", array(
2765
                    $field[ 'name' ],
2766
                    $pod[ 'id' ],
2767
                    $old_name
2768
                )
2769
            );
2770
        }
2771
2772
        if ( !$save_pod )
2773
            $this->cache_flush_pods( $pod );
2774
        else {
2775
            pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
2776
2777
            if ( !empty( $old_id ) && $old_name != $field[ 'name' ] )
2778
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $old_name );
2779
        }
2780
2781
        if ( true === $db )
2782
            return $params->id;
2783
        else
2784
            return $field;
2785
    }
2786
2787
    /**
2788
     * Fix Pod / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name)
2789
     *
2790
     * @param string $slug Unique slug value
2791
     * @param int $post_ID Post ID
2792
     * @param string $post_status Post Status
2793
     * @param string $post_type Post Type
2794
     * @param int $post_parent Post Parent ID
2795
     * @param string $original_slug Original slug value
2796
     *
2797
     * @return string Final slug value
2798
     *
2799
     * @since 2.3.3
2800
     */
2801
    public function save_slug_fix ( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) {
2802
        if ( in_array( $post_type, array( '_pods_field', '_pods_pod' ) ) && false !== strpos( $slug, '-' ) )
2803
            $slug = $original_slug;
2804
2805
        return $slug;
2806
    }
2807
2808
    /**
2809
     * Add or Edit a Pods Object
2810
     *
2811
     * $params['id'] int The Object ID
2812
     * $params['name'] string The Object name
2813
     * $params['type'] string The Object type
2814
     * $params['options'] Associative array of Object options
2815
     *
2816
     * @param array|object $params An associative array of parameters
2817
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
2818
     *
2819
     * @return int The Object ID
2820
     * @since 2.0
2821
     */
2822
    public function save_object ( $params, $sanitized = false ) {
2823
        $params = (object) $params;
2824
2825
        if ( false === $sanitized )
2826
            $params = pods_sanitize( $params );
2827
2828 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
2829
            return pods_error( __( 'Name must be given to save an Object', 'pods' ), $this );
2830
2831 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
2832
            return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this );
2833
2834
        $object = array(
2835
            'id' => 0,
2836
            'name' => $params->name,
2837
            'type' => $params->type,
2838
            'code' => '',
2839
            'options' => array()
2840
        );
2841
2842
        // Setup options
2843
        $options = get_object_vars( $params );
2844
2845
        if ( isset( $options[ 'method' ] ) )
2846
            unset( $options[ 'method' ] );
2847
2848
        $exclude = array(
2849
            'id',
2850
            'name',
2851
            'helper_type',
2852
            'code',
2853
            'options',
2854
            'status'
2855
        );
2856
2857 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2858
            $aliases = array( $exclude_field );
2859
2860
            if ( is_array( $exclude_field ) ) {
2861
                $aliases = array_merge( array( $k ), $exclude_field );
2862
                $exclude_field = $k;
2863
            }
2864
2865
            foreach ( $aliases as $alias ) {
2866
                if ( isset( $options[ $alias ] ) ) {
2867
                    $object[ $exclude_field ] = pods_trim( $options[ $alias ] );
2868
2869
                    unset( $options[ $alias ] );
2870
                }
2871
            }
2872
        }
2873
2874
        if ( 'helper' == $object[ 'type' ] )
2875
            $object[ 'options' ][ 'helper_type' ] = $object[ 'helper_type' ];
2876
2877
        if ( isset( $object[ 'options' ][ 'code' ] ) )
2878
            unset( $object[ 'options' ][ 'code' ] );
2879
2880
        $object[ 'options' ] = array_merge( $object[ 'options' ], $options );
2881
2882
        $post_data = array(
2883
            'post_name' => pods_clean_name( $object[ 'name' ], true),
2884
            'post_title' => $object[ 'name' ],
2885
            'post_content' => $object[ 'code' ],
2886
            'post_type' => '_pods_' . $object[ 'type' ],
2887
            'post_status' => 'publish'
2888
        );
2889
2890
        if ( !empty( $object[ 'id' ] ) )
2891
            $post_data[ 'ID' ] = $object[ 'id' ];
2892
2893
        if ( null !== pods_var( 'status', $object, null, null, true ) )
2894
            $post_data[ 'post_status' ] = pods_var( 'status', $object, null, null, true );
2895
2896
        remove_filter( 'content_save_pre', 'balanceTags', 50 );
2897
2898
        $post_data = pods_sanitize( $post_data );
2899
2900
        $params->id = $this->save_post( $post_data, $object[ 'options' ], true, true );
2901
2902
        pods_transient_clear( 'pods_objects_' . $params->type );
2903
        pods_transient_clear( 'pods_objects_' . $params->type . '_get' );
2904
2905
        return $params->id;
2906
    }
2907
2908
    /**
2909
     * @see PodsAPI::save_object
2910
     *
2911
     * Add or edit a Pod Template
2912
     *
2913
     * $params['id'] int The template ID
2914
     * $params['name'] string The template name
2915
     * $params['code'] string The template code
2916
     *
2917
     * @param array|object $params An associative array of parameters
2918
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2919
     *
2920
     * @return int The Template ID
2921
     *
2922
     * @since 1.7.9
2923
     */
2924
    public function save_template ( $params, $sanitized = false ) {
2925
        $params = (object) $params;
2926
2927
        $params->type = 'template';
2928
2929
        return $this->save_object( $params, $sanitized );
2930
    }
2931
2932
    /**
2933
     * @see PodsAPI::save_object
2934
     *
2935
     * Add or edit a Pod Page
2936
     *
2937
     * $params['id'] int The page ID
2938
     * $params['name'] string The page URI
2939
     * $params['code'] string The page code
2940
     *
2941
     * @param array|object $params An associative array of parameters
2942
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2943
     *
2944
     * @return int The page ID
2945
     * @since 1.7.9
2946
     */
2947
    public function save_page ( $params, $sanitized = false ) {
2948
        $params = (object) $params;
2949
2950
        if ( !isset( $params->name ) ) {
2951
            $params->name = $params->uri;
2952
            unset( $params->uri );
2953
        }
2954
2955
        if ( isset( $params->phpcode ) ) {
2956
            $params->code = $params->phpcode;
2957
            unset( $params->phpcode );
2958
        }
2959
2960
        $params->name = trim( $params->name, '/' );
2961
        $params->type = 'page';
2962
2963
        return $this->save_object( $params, $sanitized );
2964
    }
2965
2966
    /**
2967
     * @see PodsAPI::save_object
2968
     *
2969
     * Add or edit a Pod Helper
2970
     *
2971
     * $params['id'] int The helper ID
2972
     * $params['name'] string The helper name
2973
     * $params['helper_type'] string The helper type ("pre_save", "display", etc)
2974
     * $params['code'] string The helper code
2975
     *
2976
     * @param array $params An associative array of parameters
2977
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2978
     *
2979
     * @return int The helper ID
2980
     * @since 1.7.9
2981
     */
2982
    public function save_helper ( $params, $sanitized = false ) {
2983
        $params = (object) $params;
2984
2985
        if ( isset( $params->phpcode ) ) {
2986
            $params->code = $params->phpcode;
2987
            unset( $params->phpcode );
2988
        }
2989
2990
        if ( isset( $params->type ) ) {
2991
            $params->helper_type = $params->type;
2992
            unset( $params->type );
2993
        }
2994
2995
        $params->type = 'helper';
2996
2997
        return $this->save_object( $params, $sanitized );
2998
    }
2999
3000
    /**
3001
     * Add or edit a single pod item
3002
     *
3003
     * $params['pod'] string The Pod name (pod or pod_id is required)
3004
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
3005
     * $params['id'] int|array The item ID, or an array of item IDs to save data for
3006
     * $params['data'] array (optional) Associative array of field names + values
3007
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
3008
	 * $params['track_changed_fields'] bool Set to true to enable tracking of saved fields via PodsAPI::get_changed_fields()
3009
	 * $params['error_mode'] string Throw an 'exception', 'exit' with the message, return 'false', or return 'wp_error'
3010
     *
3011
     * @param array|object $params An associative array of parameters
3012
     *
3013
     * @return int|array The item ID, or an array of item IDs (if `id` is an array if IDs)
3014
     *
3015
     * @since 1.7.9
3016
     */
3017
    public function save_pod_item ( $params ) {
3018
3019
		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...
3020
3021
        $params = (object) pods_str_replace( '@wp_', '{prefix}', $params );
3022
3023
        $tableless_field_types = PodsForm::tableless_field_types();
3024
        $repeatable_field_types = PodsForm::repeatable_field_types();
3025
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
3026
3027
	    $error_mode = $this->display_errors;
3028
3029
	    if ( ! empty( $params->error_mode ) ) {
3030
		    $error_mode = $params->error_mode;
3031
	    }
3032
3033
        // @deprecated 2.0
3034
        if ( isset( $params->datatype ) ) {
3035
            pods_deprecated( '$params->pod instead of $params->datatype', '2.0' );
3036
3037
            $params->pod = $params->datatype;
3038
3039
            unset( $params->datatype );
3040
3041
            if ( isset( $params->pod_id ) ) {
3042
                pods_deprecated( '$params->id instead of $params->pod_id', '2.0' );
3043
3044
                $params->id = $params->pod_id;
3045
3046
                unset( $params->pod_id );
3047
            }
3048
3049
            if ( isset( $params->data ) && !empty( $params->data ) && is_array( $params->data ) ) {
3050
                $check = current( $params->data );
3051
3052
                if ( is_array( $check ) ) {
3053
                    pods_deprecated( 'PodsAPI::save_pod_items', '2.0' );
3054
3055
                    return $this->save_pod_items( $params, $params->data );
3056
                }
3057
            }
3058
        }
3059
3060
        // @deprecated 2.0
3061
        if ( isset( $params->tbl_row_id ) ) {
3062
            pods_deprecated( '$params->id instead of $params->tbl_row_id', '2.0' );
3063
3064
            $params->id = $params->tbl_row_id;
3065
3066
            unset( $params->tbl_row_id );
3067
        }
3068
3069
        // @deprecated 2.0
3070
        if ( isset( $params->columns ) ) {
3071
            pods_deprecated( '$params->data instead of $params->columns', '2.0' );
3072
3073
            $params->data = $params->columns;
3074
3075
            unset( $params->columns );
3076
        }
3077
3078
        if ( !isset( $params->pod ) )
3079
            $params->pod = false;
3080 View Code Duplication
        if ( isset( $params->pod_id ) )
3081
            $params->pod_id = pods_absint( $params->pod_id );
3082
        else
3083
            $params->pod_id = 0;
3084
3085 View Code Duplication
        if ( isset( $params->id ) )
3086
            $params->id = pods_absint( $params->id );
3087
        else
3088
            $params->id = 0;
3089
3090
        if ( !isset( $params->from ) )
3091
            $params->from = 'save';
3092
3093
        if ( !isset( $params->location ) )
3094
            $params->location = null;
3095
3096
        if ( !isset( $params->track_changed_fields ) )
3097
            $params->track_changed_fields = false;
3098
3099
		/**
3100
		 * Override $params['track_changed_fields']
3101
		 *
3102
		 * Use for globally setting field change tracking.
3103
		 *
3104
		 * @param bool
3105
		 *
3106
		 * @since 2.3.19
3107
		 */
3108
		$track_changed_fields = apply_filters( 'pods_api_save_pod_item_track_changed_fields_' . $params->pod, (boolean) $params->track_changed_fields, $params );
3109
3110
		$changed_fields = array();
3111
3112
		if ( !isset( $params->clear_slug_cache ) ) {
3113
			$params->clear_slug_cache = true;
3114
		}
3115
3116
        // Support for bulk edit
3117
        if ( isset( $params->id ) && !empty( $params->id ) && is_array( $params->id ) ) {
3118
            $ids = array();
3119
            $new_params = $params;
3120
3121
            foreach ( $params->id as $id ) {
3122
                $new_params->id = $id;
3123
3124
                $ids[] = $this->save_pod_item( $new_params );
3125
            }
3126
3127
            return $ids;
3128
        }
3129
3130
        // Allow Helpers to know what's going on, are we adding or saving?
3131
        $is_new_item = false;
3132
3133
        if ( empty( $params->id ) )
3134
            $is_new_item = true;
3135
3136
        if ( isset( $params->is_new_item ) )
3137
            $is_new_item = (boolean) $params->is_new_item;
3138
3139
        // Allow Helpers to bypass subsequent helpers in recursive save_pod_item calls
3140
        $bypass_helpers = false;
3141
3142
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
3143
            $bypass_helpers = true;
3144
3145
        // Allow Custom Fields not defined by Pods to be saved
3146
        $allow_custom_fields = false;
3147
3148
        if ( isset( $params->allow_custom_fields ) && false !== $params->allow_custom_fields )
3149
            $allow_custom_fields = true;
3150
3151
        // Get array of Pods
3152
        $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
3153
3154
        if ( false === $pod )
3155
            return pods_error( __( 'Pod not found', 'pods' ), $error_mode );
3156
3157
        $params->pod = $pod[ 'name' ];
3158
        $params->pod_id = $pod[ 'id' ];
3159
3160
        if ( 'settings' == $pod[ 'type' ] )
3161
            $params->id = $pod[ 'id' ];
3162
3163
        $fields = $pod[ 'fields' ];
3164
3165
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
3166
3167
        $fields_active = array();
3168
        $custom_data = array();
3169
3170
        // Find the active fields (loop through $params->data to retain order)
3171
        if ( !empty( $params->data ) && is_array( $params->data ) ) {
3172
            $custom_fields = array();
3173
3174
            foreach ( $params->data as $field => $value ) {
3175
                if ( isset( $object_fields[ $field ] ) ) {
3176
                    $object_fields[ $field ][ 'value' ] = $value;
3177
                    $fields_active[] = $field;
3178
                }
3179
                elseif ( isset( $fields[ $field ] ) ) {
3180
                    if ( 'save' == $params->from || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3181
                        $fields[ $field ][ 'value' ] = $value;
3182
                        $fields_active[] = $field;
3183
                    }
3184
                    elseif ( !pods_has_permissions( $fields[ $field ][ 'options' ] ) && pods_var( 'hidden', $fields[ $field ][ 'options' ], false ) ) {
3185
                        $fields[ $field ][ 'value' ] = $value;
3186
                        $fields_active[] = $field;
3187
                    }
3188
                }
3189
                else {
3190
                    $found = false;
3191
3192
                    foreach ( $object_fields as $object_field => $object_field_opt ) {
3193
                        if ( in_array( $field, $object_field_opt[ 'alias' ] ) ) {
3194
                            $object_fields[ $object_field ][ 'value' ] = $value;
3195
                            $fields_active[] = $object_field;
3196
3197
                            $found = true;
3198
3199
                            break;
3200
                        }
3201
                    }
3202
3203
                    if ( $allow_custom_fields && !$found )
3204
                        $custom_fields[] = $field;
3205
                }
3206
            }
3207
3208
            if ( $allow_custom_fields && !empty( $custom_fields ) ) {
3209
                foreach ( $custom_fields as $field ) {
3210
                    $custom_data[ $field ] = $params->data[ $field ];
3211
                }
3212
            }
3213
3214
           unset( $params->data );
3215
        }
3216
3217 View Code Duplication
		if ( empty( $params->id ) && !in_array( 'created', $fields_active ) && isset( $fields[ 'created' ] ) && in_array( $fields[ 'created' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3218
			$fields[ 'created' ][ 'value' ] = current_time( 'mysql' );
3219
			$fields_active[] = 'created';
3220
		}
3221
3222 View Code Duplication
		if ( !in_array( 'modified', $fields_active ) && isset( $fields[ 'modified' ] ) && in_array( $fields[ 'modified' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3223
			$fields[ 'modified' ][ 'value' ] = current_time( 'mysql' );
3224
			$fields_active[] = 'modified';
3225
		}
3226
3227
        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' ] ] ) ) {
3228
			$fields[ $pod[ 'pod_field_slug' ] ][ 'value' ] = ''; // this will get picked up by slug pre_save method
3229
			$fields_active[] = $pod[ 'pod_field_slug' ];
3230
        }
3231
3232
        // Handle hidden fields
3233
        if ( empty( $params->id ) ) {
3234
            foreach ( $fields as $field => $field_data ) {
3235
                if ( in_array( $field, $fields_active ) )
3236
                    continue;
3237
3238
                if ( in_array( $params->from, array( 'save', 'process_form' ) ) || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3239
                    $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 );
3240
3241
                    if ( null !== $value && '' !== $value && false !== $value ) {
3242
                        $fields[ $field ][ 'value' ] = $value;
3243
                        $fields_active[] = $field;
3244
                    }
3245
                }
3246
            }
3247
3248
			// Set default field values for object fields
3249
			if ( !empty( $object_fields ) ) {
3250 View Code Duplication
				foreach ( $object_fields as $field => $field_data ) {
3251
					if ( in_array( $field, $fields_active ) ) {
3252
						continue;
3253
					}
3254
					elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3255
						continue;
3256
					}
3257
3258
                    $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 );
3259
3260
                    if ( null !== $value && '' !== $value && false !== $value ) {
3261
                        $object_fields[ $field ][ 'value' ] = $value;
3262
                        $fields_active[] = $field;
3263
                    }
3264
				}
3265
			}
3266
3267
			// Set default field values for Pod fields
3268 View Code Duplication
			foreach ( $fields as $field => $field_data ) {
3269
				if ( in_array( $field, $fields_active ) ) {
3270
					continue;
3271
				}
3272
				elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3273
					continue;
3274
				}
3275
3276
				$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 );
3277
3278
				if ( null !== $value && '' !== $value && false !== $value ) {
3279
					$fields[ $field ][ 'value' ] = $value;
3280
					$fields_active[] = $field;
3281
				}
3282
			}
3283
        }
3284
3285
        $columns =& $fields; // @deprecated 2.0
3286
        $active_columns =& $fields_active; // @deprecated 2.0
3287
        $params->tbl_row_id =& $params->id; // @deprecated 2.0
3288
3289
        $pre_save_helpers = $post_save_helpers = array();
3290
3291
		$pieces = array(
3292
			'fields',
3293
			'params',
3294
			'pod',
3295
			'fields_active',
3296
			'object_fields',
3297
			'custom_fields',
3298
			'custom_data',
3299
			'track_changed_fields',
3300
			'changed_fields'
3301
		);
3302
3303
		if ( $track_changed_fields ) {
3304
			self::handle_changed_fields( $params->pod, $params->id, 'set' );
3305
		}
3306
3307
        if ( false === $bypass_helpers ) {
3308
            // Plugin hooks
3309
            $hooked = $this->do_hook( 'pre_save_pod_item', compact( $pieces ), $is_new_item, $params->id );
3310
3311
            if ( is_array( $hooked ) && !empty( $hooked ) )
3312
                extract( $hooked );
3313
3314
            $hooked = $this->do_hook( "pre_save_pod_item_{$params->pod}", compact( $pieces ), $is_new_item, $params->id );
3315
3316
            if ( is_array( $hooked ) && !empty( $hooked ) )
3317
                extract( $hooked );
3318
3319
            if ( $is_new_item ) {
3320
                $hooked = $this->do_hook( 'pre_create_pod_item', compact( $pieces ) );
3321
3322
                if ( is_array( $hooked ) && !empty( $hooked ) )
3323
                    extract( $hooked );
3324
3325
                $hooked = $this->do_hook( "pre_create_pod_item_{$params->pod}", compact( $pieces ) );
3326
3327
                if ( is_array( $hooked ) && !empty( $hooked ) )
3328
                    extract( $hooked );
3329
            }
3330
            else {
3331
                $hooked = $this->do_hook( 'pre_edit_pod_item', compact( $pieces ), $params->id );
3332
3333
                if ( is_array( $hooked ) && !empty( $hooked ) )
3334
                    extract( $hooked );
3335
3336
                $hooked = $this->do_hook( "pre_edit_pod_item_{$params->pod}", compact( $pieces ), $params->id );
3337
3338
                if ( is_array( $hooked ) && !empty( $hooked ) )
3339
                    extract( $hooked );
3340
            }
3341
3342
            // Call any pre-save helpers (if not bypassed)
3343 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3344
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
3345
                    $helpers = array( 'pre_save_helpers', 'post_save_helpers' );
3346
3347
                    foreach ( $helpers as $helper ) {
3348
                        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...
3349
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
3350
                    }
3351
                }
3352
3353
                if ( !empty( $pre_save_helpers ) ) {
3354
                    pods_deprecated( sprintf( __( 'Pre-save helpers are deprecated, use the action pods_pre_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3355
3356
                    foreach ( $pre_save_helpers as $helper ) {
3357
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3358
3359
                        if ( false !== $helper )
3360
                            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...
3361
                    }
3362
                }
3363
            }
3364
        }
3365
3366
        $table_data = $table_formats = $update_values = $rel_fields = $rel_field_ids = array();
3367
3368
        $object_type = $pod[ 'type' ];
3369
3370
        $object_ID = 'ID';
3371
3372
        if ( 'comment' == $object_type )
3373
            $object_ID = 'comment_ID';
3374
        elseif ( 'taxonomy' == $object_type )
3375
            $object_ID = 'term_id';
3376
3377
        $object_data = $object_meta = $post_term_data = array();
3378
3379
        if ( 'settings' == $object_type )
3380
            $object_data[ 'option_id' ] = $pod[ 'name' ];
3381
        elseif ( !empty( $params->id ) )
3382
            $object_data[ $object_ID ] = $params->id;
3383
3384
        $fields_active = array_unique( $fields_active );
3385
3386
        // Loop through each active field, validating and preparing the table data
3387
        foreach ( $fields_active as $field ) {
3388 View Code Duplication
            if ( isset( $object_fields[ $field ] ) )
3389
                $field_data = $object_fields[ $field ];
3390
            elseif ( isset( $fields[ $field ] ) )
3391
                $field_data = $fields[ $field ];
3392
            else
3393
                continue;
3394
3395
            $value = $field_data[ 'value' ];
3396
            $type = $field_data[ 'type' ];
3397
            $options = pods_var( 'options', $field_data, array() );
3398
3399
            // WPML AJAX compatibility
3400
            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' ) )
3401
                $options[ 'unique' ] = $fields[ $field ][ 'options' ][ 'unique' ] = $options[ 'required' ] = $fields[ $field ][ 'options' ][ 'required' ] = 0;
3402
            else {
3403
                // Validate value
3404
                $validate = $this->handle_field_validation( $value, $field, $object_fields, $fields, $pod, $params );
3405
3406
                if ( false === $validate )
3407
                    $validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field_data[ 'label' ] );
3408
                elseif ( true !== $validate )
3409
                    $validate = (array) $validate;
3410
3411
                if ( !is_bool( $validate ) && !empty( $validate ) )
3412
                    return pods_error( $validate, $error_mode );
3413
            }
3414
3415
            $value = PodsForm::pre_save( $field_data[ 'type' ], $value, $params->id, $field, array_merge( $field_data, $options ), array_merge( $fields, $object_fields ), $pod, $params );
3416
3417
            $field_data[ 'value' ] = $value;
3418
3419
            if ( isset( $object_fields[ $field ] ) ) {
3420
            	// @todo Eventually support 'comment' field type saving here too
3421
				if ( 'taxonomy' == $object_fields[ $field ][ 'type' ] ) {
3422
					$post_term_data[ $field ] = $value;
3423
				}
3424
				else {
3425
                	$object_data[ $field ] = $value;
3426
				}
3427
			}
3428
            else {
3429
                $simple = ( 'pick' == $type && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
3430
                $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field_data, $field, $fields, $pod, $params );
3431
3432
                // Handle Simple Relationships
3433
                if ( $simple ) {
3434
                    if ( !is_array( $value ) )
3435
                        $value = explode( ',', $value );
3436
3437
                    $pick_limit = (int) pods_var_raw( 'pick_limit', $options, 0 );
3438
3439
                    if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
3440
                        $pick_limit = 1;
3441
3442
                    if ( 'custom-simple' == pods_var( 'pick_object', $field_data ) ) {
3443
                        $custom = pods_var_raw( 'pick_custom', $options, '' );
3444
3445
                        $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data[ 'name' ], $value, array_merge( $field_data, $options ), $pod, $params->id );
3446
3447
                        if ( empty( $value ) || empty( $custom ) )
3448
                            $value = '';
3449
                        elseif ( !empty( $custom ) ) {
3450
                            if ( !is_array( $custom ) ) {
3451
                                $custom = explode( "\n", $custom );
3452
3453
                                $custom_values = array();
3454
3455
                                foreach ( $custom as $c => $cv ) {
3456
                                    if ( 0 < strlen( $cv ) ) {
3457
                                        $custom_label = explode( '|', $cv );
3458
3459
                                        if ( !isset( $custom_label[ 1 ] ) )
3460
                                            $custom_label[ 1 ] = $custom_label[ 0 ];
3461
3462
                                        $custom_label[ 0 ] = trim( (string) $custom_label[ 0 ] );
3463
                                        $custom_label[ 1 ] = trim( (string) $custom_label[ 1 ] );
3464
                                        $custom_values[ $custom_label[ 0 ] ] = $custom_label[ 1 ];
3465
                                    }
3466
                                }
3467
                            }
3468
                            else
3469
                                $custom_values = $custom;
3470
3471
                            $values = array();
3472
3473
                            foreach ( $value as $k => $v ) {
3474
                                $v = pods_unsanitize( $v );
3475
3476
                                if ( isset( $custom_values[ $v ] ) )
3477
                                    $values[ $k ] = $v;
3478
                            }
3479
3480
                            $value = $values;
3481
                        }
3482
                    }
3483
3484
                    if ( 0 < $pick_limit && !empty( $value ) )
3485
                        $value = array_slice( $value, 0, $pick_limit );
3486
3487
                    // Don't save an empty array, just make it an empty string
3488 View Code Duplication
                    if ( empty( $value ) )
3489
                        $value = '';
3490
                    elseif ( is_array( $value ) ) {
3491
                        // If there's just one item, don't save as an array, save the string
3492
                        if ( 1 == $pick_limit || 1 == count( $value ) )
3493
                            $value = implode( '', $value );
3494
                        // If storage is set to table, json encode, otherwise WP will serialize automatically
3495
                        elseif ( 'table' == pods_var( 'storage', $pod ) )
3496
                            $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...
3497
                    }
3498
                }
3499
3500
                // Prepare all table / meta data
3501
                if ( !in_array( $type, $tableless_field_types ) || $simple ) {
3502
                    if ( in_array( $type, $repeatable_field_types ) && 1 == pods_var( $type . '_repeatable', $field_data, 0 ) ) {
3503
                        // Don't save an empty array, just make it an empty string
3504 View Code Duplication
                        if ( empty( $value ) )
3505
                            $value = '';
3506
                        elseif ( is_array( $value ) ) {
3507
                            // If there's just one item, don't save as an array, save the string
3508
                            if ( 1 == count( $value ) )
3509
                                $value = implode( '', $value );
3510
                            // If storage is set to table, json encode, otherwise WP will serialize automatically
3511
                            elseif ( 'table' == pods_var( 'storage', $pod ) )
3512
                                $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...
3513
                        }
3514
                    }
3515
3516
                    $table_data[ $field ] = str_replace( array( '{prefix}', '@wp_' ), array( '{/prefix/}', '{prefix}' ), $value ); // Fix for pods_query
3517
                    $table_formats[] = PodsForm::prepare( $type, $options );
3518
3519
                    $object_meta[ $field ] = $value;
3520
                }
3521
                // Store relational field data to be looped through later
3522
                else {
3523
                    // Convert values from a comma-separated string into an array
3524
                    if ( !is_array( $value ) )
3525
                        $value = explode( ',', $value );
3526
3527
                    $rel_fields[ $type ][ $field ] = $value;
3528
                    $rel_field_ids[] = $field_data[ 'id' ];
3529
                }
3530
            }
3531
        }
3532
3533
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) ) {
3534
            $object_name = $pod[ 'name' ];
3535
3536
            if ( !empty( $pod[ 'object' ] ) )
3537
                $object_name = $pod[ 'object' ];
3538
3539
            $object_name_field = 'post_type';
3540
3541
            if ( 'taxonomy' == $pod['type'] ) {
3542
                $object_name_field = 'taxonomy';
3543
            }
3544
3545
            $object_data[ $object_name_field ] = $object_name;
3546
        }
3547
3548
        if ( ( 'meta' == $pod[ 'storage' ] || 'settings' == $pod[ 'type' ] || ( 'taxonomy' == $pod[ 'type' ] && 'none' == $pod[ 'storage' ] ) ) && !in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3549
            if ( $allow_custom_fields && !empty( $custom_data ) )
3550
                $object_meta = array_merge( $custom_data, $object_meta );
3551
3552
			$fields_to_send = array_flip( array_keys( $object_meta ) );
3553
3554
			foreach ( $fields_to_send as $field => $field_data ) {
3555 View Code Duplication
				if ( isset( $object_fields[ $field ] ) ) {
3556
					$field_data = $object_fields[ $field ];
3557
				}
3558
				elseif ( isset( $fields[ $field ] ) ) {
3559
					$field_data = $fields[ $field ];
3560
				}
3561
				else {
3562
					unset( $fields_to_send[ $field ] );
3563
				}
3564
3565
				$fields_to_send[ $field ] = $field_data;
3566
			}
3567
3568
            $params->id = $this->save_wp_object( $object_type, $object_data, $object_meta, false, true, $fields_to_send );
3569
3570
            if ( !empty( $params->id ) && 'settings' == $object_type )
3571
                $params->id = $pod[ 'id' ];
3572
        }
3573
        else {
3574
            if ( ! in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3575
                $params->id = $this->save_wp_object( $object_type, $object_data, array(), false, true );
3576
            }
3577
3578
            if ( 'table' == $pod[ 'storage' ] ) {
3579
                // Every row should have an id set here, otherwise Pods with nothing
3580
                // but relationship fields won't get properly ID'd
3581
                if ( empty( $params->id ) )
3582
                    $params->id = 0;
3583
3584
                $table_data = array( 'id' => $params->id ) + $table_data;
3585
                array_unshift( $table_formats, '%d' );
3586
3587
                if ( !empty( $table_data ) ) {
3588
                    $sql = pods_data()->insert_on_duplicate( "@wp_pods_{$params->pod}", $table_data, $table_formats );
3589
3590
                    $id = pods_query( $sql, 'Cannot add/save table row' );
3591
3592
                    if ( empty( $params->id ) )
3593
                        $params->id = $id;
3594
                }
3595
            }
3596
        }
3597
3598
        $params->id = (int) $params->id;
3599
3600
		// Save terms for taxonomies associated to a post type
3601
        if ( 0 < $params->id && 'post_type' == $pod[ 'type' ] && !empty( $post_term_data ) ) {
3602
			foreach ( $post_term_data as $post_taxonomy => $post_terms ) {
3603
                $post_terms = (array) $post_terms;
3604
3605
                foreach ( $post_terms as $k => $v ) {
3606
                    if ( ! preg_match( '/[^0-9]/', $v ) ) {
3607
                        $v = (int) $v;
3608
                    }
3609
3610
                    $post_terms[ $k ] = $v;
3611
                }
3612
3613
				wp_set_object_terms( $params->id, $post_terms, $post_taxonomy );
3614
			}
3615
		}
3616
3617
        $no_conflict = pods_no_conflict_check( $pod[ 'type' ] );
3618
3619
        if ( !$no_conflict )
3620
            pods_no_conflict_on( $pod[ 'type' ] );
3621
3622
        // Save relationship / file data
3623
        if ( !empty( $rel_fields ) ) {
3624
            foreach ( $rel_fields as $type => $data ) {
3625
                // Only handle tableless fields
3626
                if ( !in_array( $type, $tableless_field_types ) ) {
3627
                    continue;
3628
				}
3629
3630
                foreach ( $data as $field => $values ) {
3631
                    $pick_val = pods_var( 'pick_val', $fields[ $field ] );
3632
3633
                    if ( 'table' == pods_var( 'pick_object', $fields[ $field ] ) ) {
3634
                        $pick_val = pods_var( 'pick_table', $fields[ $field ][ 'options' ], $pick_val, null, true );
3635
					}
3636
3637 View Code Duplication
                    if ( '__current__' == $pick_val ) {
3638
                        if ( is_object( $pod ) ) {
3639
                            $pick_val = $pod->pod;
3640
						}
3641
                        elseif ( is_array( $pod ) ) {
3642
                            $pick_val = $pod[ 'name' ];
3643
						}
3644
                        elseif ( 0 < strlen( $pod ) ) {
3645
                            $pick_val = $pod;
3646
						}
3647
                    }
3648
3649
                    $fields[ $field ][ 'options' ][ 'table_info' ] = pods_api()->get_table_info( pods_var( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ][ 'options' ] );
3650
3651
                    if ( isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && !empty( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] ) ) {
3652
						$search_data = pods( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] );
3653
3654
						$data_mode = 'pods';
3655
                    }
3656
					else {
3657
						$search_data = pods_data();
3658
						$search_data->table( $fields[ $field ][ 'options' ][ 'table_info' ] );
3659
3660
						$data_mode = 'data';
3661
					}
3662
3663
					$find_rel_params = array(
3664
						'select' => "`t`.`{$search_data->field_id}`",
3665
						'where' => "`t`.`{$search_data->field_slug}` = %s OR `t`.`{$search_data->field_index}` = %s",
3666
						'limit' => 1,
3667
						'pagination' => false,
3668
						'search' => false
3669
					);
3670
3671
					if ( empty( $search_data->field_slug ) && !empty( $search_data->field_index ) ) {
3672
						$find_rel_params[ 'where' ] = "`t`.`{$search_data->field_index}` = %s";
3673
					}
3674
					elseif ( empty( $search_data->field_slug ) && empty( $search_data->field_index ) ) {
3675
						$find_rel_params = false;
3676
					}
3677
3678
                    $related_limit = (int) pods_var_raw( $type . '_limit', $fields[ $field ][ 'options' ], 0 );
3679
3680 View Code Duplication
                    if ( 'single' == pods_var_raw( $type . '_format_type', $fields[ $field ][ 'options' ] ) ) {
3681
                        $related_limit = 1;
3682
					}
3683
3684
                    // Enforce integers / unique values for IDs
3685
                    $value_ids = array();
3686
3687
					$is_file_field = in_array( $type, PodsForm::file_field_types() );
3688
					$is_taggable = ( in_array( $type, PodsForm::tableless_field_types() ) && 1 == pods_v( $type . '_taggable', $fields[ $field ][ 'options' ] ) );
3689
3690
					// @todo Handle simple relationships eventually
3691
                    foreach ( $values as $v ) {
3692
                        if ( !empty( $v ) ) {
3693
							if ( !is_array( $v ) ) {
3694
								if ( !preg_match( '/[^0-9]/', $v ) ) {
3695
									$v = (int) $v;
3696
								}
3697
								// File handling
3698
								elseif ( $is_file_field ) {
3699
									// Get ID from GUID
3700
									$v = pods_image_id_from_field( $v );
3701
3702
									// If file not found, add it
3703
									if ( empty( $v ) ) {
3704
										$v = pods_attachment_import( $v );
3705
									}
3706
								}
3707
								// Reference by slug
3708
								else {
3709
									$v_data = false;
3710
3711
									if ( false !== $find_rel_params ) {
3712
										$rel_params = $find_rel_params;
3713
										$rel_params[ 'where' ] = $wpdb->prepare( $rel_params[ 'where' ], array( $v, $v ) );
3714
3715
										$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...
3716
3717
										$v_data = $search_data->fetch( $v );
3718
									}
3719
3720
									if ( !empty( $v_data ) && isset( $v_data[ $search_data->field_id ] ) ) {
3721
										$v = (int) $v_data[ $search_data->field_id ];
3722
									}
3723
									// Allow tagging for Pods objects
3724
									elseif ( $is_taggable && 'pods' == $data_mode ) {
3725
										$tag_data = array(
3726
											$search_data->field_index => $v
3727
										);
3728
3729
										if ( 'post_type' == $search_data->pod_data[ 'type' ] ) {
3730
											$tag_data[ 'post_status' ] = 'publish';
3731
										}
3732
3733
										/**
3734
										 * Filter for changing tag before adding new item.
3735
										 *
3736
										 * @param array $tag_data Fields for creating new item.
3737
										 * @param int $v Field ID of tag.
3738
										 * @param Pods $search_data Search object for tag.
3739
										 * @param string $field Table info for field.
3740
										 * @param array	$pieces Field array.
3741
										 *
3742
										 * @since 2.3.19
3743
										 */
3744
										$tag_data = apply_filters( 'pods_api_save_pod_item_taggable_data', $tag_data, $v, $search_data, $field, compact( $pieces ) );
3745
3746
										// Save $v to a new item on related object
3747
										$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...
3748
3749
										// @todo Support non-Pods for tagging
3750
									}
3751
								}
3752
							}
3753
							elseif ( $is_file_field && isset( $v[ 'id' ] ) ) {
3754
								$v = (int) $v[ 'id' ];
3755
							}
3756
							else {
3757
								continue;
3758
							}
3759
3760
							if ( !empty( $v ) && !in_array( $v, $value_ids ) ) {
3761
								$value_ids[] = $v;
3762
							}
3763
                        }
3764
                    }
3765
3766
                    $value_ids = array_unique( array_filter( $value_ids ) );
3767
3768
                    // Limit values
3769
                    if ( 0 < $related_limit && !empty( $value_ids ) )
3770
                        $value_ids = array_slice( $value_ids, 0, $related_limit );
3771
3772
                    // Get current values
3773
                    if ( 'pick' == $type && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ] ) )
3774
                        $related_ids = PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ];
3775
                    else
3776
                        $related_ids = $this->lookup_related_items( $fields[ $field ][ 'id' ], $pod[ 'id' ], $params->id, $fields[ $field ], $pod );
3777
3778
                    // Get ids to remove
3779
                    $remove_ids = array_diff( $related_ids, $value_ids );
3780
3781
                    // Delete relationships
3782
                    if ( !empty( $remove_ids ) )
3783
                        $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] );
3784
3785
                    // Save relationships
3786
                    if ( !empty( $value_ids ) )
3787
                        $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] );
3788
3789
                    // Run save function for field type (where needed)
3790
                    PodsForm::save( $type, $value_ids, $params->id, $field, array_merge( $fields[ $field ], $fields[ $field ][ 'options' ] ), array_merge( $fields, $object_fields ), $pod, $params );
3791
                }
3792
3793
                // Unset data no longer needed
3794
                if ( 'pick' == $type ) {
3795
                    foreach ( $data as $field => $values ) {
3796
                        if ( isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) ) {
3797
                            unset( PodsField_Pick::$related_data[ PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'related_field' ][ 'id' ] ] );
3798
                            unset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] );
3799
                        }
3800
                    }
3801
                }
3802
            }
3803
        }
3804
3805
        if ( !$no_conflict )
3806
            pods_no_conflict_off( $pod[ 'type' ] );
3807
3808
        // Clear cache
3809
        pods_cache_clear( $params->id, 'pods_items_' . $pod[ 'name' ] );
3810
3811
		if ( $params->clear_slug_cache && !empty( $pod[ 'field_slug' ] ) ) {
3812
			$slug = pods( $pod[ 'name' ], $params->id )->field( $pod[ 'field_slug' ] );
3813
3814
			if ( 0 < strlen( $slug ) ) {
3815
        		pods_cache_clear( $slug, 'pods_items_' . $pod[ 'name' ] );
3816
			}
3817
		}
3818
3819
        // Clear WP meta cache
3820
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3821
            $meta_type = $pod[ 'type' ];
3822
3823
            if ( 'post_type' == $meta_type )
3824
                $meta_type = 'post';
3825
3826
            wp_cache_delete( $params->id, $meta_type . '_meta' );
3827
            wp_cache_delete( $params->id, 'pods_' . $meta_type . '_meta' );
3828
        }
3829
3830
        if ( false === $bypass_helpers ) {
3831
			if ( $track_changed_fields ) {
3832
				$changed_fields = self::handle_changed_fields( $params->pod, $params->id, 'get' );
3833
			}
3834
3835
            $compact_pieces = compact( $pieces );
3836
3837
            // Plugin hooks
3838
            $this->do_hook( 'post_save_pod_item', $compact_pieces, $is_new_item, $params->id );
3839
            $this->do_hook( "post_save_pod_item_{$params->pod}", $compact_pieces, $is_new_item, $params->id );
3840
3841
            if ( $is_new_item ) {
3842
                $this->do_hook( 'post_create_pod_item', $compact_pieces, $params->id );
3843
                $this->do_hook( "post_create_pod_item_{$params->pod}", $compact_pieces, $params->id );
3844
            }
3845
            else {
3846
                $this->do_hook( 'post_edit_pod_item', $compact_pieces, $params->id );
3847
                $this->do_hook( "post_edit_pod_item_{$params->pod}", $compact_pieces, $params->id );
3848
            }
3849
3850
            // Call any post-save helpers (if not bypassed)
3851
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3852 View Code Duplication
                if ( !empty( $post_save_helpers ) ) {
3853
                    pods_deprecated( sprintf( __( 'Post-save helpers are deprecated, use the action pods_post_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3854
3855
                    foreach ( $post_save_helpers as $helper ) {
3856
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3857
3858
                        if ( false !== $helper && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
3859
                            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...
3860
                    }
3861
                }
3862
            }
3863
        }
3864
3865
        // Success! Return the id
3866
        return $params->id;
3867
3868
    }
3869
3870
    /**
3871
     * @see PodsAPI::save_pod_item
3872
     * Add multiple pod items
3873
     *
3874
     * $params['pod'] string The Pod name (pod or pod_id is required)
3875
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
3876
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
3877
     *
3878
     * $data['id'] int The item ID (optional)
3879
     * $data['data'] array An associative array of field names + values
3880
     *
3881
     * @param array|object $params An associative array of parameters, data excluded
3882
     * @param array $data An associative array of pod ids and field names + values (arrays of field data)
3883
     *
3884
     * @return int The item ID
3885
     * @since 2.0
3886
     */
3887
    public function save_pod_items ( $params, $data ) {
3888
        $params = (object) $params;
3889
3890
        $ids = array();
3891
3892
        foreach ( $data as $fields ) {
3893
            $params->data = $fields;
3894
3895
            if ( isset( $fields[ 'id' ] ) && isset( $fields[ 'data' ] ) ) {
3896
                $params->id = $fields[ 'id' ];
3897
                $params->data = $fields[ 'data' ];
3898
            }
3899
3900
            $ids[] = $this->save_pod_item( $params );
3901
        }
3902
3903
        return $ids;
3904
    }
3905
3906
	/**
3907
	 *Handle tracking changed fields or get them
3908
	 *
3909
	 * @param string $pod
3910
	 * @param int    $id
3911
	 * @param string $mode
3912
	 *
3913
	 * @return array List of changed fields (if $mode = 'get')
3914
	 */
3915
	public static function handle_changed_fields( $pod, $id, $mode = 'set' ) {
3916
3917
		static $changed_pods_cache = array();
3918
		static $old_fields_cache = array();
3919
		static $changed_fields_cache = array();
3920
3921
		$cache_key = $pod . '|' . $id;
3922
3923
		$export_params = array(
3924
			'depth' => 1,
3925
		);
3926
3927
		if ( in_array( $mode, array( 'set', 'reset' ), true ) ) {
3928
			if ( isset( $changed_fields_cache[ $cache_key ] ) ) {
3929
				unset( $changed_fields_cache[ $cache_key ] );
3930
			}
3931
3932
			if ( empty( $old_fields_cache[ $cache_key ] ) || 'reset' === $mode ) {
3933
				$old_fields_cache[ $cache_key ] = array();
3934
3935
				if ( ! empty( $id ) ) {
3936
					if ( empty( $changed_pods_cache[ $cache_key ] ) ) {
3937
						$changed_pods_cache[ $pod ] = pods( $pod );
3938
					}
3939
3940
					$changed_pods_cache[ $pod ]->fetch( $id );
3941
3942
					$old_fields_cache[ $cache_key ] = $changed_pods_cache[ $pod ]->export( $export_params );
3943
				}
3944
			}
3945
		}
3946
3947
		$changed_fields = array();
3948
3949
		if ( isset( $changed_fields_cache[ $cache_key ] ) ) {
3950
			$changed_fields = $changed_fields_cache[ $cache_key ];
3951
		} elseif ( isset( $old_fields_cache[ $cache_key ] ) ) {
3952
			$old_fields = $old_fields_cache[ $cache_key ];
3953
3954
			if ( 'get' === $mode ) {
3955
				if ( ! empty( $changed_pods_cache[ $pod ] ) ) {
3956
					if ( $id != $changed_pods_cache[ $pod ]->id() ) {
3957
						$changed_pods_cache[ $pod ]->fetch( $id );
3958
					}
3959
3960
					$new_fields = $changed_pods_cache[ $pod ]->export( $export_params );
3961
3962
					foreach ( $new_fields as $field => $value ) {
3963
						if ( ! isset( $old_fields[ $field ] ) || $value != $old_fields[ $field ] ) {
3964
							$changed_fields[ $field ] = $value;
3965
						}
3966
					}
3967
3968
					$changed_fields_cache[ $cache_key ] = $changed_fields;
3969
				}
3970
			}
3971
		}
3972
3973
		return $changed_fields;
3974
3975
	}
3976
3977
	/**
3978
	 * Get the fields that have changed during a save
3979
	 *
3980
	 * @param array $pieces Pieces array from save_pod_item
3981
	 *
3982
	 * @return array Array of fields and values that have changed
3983
	 *               
3984
	 * @deprecated Use PodsAPI::handle_changed_fields
3985
	 */
3986
	public function get_changed_fields( $pieces ) {
3987
3988
		return self::handle_changed_fields( $pieces['params']->pod, $pieces['params']->id, 'get' );
3989
3990
	}
3991
3992
    /**
3993
     * Save relationships
3994
     *
3995
     * @param int $id ID of item
3996
     * @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...
3997
     * @param array $pod Pod data
3998
     * @param array $field Field data
3999
     */
4000
    public function save_relationships ( $id, $related_ids, $pod, $field ) {
4001
        // Get current values
4002
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ] ) )
4003
            $current_ids = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ];
4004
        else
4005
            $current_ids = $this->lookup_related_items( $field[ 'id' ], $pod[ 'id' ], $id, $field, $pod );
4006
4007
	    if ( isset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] ) ) {
4008
		    // Delete relationship from cache
4009
		    unset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] );
4010
	    }
4011
4012
        if ( !is_array( $related_ids ) )
4013
            $related_ids = implode( ',', $related_ids );
4014
4015
        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...
4016
            $related_ids[ $k ] = (int) $related_id;
4017
        }
4018
4019
        $related_ids = array_unique( array_filter( $related_ids ) );
4020
4021
        $related_limit = (int) pods_var_raw( $field[ 'type' ] . '_limit', $field[ 'options' ], 0 );
4022
4023 View Code Duplication
        if ( 'single' == pods_var_raw( $field[ 'type' ] . '_format_type', $field[ 'options' ] ) )
4024
            $related_limit = 1;
4025
4026
        // Limit values
4027
        if ( 0 < $related_limit && !empty( $related_ids ) )
4028
            $related_ids = array_slice( $related_ids, 0, $related_limit );
4029
4030
        // Post Types, Media, Users, and Comments (meta-based)
4031 View Code Duplication
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
4032
            $object_type = $pod[ 'type' ];
4033
4034
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
4035
                $object_type = 'post';
4036
            elseif ( 'taxonomy' == $object_type )
4037
                $object_type = 'term';
4038
4039
            delete_metadata( $object_type, $id, $field[ 'name' ] );
4040
4041
            if ( !empty( $related_ids ) ) {
4042
                update_metadata( $object_type, $id, '_pods_' . $field[ 'name' ], $related_ids );
4043
4044
                foreach ( $related_ids as $related_id ) {
4045
                    add_metadata( $object_type, $id, $field[ 'name' ], $related_id );
4046
                }
4047
            }
4048
            else
4049
                delete_metadata( $object_type, $id, '_pods_' . $field[ 'name' ] );
4050
        }
4051
        // Custom Settings Pages (options-based)
4052
        elseif ( 'settings' == $pod[ 'type' ] ) {
4053
            if ( !empty( $related_ids ) )
4054
                update_option( $pod[ 'name' ] . '_' . $field[ 'name' ], $related_ids );
4055
            else
4056
                delete_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
4057
        }
4058
4059
        $related_pod_id = $related_field_id = 0;
4060
4061
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && !empty( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ] ) ) {
4062
            $related_pod_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_pod' ][ 'id' ];
4063
            $related_field_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ][ 'id' ];
4064
        }
4065
4066
        // Relationships table
4067
        if ( !pods_tableless() ) {
4068
            $related_weight = 0;
4069
4070
            foreach ( $related_ids as $related_id ) {
4071
                if ( in_array( $related_id, $current_ids ) ) {
4072
                    pods_query( "
4073
                        UPDATE `@wp_podsrel`
4074
                        SET
4075
                            `pod_id` = %d,
4076
                            `field_id` = %d,
4077
                            `item_id` = %d,
4078
                            `related_pod_id` = %d,
4079
                            `related_field_id` = %d,
4080
                            `related_item_id` = %d,
4081
                            `weight` = %d
4082
                        WHERE
4083
                            `pod_id` = %d
4084
                            AND `field_id` = %d
4085
                            AND `item_id` = %d
4086
                            AND `related_item_id` = %d
4087
                    ", array(
4088
                        $pod[ 'id' ],
4089
                        $field[ 'id' ],
4090
                        $id,
4091
                        $related_pod_id,
4092
                        $related_field_id,
4093
                        $related_id,
4094
                        $related_weight,
4095
4096
                        $pod[ 'id' ],
4097
                        $field[ 'id' ],
4098
                        $id,
4099
                        $related_id,
4100
                    ) );
4101
                }
4102
                else {
4103
                    pods_query( "
4104
                        INSERT INTO `@wp_podsrel`
4105
                            (
4106
                                `pod_id`,
4107
                                `field_id`,
4108
                                `item_id`,
4109
                                `related_pod_id`,
4110
                                `related_field_id`,
4111
                                `related_item_id`,
4112
                                `weight`
4113
                            )
4114
                        VALUES ( %d, %d, %d, %d, %d, %d, %d )
4115
                    ", array(
4116
                        $pod[ 'id' ],
4117
                        $field[ 'id' ],
4118
                        $id,
4119
                        $related_pod_id,
4120
                        $related_field_id,
4121
                        $related_id,
4122
                        $related_weight
4123
                    ) );
4124
                }
4125
4126
                $related_weight++;
4127
            }
4128
        }
4129
    }
4130
4131
    /**
4132
     * Duplicate a Pod
4133
     *
4134
     * $params['id'] int The Pod ID
4135
     * $params['name'] string The Pod name
4136
     * $params['new_name'] string The new Pod name
4137
     *
4138
     * @param array $params An associative array of parameters
4139
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4140
     *
4141
     * @return int New Pod ID
4142
     * @since 2.3
4143
     */
4144
    public function duplicate_pod ( $params, $strict = false ) {
4145 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4146
            if ( is_numeric( $params ) )
4147
                $params = array( 'id' => $params );
4148
            else
4149
                $params = array( 'name' => $params );
4150
4151
            $params = (object) pods_sanitize( $params );
4152
        }
4153
        else
4154
            $params = (object) pods_sanitize( $params );
4155
4156
        $params->table_info = false;
4157
4158
        $pod = $this->load_pod( $params, $strict );
4159
4160
        if ( empty( $pod ) ) {
4161
            if ( false !== $strict )
4162
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4163
4164
            return false;
4165
        }
4166
        elseif ( in_array( $pod[ 'type' ], array( 'media', 'user', 'comment' ) ) ) {
4167
            if ( false !== $strict )
4168
                return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this );
4169
4170
            return false;
4171
        }
4172
        elseif ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod[ 'object' ] ) ) {
4173
			$pod[ 'object' ] = '';
4174
        }
4175
4176
        unset( $pod[ 'id' ] );
4177
4178
        if ( isset( $params->new_name ) )
4179
            $pod[ 'name' ] = $params->new_name;
4180
4181
        $try = 1;
4182
4183
        $check_name = $pod[ 'name' ];
4184
        $new_label = $pod[ 'label' ];
4185
4186 View Code Duplication
        while ( $this->load_pod( array( 'name' => $check_name, 'table_info' => false ), false ) ) {
4187
            $try++;
4188
4189
            $check_name = $pod[ 'name' ] . $try;
4190
            $new_label = $pod[ 'label' ] . $try;
4191
        }
4192
4193
        $pod[ 'name' ] = $check_name;
4194
        $pod[ 'label' ] = $new_label;
4195
4196
        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
4197
            unset( $pod[ 'fields' ][ $field ][ 'id' ] );
4198
        }
4199
4200
        return $this->save_pod( $pod );
4201
    }
4202
4203
    /**
4204
     * Duplicate a Field
4205
     *
4206
     * $params['pod_id'] int The Pod ID
4207
     * $params['pod'] string The Pod name
4208
     * $params['id'] int The Field ID
4209
     * $params['name'] string The Field name
4210
     * $params['new_name'] string The new Field name
4211
     *
4212
     * @param array $params An associative array of parameters
4213
     * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error
4214
     *
4215
     * @return int New Field ID
4216
     * @since 2.3.10
4217
     */
4218
	public function duplicate_field( $params, $strict = false ) {
4219
4220
		if ( !is_object( $params ) && !is_array( $params ) ) {
4221
			if ( is_numeric( $params ) ) {
4222
				$params = array( 'id' => $params );
4223
			}
4224
			else {
4225
				$params = array( 'name' => $params );
4226
			}
4227
		}
4228
4229
		$params = (object) pods_sanitize( $params );
4230
4231
		$params->table_info = false;
4232
4233
		$field = $this->load_field( $params, $strict );
4234
4235
		if ( empty( $field ) ) {
4236
			if ( false !== $strict ) {
4237
				return pods_error( __( 'Field not found', 'pods' ), $this );
4238
			}
4239
4240
			return false;
4241
		}
4242
4243
		unset( $field[ 'id' ] );
4244
4245
		if ( isset( $params->new_name ) ) {
4246
			$field[ 'name' ] = $params->new_name;
4247
		}
4248
4249
		$try = 1;
4250
4251
		$check_name = $field[ 'name' ];
4252
		$new_label = $field[ 'label' ];
4253
4254 View Code Duplication
		while ( $this->load_field( array( 'pod_id' => $field[ 'pod_id' ], 'name' => $check_name, 'table_info' => false ), false ) ) {
4255
			$try++;
4256
4257
			$check_name = $field[ 'name' ] . $try;
4258
			$new_label = $field[ 'label' ] . $try;
4259
		}
4260
4261
		$field[ 'name' ] = $check_name;
4262
		$field[ 'label' ] = $new_label;
4263
4264
		return $this->save_field( $field );
4265
4266
	}
4267
4268
	/**
4269
	* @see PodsAPI::save_pod_item
4270
	*
4271
	* Duplicate a pod item
4272
	*
4273
	* $params['pod'] string The Pod name
4274
	* $params['id'] int The item's ID from the wp_pods_* table
4275
	*
4276
	* @param array $params An associative array of parameters
4277
	*
4278
	* @return int The table row ID
4279
	*
4280
	* @since 1.12
4281
	*/
4282
	public function duplicate_pod_item ( $params ) {
4283
4284
		$params = (object) pods_sanitize( $params );
4285
4286
		$load_pod_params = array(
4287
			'name' => $params->pod,
4288
			'table_info' => false,
4289
		);
4290
4291
		$pod = $this->load_pod( $load_pod_params );
4292
4293
		if ( false === $pod ) {
4294
			return pods_error( __( 'Pod not found', 'pods' ), $this );
4295
		}
4296
4297
		$pod = pods( $params->pod, $params->id );
4298
4299
		$params->pod = $pod->pod;
4300
		$params->pod_id = $pod->pod_id;
4301
4302
		$fields = (array) pods_var_raw( 'fields', $pod->pod_data, array(), null, true );
4303
		$object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4304
4305
		if ( ! empty( $object_fields ) ) {
4306
			$fields = array_merge( $object_fields, $fields );
4307
		}
4308
4309
		$save_params = array(
4310
			'pod' => $params->pod,
4311
			'data' => array()
4312
		);
4313
4314
		$ignore_fields = array(
4315
			$pod->pod_data['field_id'],
4316
			$pod->pod_data['field_slug'],
4317
		);
4318
4319
		if ( in_array( $pod->pod_data['type'], array( 'post_type', 'media' ) ) ) {
4320
			$ignore_fields = array(
4321
				'ID',
4322
				'post_name',
4323
				'post_date',
4324
				'post_date_gmt',
4325
				'post_modified',
4326
				'post_modified_gmt',
4327
				'guid',
4328
		        );
4329
		} elseif ( 'term' == $pod->pod_data['type'] ) {
4330
			$ignore_fields = array(
4331
				'term_id',
4332
				'term_taxonomy_id',
4333
				'slug',
4334
		        );
4335
		} elseif ( 'user' == $pod->pod_data['type'] ) {
4336
			$ignore_fields = array(
4337
				'ID',
4338
				'user_nicename',
4339
		        );
4340
		} elseif ( 'comment' == $pod->pod_data['type'] ) {
4341
			$ignore_fields = array(
4342
				'comment_ID',
4343
		        );
4344
		} elseif ( 'settings' == $pod->pod_data['type'] ) {
4345
			return pods_error( __( 'Settings do not support duplication.', 'pods' ), $this );
4346
		}
4347
4348
		/**
4349
		 * Filter the fields to ignore during duplication
4350
		 *
4351
		 * @since 2.6.6
4352
		 *
4353
		 * @param array  $ignore_fields Fields to ignore and not save during duplication
4354
		 * @param Pods   $pod           Pod object
4355
		 * @param array  $fields        Fields on the pod to duplicate
4356
		 * @param object $params        Params passed into duplicate_pod_item()
4357
		 */
4358
		$ignore_fields = apply_filters( 'pods_api_duplicate_pod_item_ignore_fields', $ignore_fields, $pod, $fields, $params );
4359
4360
		foreach ( $fields as $field ) {
4361
			if ( in_array( $field['name'], $ignore_fields ) ) {
4362
				continue;
4363
			}
4364
4365
			$field = array(
4366
				'name' => $field['name'],
4367
				'output' => 'ids'
4368
			);
4369
4370
			$value = $pod->field( $field );
4371
4372
			// @todo Add post type compatibility to set unique post_title
4373
			// @todo Add term compatibility to set unique name
4374
			// @todo Add user compatibility to set unique user_login/user_email
4375
4376
			if ( ! empty( $value ) || ( ! is_array( $value ) && 0 < strlen( $value ) ) ) {
4377
				$save_params['data'][ $field['name'] ] = $value;
4378
			}
4379
		}
4380
4381
		$save_params = $this->do_hook( 'duplicate_pod_item', $save_params, $pod->pod, $pod->id(), $params );
4382
4383
		$id = $this->save_pod_item( $save_params );
4384
4385
		return $id;
4386
4387
	}
4388
4389
    /**
4390
     * @see pods()
4391
     *
4392
     * Export a pod item
4393
     *
4394
     * $params['pod'] string The Pod name
4395
     * $params['id'] int The item's ID from the wp_pods_* table
4396
     * $params['fields'] array The fields to export
4397
     * $params['depth'] int How many levels deep to export data
4398
     *
4399
     * @param array $params An associative array of parameters
4400
     * @param object $pod (optional) Pods object
4401
     *
4402
     * @return int The table row ID
4403
     * @since 1.12
4404
     */
4405
    public function export_pod_item ( $params, $pod = null ) {
4406
        if ( !is_object( $pod ) || 'Pods' != get_class( $pod ) ) {
4407
            if ( empty( $params ) )
4408
                return false;
4409
4410
            $params = (object) pods_sanitize( $params );
4411
4412
            $pod = pods( $params->pod, $params->id, false );
4413
4414
            if ( empty( $pod ) )
4415
                return false;
4416
        }
4417
4418
        $fields = (array) pods_var_raw( 'fields', $params, array(), null, true );
4419
        $depth = (int) pods_var_raw( 'depth', $params, 2, null, true );
4420
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4421
        $flatten = (boolean) pods_var( 'flatten', $params, false, null, true );
4422
4423
        if ( empty( $fields ) ) {
4424
            $fields = $pod->fields;
4425
            $fields = array_merge( $fields, $object_fields );
4426
        }
4427
4428
        $data = $this->export_pod_item_level( $pod, $fields, $depth, $flatten );
4429
4430
        $data = $this->do_hook( 'export_pod_item', $data, $pod->pod, $pod->id(), $pod, $fields, $depth, $flatten );
4431
4432
        return $data;
4433
    }
4434
4435
    /**
4436
     * Export a pod item by depth level
4437
     *
4438
     * @param Pods $pod Pods object
4439
     * @param array $fields Fields to export
4440
     * @param int $depth Depth limit
4441
     * @param boolean $flatten Whether to flatten arrays for display
4442
     * @param int $current_depth Current depth level
4443
     *
4444
     * @return array Data array
4445
     *
4446
     * @since 2.3
4447
     */
4448
    private function export_pod_item_level ( $pod, $fields, $depth, $flatten = false, $current_depth = 1 ) {
4449
        $tableless_field_types = PodsForm::tableless_field_types();
4450
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4451
4452
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4453
4454
        $export_fields = array();
4455
4456
        foreach ( $fields as $k => $field ) {
4457
            if ( !is_array( $field ) ) {
4458
                $field = array(
4459
                    'id' => 0,
4460
                    'name' => $field
4461
                );
4462
            }
4463
4464
            if ( isset( $pod->fields[ $field[ 'name' ] ] ) ) {
4465
                $field = $pod->fields[ $field[ 'name' ] ];
4466
                $field[ 'lookup_name' ] = $field[ 'name' ];
4467
4468
                if ( in_array( $field[ 'type' ], $tableless_field_types ) && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4469
                    if ( 'pick' == $field[ 'type' ] ) {
4470
                        if ( empty( $field[ 'table_info' ] ) )
4471
                            $field[ 'table_info' ] = $this->get_table_info( pods_var_raw( 'pick_object', $field ), pods_var_raw( 'pick_val', $field ), null, null, $field );
4472
4473
                        if ( !empty( $field[ 'table_info' ] ) )
4474
                            $field[ 'lookup_name' ] .= '.' . $field[ 'table_info' ][ 'field_id' ];
4475
                    }
4476
                    elseif ( in_array( $field[ 'type' ], PodsForm::file_field_types() ) )
4477
                        $field[ 'lookup_name' ] .= '.guid';
4478
                }
4479
4480
                $export_fields[ $field[ 'name' ] ] = $field;
4481
            }
4482
            elseif ( isset( $object_fields[ $field[ 'name' ] ] ) ) {
4483
                $field = $object_fields[ $field[ 'name' ] ];
4484
                $field[ 'lookup_name' ] = $field[ 'name' ];
4485
4486
                $export_fields[ $field[ 'name' ] ] = $field;
4487
            }
4488
            elseif ( $field[ 'name' ] == $pod->pod_data[ 'field_id' ] ) {
4489
                $field[ 'type' ] = 'number';
4490
                $field[ 'lookup_name' ] = $field[ 'name' ];
4491
4492
                $export_fields[ $field[ 'name' ] ] = $field;
4493
            }
4494
        }
4495
4496
        $data = array();
4497
4498
        foreach ( $export_fields as $field ) {
4499
            // Return IDs (or guid for files) if only one level deep
4500
            if ( 1 == $depth )
4501
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'lookup_name' ], 'output' => 'arrays' ) );
4502
            // Recurse depth levels for pick fields if $depth allows
4503
            elseif ( ( -1 == $depth || $current_depth < $depth ) && 'pick' == $field[ 'type' ] && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4504
                $related_data = array();
4505
4506
                $related_ids = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'ids' ) );
4507
4508
                if ( !empty( $related_ids ) ) {
4509
                    $related_ids = (array) $related_ids;
4510
4511
                    $pick_object = pods_var_raw( 'pick_object', $field );
4512
4513
                    $related_pod = pods( pods_var_raw( 'pick_val', $field ), null, false );
4514
4515
                    // If this isn't a Pod, return data exactly as Pods does normally
4516
                    if ( empty( $related_pod ) || ( 'pod' != $pick_object && $pick_object != $related_pod->pod_data[ 'type' ] ) || $related_pod->pod == $pod->pod )
4517
                        $related_data = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4518
                    else {
4519
                        $related_object_fields = (array) pods_var_raw( 'object_fields', $related_pod->pod_data, array(), null, true );
4520
4521
                        $related_fields = array_merge( $related_pod->fields, $related_object_fields );
4522
4523
                        foreach ( $related_ids as $related_id ) {
4524
                            if ( $related_pod->fetch( $related_id ) ) {
4525
                                $related_item = $this->export_pod_item_level( $related_pod, $related_fields, $depth, $flatten, ( $current_depth + 1 ) );
4526
4527
                                $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 ) );
4528
                            }
4529
                        }
4530
4531
                        if ( $flatten && !empty( $related_data ) )
4532
                            $related_data = pods_serial_comma( array_values( $related_data ), array( 'and' => '', 'field_index' => $related_pod->pod_data[ 'field_index' ] ) );
4533
                    }
4534
                }
4535
4536
                $data[ $field[ 'name' ] ] = $related_data;
4537
            }
4538
            // Return data exactly as Pods does normally
4539
            else
4540
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4541
4542
            if ( $flatten && is_array( $data[ $field[ 'name' ] ] ) )
4543
                $data[ $field[ 'name' ] ] = pods_serial_comma( $data[ $field[ 'name' ] ], array( 'field' => $field[ 'name' ], 'fields' => $export_fields, 'and' => '' ) );
4544
        }
4545
4546
	$data[ 'id' ] = (int) $pod->id();
4547
        return $data;
4548
    }
4549
4550
    /**
4551
     * Reorder a Pod
4552
     *
4553
     * $params['pod'] string The Pod name
4554
     * $params['field'] string The field name of the field to reorder
4555
     * $params['order'] array The key => value array of items to reorder (key should be an integer)
4556
     *
4557
     * @param array $params An associative array of parameters
4558
     *
4559
     * @return bool
4560
     *
4561
     * @since 1.9.0
4562
     */
4563
    public function reorder_pod_item ( $params ) {
4564
        $params = (object) pods_sanitize( $params );
4565
4566
        // @deprecated 2.0
4567
        if ( isset( $params->datatype ) ) {
4568
            pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4569
4570
            $params->pod = $params->datatype;
4571
4572
            unset( $params->datatype );
4573
        }
4574
4575
        if ( null === pods_var_raw( 'pod', $params, null, null, true ) )
4576
            return pods_error( __( '$params->pod is required', 'pods' ), $this );
4577
4578
        if ( !is_array( $params->order ) )
4579
            $params->order = explode( ',', $params->order );
4580
4581
        $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
4582
4583
        $params->name = $pod[ 'name' ];
4584
4585
        if ( false === $pod )
4586
            return pods_error( __( 'Pod is required', 'pods' ), $this );
4587
4588
        foreach ( $params->order as $order => $id ) {
4589
            if ( isset( $pod[ 'fields' ][ $params->field ] ) || isset( $pod[ 'object_fields' ][ $params->field ] ) ) {
4590
                if ( 'table' == $pod[ 'storage' ] && ( !pods_tableless() ) ) {
4591
                    if ( isset( $pod[ 'fields' ][ $params->field ] ) )
4592
                        pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" );
4593
                    else
4594
                        pods_query( "UPDATE `{$pod['table']}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `{$pod['field_id']}` = " . pods_absint( $id ) . " LIMIT 1" );
4595
                }
4596
                else
4597
                    $this->save_pod_item( array( 'pod' => $params->pod, 'pod_id' => $params->pod_id, 'id' => $id, 'data' => array( $params->field => pods_absint( $order ) ) ) );
4598
            }
4599
        }
4600
4601
        return true;
4602
    }
4603
4604
    /**
4605
     *
4606
     * Delete all content for a Pod
4607
     *
4608
     * $params['id'] int The Pod ID
4609
     * $params['name'] string The Pod name
4610
     *
4611
     * @param array $params An associative array of parameters
4612
     * @param array $pod Pod data
4613
     *
4614
     * @return bool
4615
     *
4616
     * @uses pods_query
4617
     * @uses pods_cache_clear
4618
     *
4619
     * @since 1.9.0
4620
     */
4621
    public function reset_pod ( $params, $pod = false ) {
4622
        $params = (object) pods_sanitize( $params );
4623
4624
        $params->table_info = true;
4625
4626
        if ( empty( $pod ) )
4627
            $pod = $this->load_pod( $params );
4628
4629
        if ( false === $pod )
4630
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4631
4632
        $params->id = $pod[ 'id' ];
4633
        $params->name = $pod[ 'name' ];
4634
4635 View Code Duplication
        if ( !pods_tableless() ) {
4636
            if ( 'table' == $pod[ 'storage' ] ) {
4637
                try {
4638
                    pods_query( "TRUNCATE `@wp_pods_{$params->name}`", false );
4639
                }
4640
                catch ( Exception $e ) {
4641
                    // Allow pod to be reset if the table doesn't exist
4642
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4643
                        return pods_error( $e->getMessage(), $this );
4644
                }
4645
            }
4646
4647
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4648
        }
4649
4650
        // @todo Delete relationships from tableless relationships
4651
4652
        // Delete all posts/revisions from this post type
4653
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media' ) ) ) {
4654
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4655
4656
            $sql = "
4657
                DELETE `t`, `r`, `m`
4658
                FROM `{$pod['table']}` AS `t`
4659
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4660
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4661
                LEFT JOIN `{$pod['table']}` AS `r`
4662
                    ON `r`.`post_parent` = `t`.`{$pod['field_id']}` AND `r`.`post_status` = 'inherit'
4663
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4664
            ";
4665
4666
            pods_query( $sql, false );
4667
        }
4668
        // Delete all terms from this taxonomy
4669
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
4670
            if ( function_exists( 'get_term_meta' ) ) {
4671
                $sql = "
4672
                    DELETE `t`, `m`, `tt`, `tr`
4673
                    FROM `{$pod['table']}` AS `t`
4674
                    LEFT JOIN `{$pod['meta_table']}` AS `m`
4675
                        ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4676
                    " . $pod['join']['tt'] . "
4677
                    " . $pod['join']['tr'] . "
4678
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4679
                ";
4680
            } else {
4681
                $sql = "
4682
                    DELETE `t`, `tt`, `tr`
4683
                    FROM `{$pod['table']}` AS `t`
4684
                    " . $pod['join']['tt'] . "
4685
                    " . $pod['join']['tr'] . "
4686
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4687
                ";
4688
            }
4689
4690
            pods_query( $sql, false );
4691
        }
4692
        // Delete all users except the current one
4693
        elseif ( 'user' == $pod[ 'type' ] ) {
4694
            $sql = "
4695
                DELETE `t`, `m`
4696
                FROM `{$pod['table']}` AS `t`
4697
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4698
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4699
                WHERE `t`.`{$pod['field_id']}` != " . (int) get_current_user_id() . "
4700
            ";
4701
4702
            pods_query( $sql, false );
4703
        }
4704
        // Delete all comments
4705
        elseif ( 'comment' == $pod[ 'type' ] ) {
4706
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4707
4708
            $sql = "
4709
                DELETE `t`, `m`
4710
                FROM `{$pod['table']}` AS `t`
4711
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4712
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4713
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4714
            ";
4715
4716
            pods_query( $sql, false );
4717
        }
4718
4719
        pods_cache_clear( true ); // only way to reliably clear out cached data across an entire group
4720
4721
        return true;
4722
    }
4723
4724
    /**
4725
     * Delete a Pod and all its content
4726
     *
4727
     * $params['id'] int The Pod ID
4728
     * $params['name'] string The Pod name
4729
     *
4730
     * @param array $params An associative array of parameters
4731
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4732
     * @param bool $delete_all (optional) Whether to delete all content from a WP object
4733
     *
4734
     * @uses PodsAPI::load_pod
4735
     * @uses wp_delete_post
4736
     * @uses pods_query
4737
     *
4738
     * @return bool
4739
     * @since 1.7.9
4740
     */
4741
    public function delete_pod ( $params, $strict = false, $delete_all = false ) {
4742
        /**
4743
         * @var $wpdb wpdb
4744
         */
4745
        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...
4746
4747 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4748
            if ( is_numeric( $params ) )
4749
                $params = array( 'id' => $params );
4750
            else
4751
                $params = array( 'name' => $params );
4752
4753
            $params = (object) pods_sanitize( $params );
4754
        }
4755
        else
4756
            $params = (object) pods_sanitize( $params );
4757
4758
        $params->table_info = false;
4759
4760
        $pod = $this->load_pod( $params, $strict );
4761
4762
        if ( empty( $pod ) ) {
4763
            if ( false !== $strict )
4764
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4765
4766
            return false;
4767
        }
4768
4769
        $params->id = (int) $pod[ 'id' ];
4770
        $params->name = $pod[ 'name' ];
4771
4772
        foreach ( $pod[ 'fields' ] as $field ) {
4773
            $field[ 'pod' ] = $pod;
4774
4775
            $this->delete_field( $field, false );
4776
        }
4777
4778
        // Only delete the post once the fields are taken care of, it's not required anymore
4779
        $success = wp_delete_post( $params->id );
4780
4781
        if ( !$success )
4782
            return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this );
4783
4784
        // Reset content
4785
        if ( $delete_all )
4786
            $this->reset_pod( $params, $pod );
4787
4788 View Code Duplication
        if ( !pods_tableless() ) {
4789
            if ( 'table' == $pod[ 'storage' ] ) {
4790
                try {
4791
                    pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false );
4792
                }
4793
                catch ( Exception $e ) {
4794
                    // Allow pod to be deleted if the table doesn't exist
4795
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4796
                        return pods_error( $e->getMessage(), $this );
4797
                }
4798
            }
4799
4800
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4801
        }
4802
4803
        // @todo Delete relationships from tableless relationships
4804
4805
        // Delete any relationship references
4806
        $sql = "
4807
            DELETE `pm`
4808
            FROM `{$wpdb->postmeta}` AS `pm`
4809
            LEFT JOIN `{$wpdb->posts}` AS `p`
4810
                ON `p`.`post_type` = '_pods_field'
4811
                    AND `p`.`ID` = `pm`.`post_id`
4812
            LEFT JOIN `{$wpdb->postmeta}` AS `pm2`
4813
                ON `pm2`.`meta_key` = 'pick_object'
4814
                    AND `pm2`.`meta_value` = 'pod'
4815
                    AND `pm2`.`post_id` = `pm`.`post_id`
4816
            WHERE
4817
                `p`.`ID` IS NOT NULL
4818
                AND `pm2`.`meta_id` IS NOT NULL
4819
                AND `pm`.`meta_key` = 'pick_val'
4820
                AND `pm`.`meta_value` = '{$params->name}'
4821
        ";
4822
4823
        pods_query( $sql );
4824
4825
        $this->cache_flush_pods( $pod );
4826
4827
        return true;
4828
    }
4829
4830
    /**
4831
     * Drop a field within a Pod
4832
     *
4833
     * $params['id'] int The field ID
4834
     * $params['name'] int The field name
4835
     * $params['pod'] string The Pod name
4836
     * $params['pod_id'] string The Pod name
4837
     *
4838
     * @param array $params An associative array of parameters
4839
     * @param bool $table_operation Whether or not to handle table operations
4840
     *
4841
     * @uses PodsAPI::load_field
4842
     * @uses wp_delete_post
4843
     * @uses pods_query
4844
     *
4845
     * @return bool
4846
     * @since 1.7.9
4847
     */
4848
    public function delete_field ( $params, $table_operation = true ) {
4849
        /**
4850
         * @var $wpdb wpdb
4851
         */
4852
        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...
4853
4854
        $tableless_field_types = PodsForm::tableless_field_types();
4855
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4856
4857
        $params = (object) pods_sanitize( $params );
4858
4859
        if ( !isset( $params->pod ) )
4860
            $params->pod = '';
4861
4862
        if ( !isset( $params->pod_id ) )
4863
            $params->pod_id = 0;
4864
4865
        $pod = $params->pod;
4866
4867
        $save_pod = false;
4868
4869
        if ( !is_array( $pod ) )
4870
            $pod = $this->load_pod( array( 'name' => $pod, 'id' => $params->pod_id, 'table_info' => false ) );
4871
        else
4872
            $save_pod = true;
4873
4874
        if ( empty( $pod ) )
4875
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4876
4877
        $params->pod_id = $pod[ 'id' ];
4878
        $params->pod = $pod[ 'name' ];
4879
4880
        if ( !isset( $params->name ) )
4881
            $params->name = '';
4882
4883
        if ( !isset( $params->id ) )
4884
            $params->id = 0;
4885
4886
        $field = $this->load_field( array( 'name' => $params->name, 'id' => $params->id, 'pod' => $params->pod, 'pod_id' => $params->pod_id ) );
4887
4888
        if ( false === $field )
4889
            return pods_error( __( 'Field not found', 'pods' ), $this );
4890
4891
        $params->id = $field[ 'id' ];
4892
        $params->name = $field[ 'name' ];
4893
4894
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
4895
        $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params );
4896
4897
        if ( $table_operation && 'table' == $pod[ 'storage' ] && ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) )
4898
            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false );
4899
4900
        $success = wp_delete_post( $params->id );
4901
4902
        if ( !$success )
4903
            return pods_error( __( 'Field unable to be deleted', 'pods' ), $this );
4904
4905
        $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm
4906
            LEFT JOIN {$wpdb->posts} AS p
4907
                ON p.post_type = '_pods_field' AND p.ID = pm.post_id
4908
            WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) );
4909
4910
        if ( ( !pods_tableless() ) && $table_operation ) {
4911
            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 );
4912
        }
4913
4914
        // @todo Delete tableless relationship meta
4915
4916
        if ( true === $save_pod )
4917
            $this->cache_flush_pods( $pod );
4918
4919
        return true;
4920
    }
4921
4922
    /**
4923
     * Drop a Pod Object
4924
     *
4925
     * $params['id'] int The object ID
4926
     * $params['name'] string The object name
4927
     * $params['type'] string The object type
4928
     *
4929
     * @param array|object $params An associative array of parameters
4930
     *
4931
     * @uses wp_delete_post
4932
     *
4933
     * @return bool
4934
     * @since 2.0
4935
     */
4936
    public function delete_object ( $params ) {
4937
        $params = (object) $params;
4938
        $object = $this->load_object( $params );
4939
4940 View Code Duplication
        if ( empty( $object ) )
4941
            return pods_error( sprintf( __( "%s Object not found", 'pods' ), ucwords( $params->type ) ), $this );
4942
4943
        $success = wp_delete_post( $params->id );
4944
4945 View Code Duplication
        if ( !$success )
4946
            return pods_error( sprintf( __( "%s Object not deleted", 'pods' ), ucwords( $params->type ) ), $this );
4947
4948
        pods_transient_clear( 'pods_objects_' . $params->type );
4949
4950
        return true;
4951
    }
4952
4953
    /**
4954
     * @see PodsAPI::delete_object
4955
     *
4956
     * Drop a Pod Template
4957
     *
4958
     * $params['id'] int The template ID
4959
     * $params['name'] string The template name
4960
     *
4961
     * @param array $params An associative array of parameters
4962
     *
4963
     * @return bool
4964
     * @since 1.7.9
4965
     */
4966
    public function delete_template ( $params ) {
4967
        $params = (object) $params;
4968
        $params->type = 'template';
4969
        return $this->delete_object( $params );
4970
    }
4971
4972
    /**
4973
     * @see PodsAPI::delete_object
4974
     *
4975
     * Drop a Pod Page
4976
     *
4977
     * $params['id'] int The page ID
4978
     * $params['uri'] string The page URI
4979
     *
4980
     * @param array $params An associative array of parameters
4981
     *
4982
     * @return bool
4983
     * @since 1.7.9
4984
     */
4985
    public function delete_page ( $params ) {
4986
        $params = (object) $params;
4987
        if ( isset( $params->uri ) ) {
4988
            $params->name = $params->uri;
4989
            unset( $params->uri );
4990
        }
4991
        if ( isset( $params->name ) )
4992
            $params->name = trim( $params->name, '/' );
4993
        $params->type = 'page';
4994
        return $this->delete_object( $params );
4995
    }
4996
4997
    /**
4998
     * @see PodsAPI::delete_object
4999
     *
5000
     * Drop a Pod Helper
5001
     *
5002
     * $params['id'] int The helper ID
5003
     * $params['name'] string The helper name
5004
     *
5005
     * @param array $params An associative array of parameters
5006
     *
5007
     * @return bool
5008
     * @since 1.7.9
5009
     */
5010
    public function delete_helper ( $params ) {
5011
        $params = (object) $params;
5012
        $params->type = 'helper';
5013
        return $this->delete_object( $params );
5014
    }
5015
5016
    /**
5017
     * Drop a single pod item
5018
     *
5019
     * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter)
5020
     * $params['pod'] string (optional) The Pod name (used with id parameter)
5021
     * $params['pod_id'] int (optional) The Pod ID (used with id parameter)
5022
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
5023
     *
5024
     * @param array $params An associative array of parameters
5025
     * @param bool $wp Whether to run WP object delete action
5026
     *
5027
     * @return bool
5028
     * @since 1.7.9
5029
     */
5030
    public function delete_pod_item ( $params, $wp = true ) {
5031
        $params = (object) pods_sanitize( $params );
5032
5033
        // @deprecated 2.0
5034
        if ( isset( $params->datatype_id ) || isset( $params->datatype ) || isset( $params->tbl_row_id ) ) {
5035
            if ( isset( $params->tbl_row_id ) ) {
5036
                pods_deprecated( __( '$params->id instead of $params->tbl_row_id', 'pods' ), '2.0' );
5037
                $params->id = $params->tbl_row_id;
5038
                unset( $params->tbl_row_id );
5039
            }
5040
5041 View Code Duplication
            if ( isset( $params->pod_id ) ) {
5042
                pods_deprecated( __( '$params->id instead of $params->pod_id', 'pods' ), '2.0' );
5043
                $params->id = $params->pod_id;
5044
                unset( $params->pod_id );
5045
            }
5046
5047 View Code Duplication
            if ( isset( $params->dataype_id ) ) {
5048
                pods_deprecated( __( '$params->pod_id instead of $params->datatype_id', 'pods' ), '2.0' );
5049
                $params->pod_id = $params->dataype_id;
5050
                unset( $params->dataype_id );
5051
            }
5052
5053
            if ( isset( $params->datatype ) ) {
5054
                pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
5055
                $params->pod = $params->datatype;
5056
                unset( $params->datatype );
5057
            }
5058
        }
5059
5060
        if ( !isset( $params->id ) )
5061
            return pods_error( __( 'Pod Item not found', 'pods' ), $this );
5062
5063
        $params->id = pods_absint( $params->id );
5064
5065
        if ( !isset( $params->pod ) )
5066
            $params->pod = '';
5067
5068
        if ( !isset( $params->pod_id ) )
5069
            $params->pod_id = 0;
5070
5071
        $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ) );
5072
5073
        if ( false === $pod )
5074
            return pods_error( __( 'Pod not found', 'pods' ), $this );
5075
5076
        $params->pod_id = $pod[ 'id' ];
5077
        $params->pod = $pod[ 'name' ];
5078
5079
        // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls
5080
        $bypass_helpers = false;
5081
5082
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
5083
            $bypass_helpers = true;
5084
5085
        $pre_delete_helpers = $post_delete_helpers = array();
5086
5087
        if ( false === $bypass_helpers ) {
5088
            // Plugin hook
5089
            $this->do_hook( 'pre_delete_pod_item', $params, $pod );
5090
            $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod );
5091
5092
            // Call any pre-save helpers (if not bypassed)
5093 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
5094
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
5095
                    $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' );
5096
5097
                    foreach ( $helpers as $helper ) {
5098
                        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...
5099
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
5100
                    }
5101
                }
5102
5103
                if ( !empty( $pre_delete_helpers ) ) {
5104
                    pods_deprecated( sprintf( __( 'Pre-delete helpers are deprecated, use the action pods_pre_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5105
5106
                    foreach ( $pre_delete_helpers as $helper ) {
5107
                        $helper = $this->load_helper( array( 'name' => $helper ) );
5108
5109
                        if ( false !== $helper )
5110
                            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...
5111
                    }
5112
                }
5113
            }
5114
        }
5115
5116
        // Delete object from relationship fields
5117
        $this->delete_object_from_relationships( $params->id, $pod );
5118
5119
        if ( 'table' == $pod[ 'storage' ] )
5120
            pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" );
5121
5122
        if ( $wp ) {
5123
            if ( 'taxonomy' == $pod['type'] ) {
5124
                $taxonomy = $pod['name'];
5125
5126
                if ( ! empty( $pod['object'] ) ) {
5127
                    $taxonomy = $pod['object'];
5128
                }
5129
5130
                wp_delete_term( $params->id, $taxonomy );
5131
            } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) {
5132
                $this->delete_wp_object( $pod['type'], $params->id );
5133
            }
5134
        }
5135
5136
        if ( false === $bypass_helpers ) {
5137
            // Plugin hook
5138
            $this->do_hook( 'post_delete_pod_item', $params, $pod );
5139
            $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod );
5140
5141
            // Call any post-save helpers (if not bypassed)
5142 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
5143
                if ( !empty( $post_delete_helpers ) ) {
5144
                    pods_deprecated( sprintf( __( 'Post-delete helpers are deprecated, use the action pods_post_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5145
5146
                    foreach ( $post_delete_helpers as $helper ) {
5147
                        $helper = $this->load_helper( array( 'name' => $helper ) );
5148
5149
                        if ( false !== $helper )
5150
                            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...
5151
                    }
5152
                }
5153
            }
5154
        }
5155
5156
        pods_cache_clear( $params->id, 'pods_items_' . $params->pod );
5157
5158
        return true;
5159
    }
5160
5161
    /**
5162
     * Delete an object from tableless fields
5163
     *
5164
     * @param int $id
5165
     * @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...
5166
     * @param string $name
5167
     *
5168
     * @return bool
5169
     *
5170
     * @since 2.3
5171
     */
5172
    public function delete_object_from_relationships ( $id, $object, $name = null ) {
5173
        /**
5174
         * @var $pods_init \PodsInit
5175
         */
5176
        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...
5177
5178
        $pod = false;
5179
5180
        // Run any bidirectional delete operations
5181
        if ( is_array( $object ) )
5182
            $pod = $object;
5183
        elseif ( is_object( $pods_init ) )
5184
            $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...
5185
5186
        if ( !empty( $pod ) ) {
5187
            $object = $pod[ 'type' ];
5188
            $name = $pod[ 'name' ];
5189
5190
            foreach ( $pod[ 'fields' ] as $field ) {
5191
                PodsForm::delete( $field[ 'type' ], $id, $field[ 'name' ], array_merge( $field, $field[ 'options' ] ), $pod );
5192
            }
5193
        }
5194
5195
        // Lookup related fields (non-bidirectional)
5196
        $params = array(
5197
            'where' => array(
5198
                array(
5199
                    'key' => 'type',
5200
                    'value' => 'pick'
5201
                ),
5202
                array(
5203
                    'key' => 'pick_object',
5204
                    'value' => $object
5205
                )
5206
            )
5207
        );
5208
5209
        if ( !empty( $name ) && $name != $object ) {
5210
            $params[ 'where' ][] = array(
5211
                'key' => 'pick_val',
5212
                'value' => $name
5213
            );
5214
        }
5215
5216
        $fields = $this->load_fields( $params, false );
5217
5218
        if ( !empty( $pod ) && 'media' == $pod[ 'type' ] ) {
5219
            $params[ 'where' ] = array(
5220
                array(
5221
                    'key' => 'type',
5222
                    'value' => 'file'
5223
                )
5224
            );
5225
5226
            $fields = array_merge( $fields, $this->load_fields( $params, false ) );
5227
        }
5228
5229
        if ( is_array( $fields ) && !empty( $fields ) ) {
5230
            foreach ( $fields as $related_field ) {
5231
                $related_pod = $this->load_pod( array( 'id' => $related_field[ 'pod_id' ], 'fields' => false ), false );
5232
5233
                if ( empty( $related_pod ) )
5234
                    continue;
5235
5236
                $related_from = $this->lookup_related_items_from( $related_field[ 'id' ], $related_pod[ 'id' ], $id, $related_field, $related_pod );
5237
5238
                $this->delete_relationships( $related_from, $id, $related_pod, $related_field );
5239
            }
5240
        }
5241
5242
        if ( !empty( $pod ) && !pods_tableless() ) {
5243
            pods_query( "
5244
                DELETE FROM `@wp_podsrel`
5245
                WHERE
5246
                (
5247
                    `pod_id` = %d
5248
                    AND `item_id` = %d
5249
                )
5250
                OR (
5251
                    `related_pod_id` = %d
5252
                    AND `related_item_id` = %d
5253
                )
5254
            ", array(
5255
                $pod[ 'id' ],
5256
                $id,
5257
5258
                $pod[ 'id' ],
5259
                $id
5260
            ) );
5261
        }
5262
5263
        return true;
5264
    }
5265
5266
    /**
5267
     * Delete relationships
5268
     *
5269
     * @param int|array $related_id IDs for items to save
5270
     * @param int|array $id ID or IDs to remove
5271
     * @param array $related_pod Pod data
5272
     * @param array $related_field Field data
5273
     *
5274
     * @return void
5275
     *
5276
     * @since 2.3
5277
     */
5278
    public function delete_relationships ( $related_id, $id, $related_pod, $related_field ) {
5279
        if ( is_array( $related_id ) ) {
5280
            foreach ( $related_id as $rid ) {
5281
                $this->delete_relationships( $rid, $id, $related_pod, $related_field );
5282
            }
5283
5284
            return;
5285
        }
5286
5287
        if ( is_array( $id ) ) {
5288
            foreach ( $id as $rid ) {
5289
                $this->delete_relationships( $related_id, $rid, $related_pod, $related_field );
5290
            }
5291
5292
            return;
5293
        }
5294
5295
        $id = (int) $id;
5296
5297
        if ( empty( $id ) )
5298
            return;
5299
5300
        $related_ids = $this->lookup_related_items( $related_field[ 'id' ], $related_pod[ 'id' ], $related_id, $related_field, $related_pod );
5301
5302
        if ( empty( $related_ids ) )
5303
            return;
5304
        elseif ( !in_array( $id, $related_ids ) )
5305
            return;
5306
5307
	    if ( isset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] ) ) {
5308
		    // Delete relationship from cache
5309
		    unset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] );
5310
	    }
5311
        unset( $related_ids[ array_search( $id, $related_ids ) ] );
5312
5313
        $no_conflict = pods_no_conflict_check( $related_pod[ 'type' ] );
5314
5315
        if ( !$no_conflict )
5316
            pods_no_conflict_on( $related_pod[ 'type' ] );
5317
5318
        // Post Types, Media, Users, and Comments (meta-based)
5319 View Code Duplication
        if ( in_array( $related_pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
5320
            $object_type = $related_pod[ 'type' ];
5321
5322
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
5323
                $object_type = 'post';
5324
            elseif ( 'taxonomy' == $object_type )
5325
                $object_type = 'term';
5326
5327
            delete_metadata( $object_type, $related_id, $related_field[ 'name' ] );
5328
5329
            if ( !empty( $related_ids ) ) {
5330
                update_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ], $related_ids );
5331
5332
                foreach ( $related_ids as $rel_id ) {
5333
                    add_metadata( $object_type, $related_id, $related_field[ 'name' ], $rel_id );
5334
                }
5335
            }
5336
            else
5337
                delete_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ] );
5338
        }
5339
        // Custom Settings Pages (options-based)
5340
        elseif ( 'settings' == $related_pod[ 'type' ] ) {
5341
            if ( !empty( $related_ids ) )
5342
                update_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ], $related_ids );
5343
            else
5344
                delete_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ] );
5345
        }
5346
5347
        // Relationships table
5348
        if ( !pods_tableless() ) {
5349
            pods_query( "
5350
                DELETE FROM `@wp_podsrel`
5351
                WHERE
5352
                (
5353
                    `pod_id` = %d
5354
                    AND `field_id` = %d
5355
                    AND `item_id` = %d
5356
                    AND `related_item_id` = %d
5357
                )
5358
                OR (
5359
                    `related_pod_id` = %d
5360
                    AND `related_field_id` = %d
5361
                    AND `related_item_id` = %d
5362
                    AND `item_id` = %d
5363
                )
5364
            ", array(
5365
                $related_pod[ 'id' ],
5366
                $related_field[ 'id' ],
5367
                $related_id,
5368
                $id,
5369
5370
                $related_pod[ 'id' ],
5371
                $related_field[ 'id' ],
5372
                $related_id,
5373
                $id
5374
            ) );
5375
        }
5376
5377
        if ( !$no_conflict )
5378
            pods_no_conflict_off( $related_pod[ 'type' ] );
5379
    }
5380
5381
    /**
5382
     * Check if a Pod exists
5383
     *
5384
     * $params['id'] int Pod ID
5385
     * $params['name'] string Pod name
5386
     *
5387
     * @param array $params An associative array of parameters
5388
     *
5389
     * @return bool True if exists
5390
     *
5391
     * @since 1.12
5392
     */
5393
    public function pod_exists ( $params, $type = null ) {
5394
        if ( is_string( $params ) )
5395
            $params = array( 'name' => $params );
5396
5397
        $params = (object) pods_sanitize( $params );
5398
5399
        if ( !empty( $params->id ) || !empty( $params->name ) ) {
5400
            if ( !isset( $params->name ) )
5401
                $pod = get_post( $dummy = (int) $params->id );
5402
            else {
5403
                $pod = get_posts( array(
5404
                    'name' => $params->name,
5405
                    'post_type' => '_pods_pod',
5406
                    'posts_per_page' => 1
5407
                ) );
5408
5409
                if ( is_array( $pod ) ) {
5410
                    $pod = $pod[0];
5411
                }
5412
            }
5413
5414
            if ( !empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) )
5415
                return true;
5416
        }
5417
5418
        return false;
5419
    }
5420
5421
	/**
5422
	 * Get number of pods for a specific pod type
5423
	 *
5424
	 * @param string $type Type to get count
5425
	 *
5426
	 * @return int Total number of pods for a type
5427
	 *
5428
	 * @since 2.6.6
5429
	 */
5430
	public function get_pod_type_count( $type ) {
5431
5432
		$args = array(
5433
			'post_type'      => '_pods_pod',
5434
			'posts_per_page' => - 1,
5435
			'nopaging'       => true,
5436
			'fields'         => 'ids',
5437
			'meta_query'     => array(
5438
				array(
5439
					'key'   => 'type',
5440
					'value' => $type,
5441
				),
5442
			),
5443
		);
5444
5445
		$posts = get_posts( $args );
5446
5447
		$total = count( $posts );
5448
5449
		return $total;
5450
5451
	}
5452
5453
    /**
5454
     * Load a Pod and all of its fields
5455
     *
5456
     * $params['id'] int The Pod ID
5457
     * $params['name'] string The Pod name
5458
     * $params['fields'] bool Whether to load fields (default is true)
5459
     * $params['bypass_cache'] boolean Bypass the cache when getting data
5460
     *
5461
     * @param array|object $params An associative array of parameters or pod name as a string
5462
     * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work
5463
     *
5464
     * @return array|bool|mixed|void
5465
     * @since 1.7.9
5466
     */
5467
    public function load_pod ( $params, $strict = true ) {
5468
5469
        /**
5470
         * @var $sitepress SitePress
5471
		 * @var $wpdb wpdb
5472
         */
5473
        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...
5474
5475
        $current_language = false;
5476
        $load_fields = true;
5477
	    $bypass_cache = false;
5478
5479
	    // Get current language data
5480
5481
		$lang_data = PodsInit::$i18n->get_current_language_data();
0 ignored issues
show
Bug introduced by
The property i18n 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...
5482
5483
	    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...
5484
		    if ( ! empty( $lang_data['language'] ) ) {
5485
			    $current_language = $lang_data['language'];
5486
		    }
5487
	    }
5488
5489
        if ( !is_array( $params ) && !is_object( $params ) )
5490
            $params = array( 'name' => $params, 'table_info' => false, 'fields' => true );
5491
5492
        if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && isset( $params->fields ) && !$params->fields )
5493
            $load_fields = false;
5494
        elseif ( is_array( $params ) && isset( $params[ 'fields' ] ) && !$params[ 'fields' ] )
5495
            $load_fields = false;
5496
5497
	    $table_info = false;
5498
5499
        if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->table_info ) )
5500
            $table_info = true;
5501
        elseif ( is_array( $params ) && ! empty( $params[ 'table_info' ] ) )
5502
            $table_info = true;
5503
5504
        $transient = 'pods_' . $wpdb->prefix . '_pod';
5505
5506
        if ( !empty( $current_language ) )
5507
            $transient .= '_' . $current_language;
5508
5509
        if ( !$load_fields )
5510
            $transient .= '_nofields';
5511
5512
        if ( $table_info )
5513
            $transient .= '_tableinfo';
5514
5515
	    $check_pod = $params;
5516
5517
	    if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->pod ) ) {
5518
		    $check_pod = $params->pod;
5519
	    } elseif ( is_array( $params ) && ! empty( $params['pod'] ) ) {
5520
		    $check_pod = $params['pod'];
5521
	    }
5522
5523
        if ( is_object( $check_pod ) && ( is_a( $check_pod, 'WP_Post' ) || isset( $check_pod->post_name ) ) ) {
5524
            $pod = false;
5525
5526
            if ( pods_api_cache() )
5527
                $pod = pods_transient_get( $transient . '_' . $check_pod->post_name );
5528
5529 View Code Duplication
            if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5530
	            // @todo Is this needed anymore for WPML?
5531
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) )
5532
                     && did_action( 'wpml_loaded' )
5533
                     && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
5534
                    $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
5535
                }
5536
5537
                return $pod;
5538
            }
5539
5540
            $_pod = get_object_vars( $check_pod );
5541
        }
5542
        else {
5543
            $params = (object) pods_sanitize( $params );
5544
5545 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) ) {
5546
                if ( $strict ) {
5547
	                  return pods_error( 'Either Pod ID or Name are required', $this );
5548
                }
5549
5550
                return false;
5551
            }
5552
5553
		    if ( ! empty( $params->bypass_cache ) ) {
5554
		        $bypass_cache = true;
5555
		    }
5556
5557
            if ( isset( $params->name ) ) {
5558
                $pod = false;
5559
5560
				if ( '_pods_pod' == $params->name ) {
5561
					$pod = array(
5562
						'id' => 0,
5563
						'name' => $params->name,
5564
						'label' => __( 'Pods', 'pods' ),
5565
						'type' => 'post_type',
5566
						'storage' => 'meta',
5567
						'options' => array(
5568
							'label_singular' => __( 'Pod', 'pods' )
5569
						),
5570
						'fields' => array()
5571
					);
5572
				}
5573
				elseif ( '_pods_field' == $params->name ) {
5574
					$pod = array(
5575
						'id' => 0,
5576
						'name' => $params->name,
5577
						'label' => __( 'Pod Fields', 'pods' ),
5578
						'type' => 'post_type',
5579
						'storage' => 'meta',
5580
						'options' => array(
5581
							'label_singular' => __( 'Pod Field', 'pods' )
5582
						),
5583
						'fields' => array()
5584
					);
5585
				}
5586 View Code Duplication
                elseif ( ! $bypass_cache & pods_api_cache() )
5587
                    $pod = pods_transient_get( $transient . '_' . $params->name );
5588
5589 View Code Duplication
                if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5590
                    if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && did_action( 'wpml_loaded' )
5591
                        && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) )
5592
                        $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5593
5594
                    return $pod;
5595
                }
5596
            }
5597
5598 View Code Duplication
            if ( !isset( $params->name ) )
5599
                $pod = get_post( $dummy = (int) $params->id );
5600
            else {
5601
                $pod = get_posts( array(
5602
                    'name' => $params->name,
5603
                    'post_type' => '_pods_pod',
5604
                    'posts_per_page' => 1
5605
                ) );
5606
            }
5607
5608
            if ( empty( $pod ) ) {
5609
                if ( $strict )
5610
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
5611
5612
                return false;
5613
            }
5614
5615
            if ( is_array( $pod ) )
5616
                $pod = $pod[ 0 ];
5617
5618
            $_pod = get_object_vars( $pod );
5619
        }
5620
5621
        $pod = false;
5622
5623 View Code Duplication
        if ( ! $bypass_cache || pods_api_cache() )
5624
            $pod = pods_transient_get( $transient . '_' . $_pod[ 'post_name' ] );
5625
5626 View Code Duplication
        if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5627
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) )
5628
                 && did_action( 'wpml_loaded' )
5629
                && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
5630
	            $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
5631
            }
5632
5633
            return $pod;
5634
        }
5635
5636
        $pod = array(
5637
            'id' => $_pod[ 'ID' ],
5638
            'name' => $_pod[ 'post_name' ],
5639
            'label' => $_pod[ 'post_title' ],
5640
            'description' => $_pod[ 'post_content' ]
5641
        );
5642
5643
        if ( strlen( $pod[ 'label' ] ) < 1 )
5644
            $pod[ 'label' ] = $pod[ 'name' ];
5645
5646
        // @todo update with a method to put all options in
5647
        $defaults = array(
5648
            'show_in_menu' => 1,
5649
            'type' => 'post_type',
5650
            'storage' => 'meta',
5651
            'object' => '',
5652
            'alias' => ''
5653
        );
5654
5655
        if ( $bypass_cache ) {
5656
            wp_cache_delete( $pod['id'], 'post_meta' );
5657
5658
            update_postmeta_cache( array( $pod['id'] ) );
5659
        }
5660
5661
        $pod[ 'options' ] = get_post_meta( $pod[ 'id' ] );
5662
5663 View Code Duplication
        foreach ( $pod[ 'options' ] as $option => $value ) {
5664
            if ( is_array( $value ) ) {
5665
                foreach ( $value as $k => $v ) {
5666
                    if ( !is_array( $v ) )
5667
                        $value[ $k ] = maybe_unserialize( $v );
5668
                }
5669
5670
                if ( 1 == count( $value ) )
5671
                    $value = current( $value );
5672
            }
5673
            else
5674
                $value = maybe_unserialize( $value );
5675
5676
            $pod[ 'options' ][ $option ] = $value;
5677
        }
5678
5679
        $pod[ 'options' ] = array_merge( $defaults, $pod[ 'options' ] );
5680
5681
        $pod[ 'type' ] = $pod[ 'options' ][ 'type' ];
5682
        $pod[ 'storage' ] = $pod[ 'options' ][ 'storage' ];
5683
        $pod[ 'object' ] = $pod[ 'options' ][ 'object' ];
5684
        $pod[ 'alias' ] = $pod[ 'options' ][ 'alias' ];
5685
5686
        unset( $pod[ 'options' ][ 'type' ] );
5687
        unset( $pod[ 'options' ][ 'storage' ] );
5688
        unset( $pod[ 'options' ][ 'object' ] );
5689
        unset( $pod[ 'options' ][ 'alias' ] );
5690
5691
        if ( $table_info )
5692
            $pod = array_merge( $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ), $pod );
5693
5694
        // Override old 'none' storage type
5695 View Code Duplication
        if ( 'taxonomy' == $pod['type'] && 'none' == $pod['storage'] && function_exists( 'get_term_meta' ) ) {
5696
            $pod[ 'storage' ] = 'meta';
5697
        }
5698
5699
        if ( isset( $pod[ 'pod' ] ) )
5700
            unset( $pod[ 'pod' ] );
5701
5702
        $pod[ 'fields' ] = array();
5703
5704
        $pod[ 'object_fields' ] = array();
5705
5706
        if ( 'pod' != $pod[ 'type' ] )
5707
            $pod[ 'object_fields' ] = $this->get_wp_object_fields( $pod[ 'type' ], $pod );
5708
5709
        $fields = get_posts( array(
5710
            'post_type' => '_pods_field',
5711
            'posts_per_page' => -1,
5712
            'nopaging' => true,
5713
            'post_parent' => $pod[ 'id' ],
5714
            'orderby' => 'menu_order',
5715
            'order' => 'ASC'
5716
        ) );
5717
5718
        if ( !empty( $fields ) ) {
5719
            foreach ( $fields as $field ) {
5720
                $field->pod = $pod[ 'name' ];
5721
                $field->table_info = $table_info;
5722
                $field->bypass_cache = $bypass_cache;
5723
5724
                if ( $load_fields ) {
5725
                    $field = $this->load_field( $field );
5726
5727
                    $field = PodsForm::field_setup( $field, null, $field[ 'type' ] );
5728
                }
5729
                else {
5730
			        if ( $bypass_cache ) {
5731
                        wp_cache_delete( $field->ID, 'post_meta' );
5732
5733
			            update_postmeta_cache( array( $field->ID ) );
5734
			        }
5735
5736
                    $field = array(
5737
                        'id' => $field->ID,
5738
                        'name' => $field->post_name,
5739
                        'label' => $field->post_title,
5740
                        'type' => get_post_meta( $field->ID, 'type', true )
5741
                    );
5742
                }
5743
5744
                $pod[ 'fields' ][ $field[ 'name' ] ] = $field;
5745
            }
5746
        }
5747
5748 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
5749
            pods_transient_set( $transient . '_' . $pod[ 'name' ], $pod );
5750
5751
        return $pod;
5752
    }
5753
5754
    /**
5755
     * Load a list of Pods based on filters specified.
5756
     *
5757
     * $params['type'] string/array Pod Type(s) to filter by
5758
     * $params['object'] string/array Pod Object(s) to filter by
5759
     * $params['options'] array Pod Option(s) key=>value array to filter by
5760
     * $params['orderby'] string ORDER BY clause of query
5761
     * $params['limit'] string Number of Pods to return
5762
     * $params['where'] string WHERE clause of query
5763
     * $params['ids'] string|array IDs of Objects
5764
     * $params['count'] boolean Return only a count of Pods
5765
     * $params['names'] boolean Return only an array of name => label
5766
     * $params['ids'] boolean Return only an array of ID => label
5767
     * $params['fields'] boolean Return pod fields with Pods (default is true)
5768
     * $params['key_names'] boolean Return pods keyed by name
5769
     * $params['bypass_cache'] boolean Bypass the cache when getting data
5770
     *
5771
     * @param array $params An associative array of parameters
5772
     *
5773
     * @return array|mixed
5774
     *
5775
     * @uses PodsAPI::load_pod
5776
     *
5777
     * @since 2.0
5778
     */
5779
    public function load_pods ( $params = null ) {
5780
5781
        $current_language = false;
5782
5783
	    // Get current language data
5784
		$lang_data = PodsInit::$i18n->get_current_language_data();
0 ignored issues
show
Bug introduced by
The property i18n 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...
5785
5786
	    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...
5787
		    if ( ! empty( $lang_data['language'] ) ) {
5788
			    $current_language = $lang_data['language'];
5789
		    }
5790
	    }
5791
5792
        $params = (object) pods_sanitize( $params );
5793
5794
        $order = 'ASC';
5795
        $orderby = 'menu_order title';
5796
        $limit = -1;
5797
        $ids = false;
5798
5799
        $meta_query = array();
5800
        $cache_key = '';
5801
5802
        $bypass_cache = false;
5803
5804
	    if ( ! empty( $params->bypass_cache ) ) {
5805
	    	$bypass_cache = true;
5806
	    }
5807
5808
        if ( isset( $params->type ) && !empty( $params->type ) ) {
5809
            if ( !is_array( $params->type ) )
5810
                $params->type = array( trim( $params->type ) );
5811
5812
            sort( $params->type );
5813
5814
            $meta_query[] = array(
5815
                'key' => 'type',
5816
                'value' => $params->type,
5817
                'compare' => 'IN'
5818
            );
5819
5820
            if ( 0 < count( $params->type ) )
5821
                $cache_key .= '_type_' . trim( implode( '_', $params->type ) );
5822
        }
5823
5824
        if ( isset( $params->object ) && !empty( $params->object ) ) {
5825
            if ( !is_array( $params->object ) )
5826
                $params->object = array( $params->object );
5827
5828
            $params->object = pods_trim( $params->object );
5829
5830
            sort( $params->object );
5831
5832
            $meta_query[] = array(
5833
                'key' => 'object',
5834
                'value' => $params->object,
5835
                'compare' => 'IN'
5836
            );
5837
5838
            if ( 1 == count( $params->object ) )
5839
                $cache_key .= '_object_' . trim( implode( '', $params->object ) );
5840
        }
5841
5842 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
5843
            foreach ( $params->options as $option => $value ) {
5844
                if ( !is_array( $value ) )
5845
                    $value = array( $value );
5846
5847
                $value = pods_trim( $value );
5848
5849
                sort( $value );
5850
5851
                $meta_query[] = array(
5852
                    'key' => $option,
5853
                    'value' => pods_sanitize( $value ),
5854
                    'compare' => 'IN'
5855
                );
5856
            }
5857
5858
            $cache_key = '';
5859
        }
5860
5861
        if ( isset( $params->where ) && is_array( $params->where ) )
5862
            $meta_query = array_merge( $meta_query, (array) $params->where );
5863
5864 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
5865
            $order = strtoupper( $params->order );
5866
5867
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
5868
            $orderby = strtoupper( $params->orderby );
5869
5870
        if ( isset( $params->limit ) && !empty( $params->limit ) )
5871
            $limit = pods_absint( $params->limit );
5872
5873
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
5874
            $ids = $params->ids;
5875
5876
            if ( !is_array( $ids ) )
5877
                $ids = explode( ',', $ids );
5878
        }
5879
5880
        if ( empty( $ids ) )
5881
            $ids = false;
5882
5883
        $pre_key = '';
5884
5885
        if ( !empty( $current_language ) )
5886
            $pre_key .= '_' . $current_language;
5887
5888
        if ( isset( $params->count ) && $params->count )
5889
            $pre_key .= '_count';
5890
5891
        if ( isset( $params->ids ) && $params->ids && !empty( $ids ) )
5892
            $pre_key .= '_ids_' . implode( '_', $ids );
5893
5894
        if ( isset( $params->names ) && $params->names )
5895
            $pre_key .= '_names';
5896
        elseif ( isset( $params->names_ids ) && $params->names_ids )
5897
            $pre_key .= '_names_ids';
5898
5899
        if ( isset( $params->key_names ) && $params->key_names )
5900
            $pre_key .= '_namekeys';
5901
5902
        if ( isset( $params->fields ) && !$params->fields )
5903
            $pre_key .= '_nofields';
5904
5905
        if ( isset( $params->table_info ) && $params->table_info )
5906
            $pre_key .= '_tableinfo';
5907
5908
5909
        $pre_key .= '_get';
5910
5911
        if ( empty( $cache_key ) )
5912
            $cache_key = 'pods' . $pre_key . '_all';
5913
        else
5914
            $cache_key = 'pods' . $pre_key . $cache_key;
5915
5916
        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 ) ) {
5917
            $the_pods = pods_transient_get( $cache_key );
5918
5919
            if ( false === $the_pods )
5920
                $the_pods = pods_cache_get( $cache_key, 'pods' );
5921
5922
            if ( !is_array( $the_pods ) && 'none' == $the_pods )
5923
                return array();
5924
            elseif ( false !== $the_pods )
5925
                return $the_pods;
5926
        }
5927
5928
        $the_pods = array();
5929
5930
		$args = array(
5931
			'post_type' => '_pods_pod',
5932
			'nopaging' => true,
5933
			'posts_per_page' => $limit,
5934
			'order' => $order,
5935
			'orderby' => $orderby,
5936
			'meta_query' => $meta_query,
5937
		);
5938
5939
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
5940
		if ( false != $ids ) {
5941
			$args[ 'post__in' ] = $ids;
5942
		}
5943
5944
		$_pods = get_posts( $args );
5945
5946
        $export_ignore = array(
5947
            'object_type',
5948
            'object_name',
5949
            'table',
5950
            'meta_table',
5951
            'pod_table',
5952
            'field_id',
5953
            'field_index',
5954
            'field_slug',
5955
            'field_type',
5956
            'field_parent',
5957
            'field_parent_select',
5958
            'meta_field_id',
5959
            'meta_field_index',
5960
            'meta_field_value',
5961
            'pod_field_id',
5962
            'pod_field_index',
5963
            'object_fields',
5964
            'join',
5965
            'where',
5966
            'where_default',
5967
            'orderby',
5968
            'pod',
5969
            'recurse',
5970
            'table_info',
5971
            'attributes',
5972
            'group',
5973
            'grouped',
5974
            'developer_mode',
5975
            'dependency',
5976
            'depends-on',
5977
            'excludes-on'
5978
        );
5979
5980
        $total_fields = 0;
5981
5982
        if ( isset( $params->count ) && $params->count )
5983
            $the_pods = count( $_pods );
5984
        else {
5985
            foreach ( $_pods as $pod ) {
5986
                if ( isset( $params->names ) && $params->names )
5987
                    $the_pods[ $pod->post_name ] = $pod->post_title;
5988
                elseif ( isset( $params->names_ids ) && $params->names_ids )
5989
                    $the_pods[ $pod->ID ] = $pod->post_name;
5990
                else {
5991
                    if ( isset( $params->fields ) && !$params->fields )
5992
                        $pod->fields = false;
5993
5994
                    $pod = $this->load_pod( array( 'pod' => $pod, 'table_info' => ! empty( $params->table_info ), 'bypass_cache' => $bypass_cache ) );
5995
5996
                    // Remove extra data not needed
5997
                    if ( pods_var( 'export', $params, false ) && ( !isset( $params->fields ) || $params->fields ) ) {
5998
                        foreach ( $export_ignore as $ignore ) {
5999
                            if ( isset( $pod[ $ignore ] ) )
6000
                                unset( $pod[ $ignore ] );
6001
                        }
6002
6003
                        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
6004
                            if ( isset( $pod[ 'fields' ][ $field ][ 'table_info' ] ) )
6005
                                unset( $pod[ 'fields' ][ $field ][ 'table_info' ] );
6006
                        }
6007
                    }
6008
6009
                    $total_fields += count( $pod[ 'fields' ] );
6010
6011
                    if ( isset( $params->key_names ) && $params->key_names )
6012
                        $the_pods[ $pod[ 'name' ] ] = $pod;
6013
                    else
6014
                        $the_pods[ $pod[ 'id' ] ] = $pod;
6015
                }
6016
            }
6017
        }
6018
6019
        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 ) ) {
6020
            // Too many Pods can cause issues with the DB when caching is not enabled
6021
            if ( 15 < count( $the_pods ) || 75 < count( $total_fields ) ) {
6022
                pods_transient_clear( $cache_key );
6023
6024 View Code Duplication
                if ( pods_api_cache() ) {
6025
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
6026
                        pods_cache_set( $cache_key, 'none', 'pods' );
6027
                    else
6028
                        pods_cache_set( $cache_key, $the_pods, 'pods' );
6029
                }
6030
            }
6031
            else {
6032
                pods_cache_clear( $cache_key, 'pods' );
6033
6034 View Code Duplication
                if ( pods_api_cache() ) {
6035
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
6036
                        pods_transient_set( $cache_key, 'none' );
6037
                    else
6038
                        pods_transient_set( $cache_key, $the_pods );
6039
                }
6040
            }
6041
        }
6042
6043
        return $the_pods;
6044
    }
6045
6046
    /**
6047
     * Check if a Pod's field exists
6048
     *
6049
     * $params['pod_id'] int The Pod ID
6050
     * $params['id'] int The field ID
6051
     * $params['name'] string The field name
6052
     *
6053
     * @param array $params An associative array of parameters
6054
     *
6055
     * @return bool
6056
     *
6057
     * @since 1.12
6058
     */
6059
    public function field_exists ( $params ) {
6060
        $params = (object) pods_sanitize( $params );
6061
6062
        if ( ( !empty( $params->id ) || !empty( $params->name ) ) && isset( $params->pod_id ) && !empty( $params->pod_id ) ) {
6063 View Code Duplication
            if ( !isset( $params->name ) )
6064
                $field = get_post( $dummy = (int) $params->id );
6065
            else {
6066
                $field = get_posts( array(
6067
                    'name' => $params->name,
6068
                    'post_type' => '_pods_field',
6069
                    'posts_per_page' => 1,
6070
                    'post_parent' => $params->pod_id
6071
                ) );
6072
            }
6073
6074
            if ( !empty( $field ) )
6075
                return true;
6076
        }
6077
6078
        return false;
6079
    }
6080
6081
    /**
6082
     * Load a field
6083
     *
6084
     * $params['pod_id'] int The Pod ID
6085
     * $params['pod'] string The Pod name
6086
     * $params['id'] int The field ID
6087
     * $params['name'] string The field name
6088
     * $params['table_info'] boolean Whether to lookup a pick field's table info
6089
     * $params['bypass_cache'] boolean Bypass the cache when getting data
6090
     *
6091
     * @param array $params An associative array of parameters
6092
     * @param boolean $strict Whether to require a field exist or not when loading the info
6093
     *
6094
     * @return array|bool Array with field data, false if field not found
6095
     * @since 1.7.9
6096
     */
6097
    public function load_field ( $params, $strict = false ) {
6098
        $params = (object) $params;
6099
6100
        if ( !isset( $params->table_info ) )
6101
            $params->table_info = false;
6102
6103
        $bypass_cache = false;
6104
6105
        if ( ! empty( $params->bypass_cache ) )
6106
            $bypass_cache = true;
6107
6108
        $pod = array();
6109
        $field = array();
6110
6111
        if ( isset( $params->post_title ) )
6112
            $_field = $params;
6113
        elseif ( isset( $params->id ) && !empty( $params->id ) )
6114
            $_field = get_post( $dumb = (int) $params->id );
6115
        else {
6116
            if ( !isset( $params->pod ) )
6117
                $params->pod = '';
6118
6119
            if ( !isset( $params->pod_id ) )
6120
                $params->pod_id = 0;
6121
6122
            if ( isset( $params->pod_data ) )
6123
                $pod = $params->pod_data;
6124
            else {
6125
                $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false, 'bypass_cache' => $bypass_cache ), false );
6126
6127
                if ( false === $pod ) {
6128
                    if ( $strict )
6129
                        return pods_error( __( 'Pod not found', 'pods' ), $this );
6130
6131
                    return false;
6132
                }
6133
            }
6134
6135
            $params->pod_id = $pod[ 'id' ];
6136
            $params->pod = $pod[ 'name' ];
6137
6138 View Code Duplication
            if ( empty( $params->name ) && empty( $params->pod ) && empty( $params->pod_id ) )
6139
                return pods_error( __( 'Either Field Name or Field ID / Pod ID are required', 'pods' ), $this );
6140
6141
            $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
6142
6143
            if ( isset( $pod[ 'fields' ][ $params->name ] ) && isset( $pod[ 'fields' ][ $params->name ][ 'id' ] ) )
6144
                return $pod[ 'fields' ][ $params->name ];
6145
6146
            $field = false;
6147
6148
            if ( ! $bypass_cache && pods_api_cache() )
6149
                $field = pods_transient_get( 'pods_field_' . $params->pod . '_' . $params->name );
6150
6151
            if ( empty( $field ) ) {
6152
                $field = get_posts( array(
6153
                    'name' => $params->name,
6154
                    'post_type' => '_pods_field',
6155
                    'posts_per_page' => 1,
6156
                    'post_parent' => $params->pod_id
6157
                ) );
6158
6159
                if ( empty( $field ) ) {
6160
                    if ( $strict )
6161
                        return pods_error( __( 'Field not found', 'pods' ), $this );
6162
6163
                    return false;
6164
                }
6165
6166
                $_field = $field[ 0 ];
6167
6168
                $field = array();
6169
            }
6170
        }
6171
6172
        if ( empty( $_field ) ) {
6173
            if ( $strict )
6174
                return pods_error( __( 'Field not found', 'pods' ), $this );
6175
6176
            return false;
6177
        }
6178
6179
        $_field = get_object_vars( $_field );
6180
6181
        if ( !isset( $pod[ 'name' ] ) && !isset( $_field[ 'pod' ] ) ) {
6182
            if ( 0 < $_field[ 'post_parent' ] )
6183
                $pod = $this->load_pod( array( 'id' => $_field[ 'post_parent' ], 'table_info' => false ), false );
6184
6185
            if ( empty( $pod ) ) {
6186
                if ( $strict )
6187
                    return pods_error( __( 'Pod for field not found', 'pods' ), $this );
6188
6189
                return false;
6190
            }
6191
        }
6192
6193
        if ( empty( $field ) ) {
6194 View Code Duplication
            if ( ! $bypass_cache && pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6195
                $field = pods_transient_get( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $_field[ 'post_name' ] );
6196
6197
            if ( empty( $field ) ) {
6198
                $defaults = array(
6199
                    'type' => 'text'
6200
                );
6201
6202
                $field = array(
6203
                    'id' => $_field[ 'ID' ],
6204
                    'name' => $_field[ 'post_name' ],
6205
                    'label' => $_field[ 'post_title' ],
6206
                    'description' => $_field[ 'post_content' ],
6207
                    'weight' => $_field[ 'menu_order' ],
6208
                    'pod_id' => $_field[ 'post_parent' ],
6209
                    'pick_object' => '',
6210
                    'pick_val' => '',
6211
                    'sister_id' => '',
6212
                    'table_info' => array()
6213
                );
6214
6215
                if ( isset( $pod[ 'name' ] ) )
6216
                    $field[ 'pod' ] = $pod[ 'name' ];
6217
                elseif ( isset( $_field[ 'pod' ] ) )
6218
                    $field[ 'pod' ] = $_field[ 'pod' ];
6219
6220
	            if ( $bypass_cache ) {
6221
	                wp_cache_delete( $field['id'], 'post_meta' );
6222
6223
	                update_postmeta_cache( array( $field['id'] ) );
6224
	            }
6225
6226
                $field[ 'options' ] = get_post_meta( $field[ 'id' ] );
6227
6228
                $options_ignore = array(
6229
                    'method',
6230
                    'table_info',
6231
                    'attributes',
6232
                    'group',
6233
                    'grouped',
6234
                    'developer_mode',
6235
                    'dependency',
6236
                    'depends-on',
6237
                    'excludes-on'
6238
                );
6239
6240
                foreach ( $options_ignore as $ignore ) {
6241
                    if ( isset( $field[ 'options' ][ $ignore ] ) )
6242
                        unset( $field[ 'options' ][ $ignore ] );
6243
                }
6244
6245 View Code Duplication
                foreach ( $field[ 'options' ] as $option => $value ) {
6246
                    if ( is_array( $value ) ) {
6247
                        foreach ( $value as $k => $v ) {
6248
                            if ( !is_array( $v ) )
6249
                                $value[ $k ] = maybe_unserialize( $v );
6250
                        }
6251
6252
                        if ( 1 == count( $value ) )
6253
                            $value = current( $value );
6254
                    }
6255
                    else
6256
                        $value = maybe_unserialize( $value );
6257
6258
                    $field[ 'options' ][ $option ] = $value;
6259
                }
6260
6261
                $field[ 'options' ] = array_merge( $defaults, $field[ 'options' ] );
6262
6263
                $field[ 'type' ] = $field[ 'options' ][ 'type' ];
6264
6265
                unset( $field[ 'options' ][ 'type' ] );
6266
6267 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_object' ] ) ) {
6268
                    $field[ 'pick_object' ] = $field[ 'options' ][ 'pick_object' ];
6269
6270
                    unset( $field[ 'options' ][ 'pick_object' ] );
6271
                }
6272
6273 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_val' ] ) ) {
6274
                    $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_val' ];
6275
6276
                    unset( $field[ 'options' ][ 'pick_val' ] );
6277
                }
6278
6279 View Code Duplication
                if ( isset( $field[ 'options' ][ 'sister_id' ] ) ) {
6280
                    $field[ 'sister_id' ] = $field[ 'options' ][ 'sister_id' ];
6281
6282
                    unset( $field[ 'options' ][ 'sister_id' ] );
6283
                }
6284
6285
                if ( isset( $field[ 'options' ][ 'sister_field_id' ] ) )
6286
                    unset( $field[ 'options' ][ 'sister_field_id' ] );
6287
6288 View Code Duplication
                if ( pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6289
                    pods_transient_set( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $field[ 'name' ], $field );
6290
            }
6291
        }
6292
6293
        $field[ 'table_info' ] = array();
6294
6295
        if ( 'pick' == $field[ 'type' ] && $params->table_info )
6296
            $field[ 'table_info' ] = $this->get_table_info( $field[ 'pick_object' ], $field[ 'pick_val' ], null, null, $field );
6297
6298
        return $field;
6299
    }
6300
6301
    /**
6302
     * Load fields by Pod, ID, Name, and/or Type
6303
     *
6304
     * $params['pod_id'] int The Pod ID
6305
     * $params['pod'] string The Pod name
6306
     * $params['id'] array The field IDs
6307
     * $params['name'] array The field names
6308
     * $params['type'] array The field types
6309
     * $params['options'] array Field Option(s) key=>value array to filter by
6310
     * $params['where'] string WHERE clause of query
6311
     *
6312
     * @param array $params An associative array of parameters
6313
     * @param bool $strict  Whether to require a field exist or not when loading the info
6314
     *
6315
     * @return array Array of field data.
6316
     *
6317
     * @since 1.7.9
6318
     */
6319
    public function load_fields ( $params, $strict = false ) {
6320
		// @todo Get away from using md5/serialize, I'm sure we can cache specific parts
6321
	    $cache_key = md5( serialize( $params  ) );
6322
	    if ( isset( $this->fields_cache[ $cache_key ] ) ) {
6323
		    return $this->fields_cache[ $cache_key ];
6324
	    }
6325
6326
        $params = (object) pods_sanitize( $params );
6327
6328
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6329
            $params->pod = '';
6330
6331
        if ( !isset( $params->pod_id ) || empty( $params->pod_id ) )
6332
            $params->pod_id = 0;
6333
6334 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
6335
            $params->name = array();
6336
        else
6337
            $params->name = (array) $params->name;
6338
6339
        if ( !isset( $params->id ) || empty( $params->id ) )
6340
            $params->id = array();
6341
        else {
6342
            $params->id = (array) $params->id;
6343
6344
            foreach ( $params->id as &$id ) {
6345
                $id = pods_absint( $id );
6346
            }
6347
        }
6348
6349 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6350
            $params->type = array();
6351
        else
6352
            $params->type = (array) $params->type;
6353
6354
        $fields = array();
6355
6356
        if ( !empty( $params->pod ) || !empty( $params->pod_id ) ) {
6357
            $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => true ), false );
6358
6359
            if ( false === $pod ) {
6360
                if ( $strict )
6361
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
6362
6363
                return $fields;
6364
            }
6365
6366
			$pod[ 'fields' ] = array_merge( pods_var_raw( 'object_fields', $pod, array() ), $pod[ 'fields' ] );
6367
6368
            foreach ( $pod[ 'fields' ] as $field ) {
6369
                if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6370
                    $fields[ $field[ 'name' ] ] = $field;
6371
				elseif ( in_array( $fields[ 'name' ], $params->name ) || in_array( $fields[ 'id' ], $params->id ) || in_array( $fields[ 'type' ], $params->type ) )
6372
                    $fields[ $field[ 'name' ] ] = $field;
6373
            }
6374
        }
6375
        elseif ( ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) || ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) ) ) {
6376
            $order = 'ASC';
6377
            $orderby = 'menu_order title';
6378
            $limit = -1;
6379
            $ids = false;
6380
6381
            $meta_query = array();
6382
6383 View Code Duplication
            if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6384
                foreach ( $params->options as $option => $value ) {
6385
                    if ( !is_array( $value ) )
6386
                        $value = array( $value );
6387
6388
                    $value = pods_trim( $value );
6389
6390
                    sort( $value );
6391
6392
                    $meta_query[] = array(
6393
                        'key' => $option,
6394
                        'value' => pods_sanitize( $value ),
6395
                        'compare' => 'IN'
6396
                    );
6397
                }
6398
            }
6399
6400
            if ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) )
6401
                $meta_query = array_merge( $meta_query, (array) $params->where );
6402
6403
			$args = array(
6404
				'post_type' => '_pods_field',
6405
				'nopaging' => true,
6406
				'posts_per_page' => $limit,
6407
				'order' => $order,
6408
				'orderby' => $orderby,
6409
				'meta_query' => $meta_query,
6410
			);
6411
6412
			// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6413
			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...
6414
				$args[ 'post__in' ] = $ids;
6415
			}
6416
6417
            $fields = array();
6418
6419
            $_fields = get_posts( $args );
6420
6421
            foreach ( $_fields as $field ) {
6422
                $field = $this->load_field( $field, false );
6423
6424
                if ( !empty( $field ) )
6425
                    $fields[ $field[ 'id' ] ] = $field;
6426
            }
6427
        }
6428
        else {
6429 View Code Duplication
            if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6430
                return pods_error( __( 'Either Field Name / Field ID / Field Type, or Pod Name / Pod ID are required', 'pods' ), $this );
6431
6432
            $lookup = array();
6433
6434 View Code Duplication
            if ( !empty( $params->name ) ) {
6435
                $fields = implode( "', '", $params->name );
6436
6437
                $lookup[] = "`post_name` IN ( '{$fields}' )";
6438
            }
6439
6440 View Code Duplication
            if ( !empty( $params->id ) ) {
6441
                $fields = implode( ", ", $params->id );
6442
6443
                $lookup[] = "`ID` IN ( {$fields} )";
6444
            }
6445
6446
            $lookup = implode( ' AND ', $lookup );
6447
6448
            $result = pods_query( "SELECT `ID`, `post_name`, `post_parent` FROM `@wp_posts` WHERE `post_type` = '_pods_field' AND ( {$lookup} )" );
6449
6450
            $fields = array();
6451
6452
            if ( !empty( $result ) ) {
6453
                foreach ( $result as $field ) {
6454
					$field = $this->load_field( array(
6455
                        'id' => $field->ID,
6456
                        'name' => $field->post_name,
6457
                        'pod_id' => $field->post_parent
6458
                    ), false );
6459
6460
                    if ( !empty( $field ) && ( empty( $params->type ) || in_array( $field[ 'type' ], $params->type ) ) )
6461
                        $fields[ $field[ 'id' ] ] = $field;
6462
                }
6463
            }
6464
        }
6465
	    if ( isset( $cache_key ) ) {
6466
		    $this->fields_cache[ $cache_key ] = $fields;
6467
	    }
6468
        return $fields;
6469
    }
6470
6471
    /**
6472
     * Load a Pods Object
6473
     *
6474
     * $params['id'] int The Object ID
6475
     * $params['name'] string The Object name
6476
     * $params['type'] string The Object type
6477
     *
6478
     * @param array|object $params An associative array of parameters
6479
     * @param bool $strict
6480
     *
6481
     * @return array|bool
6482
     * @since 2.0
6483
     */
6484
    public function load_object ( $params, $strict = false ) {
6485
        if ( is_object( $params ) && isset( $params->post_title ) )
6486
            $_object = get_object_vars( $params );
6487
        else {
6488
            $params = (object) pods_sanitize( $params );
6489
6490 View Code Duplication
            if ( !isset( $params->type ) || empty( $params->type ) )
6491
                return pods_error( __( 'Object type is required', 'pods' ), $this );
6492
6493 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) )
6494
                return pods_error( __( 'Either Object ID or Name are required', 'pods' ), $this );
6495
6496
            /**
6497
             * @var $wpdb wpdb
6498
             */
6499
            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...
6500
6501
            if ( isset( $params->name ) )
6502
                $_object = pods_by_title( $params->name, ARRAY_A, '_pods_' . $params->type, 'publish' );
6503
            else {
6504
                $object = $params->id;
6505
6506
                $_object = get_post( $object, ARRAY_A );
6507
            }
6508
6509
            if ( empty( $_object ) ) {
6510
                if ( $strict )
6511
                    return pods_error( __( 'Object not found', 'pods' ), $this );
6512
6513
                return false;
6514
            }
6515
        }
6516
6517
        $object = array(
6518
            'id' => $_object[ 'ID' ],
6519
            'name' => $_object[ 'post_title' ],
6520
            'code' => $_object[ 'post_content' ],
6521
            'type' => str_replace( '_pods_', '', $_object[ 'post_type' ] ),
6522
            'slug' => $_object[ 'post_name' ]
6523
        );
6524
6525
        $object[ 'options' ] = get_post_meta( $object[ 'id' ] );
6526
6527
        foreach ( $object[ 'options' ] as $option => &$value ) {
6528
            if ( is_array( $value ) && 1 == count( $value ) )
6529
                $value = current( $value );
6530
        }
6531
6532
        return $object;
6533
    }
6534
6535
    /**
6536
     * Load Multiple Pods Objects
6537
     *
6538
     * $params['type'] string The Object type
6539
     * $params['options'] array Pod Option(s) key=>value array to filter by
6540
     * $params['orderby'] string ORDER BY clause of query
6541
     * $params['limit'] string Number of objects to return
6542
     * $params['where'] string WHERE clause of query
6543
     * $params['ids'] string|array IDs of Objects
6544
     *
6545
     * @param array|object $params An associative array of parameters
6546
     *
6547
     * @return array
6548
     * @since 2.0
6549
     */
6550
    public function load_objects ( $params ) {
6551
        $params = (object) pods_sanitize( $params );
6552
6553 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6554
            return pods_error( __( 'Pods Object type is required', 'pods' ), $this );
6555
6556
        $order = 'ASC';
6557
        $orderby = 'menu_order';
6558
        $limit = -1;
6559
        $ids = false;
6560
6561
        $meta_query = array();
6562
        $cache_key = '';
6563
6564 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6565
            foreach ( $params->options as $option => $value ) {
6566
                if ( !is_array( $value ) )
6567
                    $value = array( $value );
6568
6569
                $value = pods_trim( $value );
6570
6571
                sort( $value );
6572
6573
                $meta_query[] = array(
6574
                    'key' => $option,
6575
                    'value' => pods_sanitize( $value ),
6576
                    'compare' => 'IN'
6577
                );
6578
            }
6579
        }
6580
6581
        if ( isset( $params->where ) && is_array( $params->where ) )
6582
            $meta_query = array_merge( $meta_query, (array) $params->where );
6583
6584 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
6585
            $order = strtoupper( $params->order );
6586
6587
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
6588
            $orderby = strtoupper( $params->orderby );
6589
6590
        if ( isset( $params->limit ) && !empty( $params->limit ) )
6591
            $limit = pods_absint( $params->limit );
6592
6593
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
6594
            $ids = $params->ids;
6595
6596
            if ( !is_array( $ids ) )
6597
                $ids = explode( ',', $ids );
6598
        }
6599
6600
        if ( empty( $ids ) )
6601
            $ids = false;
6602
6603
        if ( pods_api_cache() && empty( $meta_query ) && empty( $limit ) && ( empty( $orderby ) || 'menu_order' == $orderby ) && empty( $ids ) ) {
6604
            $cache_key = 'pods_objects_' . $params->type;
6605
6606
            $the_objects = pods_transient_get( $cache_key );
6607
6608
            if ( false !== $the_objects )
6609
                return $the_objects;
6610
        }
6611
6612
        $the_objects = array();
6613
6614
		$args = array(
6615
			'post_type' => '_pods_' . $params->type,
6616
			'nopaging' => true,
6617
			'posts_per_page' => $limit,
6618
			'order' => $order,
6619
			'orderby' => $orderby,
6620
			'meta_query' => $meta_query,
6621
		);
6622
6623
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6624
		if ( false != $ids ) {
6625
			$args[ 'post__in' ] = $ids;
6626
		}
6627
6628
		$objects = get_posts( $args );
6629
6630
        foreach ( $objects as $object ) {
6631
            $object = $this->load_object( $object );
6632
6633
            $the_objects[ $object[ 'name' ] ] = $object;
6634
        }
6635
6636
        if ( pods_api_cache() && !empty( $cache_key ) )
6637
            pods_transient_set( $cache_key, $the_objects );
6638
6639
        return $the_objects;
6640
    }
6641
6642
    /**
6643
     * @see PodsAPI::load_object
6644
     *
6645
     * Load a Pod Template
6646
     *
6647
     * $params['id'] int The template ID
6648
     * $params['name'] string The template name
6649
     *
6650
     * @param array $params An associative array of parameters
6651
     *
6652
     * @return array|bool
6653
     * @since 1.7.9
6654
     */
6655
    public function load_template ( $params ) {
6656
        if ( !class_exists( 'Pods_Templates' ) )
6657
            return false;
6658
6659
        $params = (object) $params;
6660
        $params->type = 'template';
6661
        return $this->load_object( $params );
6662
    }
6663
6664
    /**
6665
     * @see PodsAPI::load_objects
6666
     *
6667
     * Load Multiple Pod Templates
6668
     *
6669
     * $params['where'] string The WHERE clause of query
6670
     * $params['options'] array Pod Option(s) key=>value array to filter by
6671
     * $params['orderby'] string ORDER BY clause of query
6672
     * $params['limit'] string Number of templates to return
6673
     *
6674
     * @param array $params (optional) An associative array of parameters
6675
     *
6676
     * @return array
6677
     *
6678
     * @since 2.0
6679
     */
6680
    public function load_templates ( $params = null ) {
6681
        if ( !class_exists( 'Pods_Templates' ) )
6682
            return array();
6683
6684
        $params = (object) $params;
6685
        $params->type = 'template';
6686
        return $this->load_objects( $params );
6687
    }
6688
6689
    /**
6690
     * @see PodsAPI::load_object
6691
     *
6692
     * Load a Pod Page
6693
     *
6694
     * $params['id'] int The page ID
6695
     * $params['name'] string The page URI
6696
     *
6697
     * @param array $params An associative array of parameters
6698
     *
6699
     * @return array|bool
6700
     *
6701
     * @since 1.7.9
6702
     */
6703
    public function load_page ( $params ) {
6704
        if ( !class_exists( 'Pods_Pages' ) )
6705
            return false;
6706
6707
        $params = (object) $params;
6708 View Code Duplication
        if ( !isset( $params->name ) && isset( $params->uri ) ) {
6709
            $params->name = $params->uri;
6710
            unset( $params->uri );
6711
        }
6712
        $params->type = 'page';
6713
        return $this->load_object( $params );
6714
    }
6715
6716
    /**
6717
     * @see PodsAPI::load_objects
6718
     *
6719
     * Load Multiple Pod Pages
6720
     *
6721
     * $params['where'] string The WHERE clause of query
6722
     * $params['options'] array Pod Option(s) key=>value array to filter by
6723
     * $params['orderby'] string ORDER BY clause of query
6724
     * $params['limit'] string Number of pages to return
6725
     *
6726
     * @param array $params (optional) An associative array of parameters
6727
     *
6728
     * @return array
6729
     *
6730
     * @since 2.0
6731
     */
6732
    public function load_pages ( $params = null ) {
6733
        if ( !class_exists( 'Pods_Pages' ) )
6734
            return array();
6735
6736
        $params = (object) $params;
6737
        $params->type = 'page';
6738
        return $this->load_objects( $params );
6739
    }
6740
6741
    /**
6742
     * @see PodsAPI::load_object
6743
     *
6744
     * Load a Pod Helper
6745
     *
6746
     * $params['id'] int The helper ID
6747
     * $params['name'] string The helper name
6748
     *
6749
     * @param array $params An associative array of parameters
6750
     *
6751
     * @return array|bool
6752
     *
6753
     * @since 1.7.9
6754
     */
6755 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...
6756
        if ( !class_exists( 'Pods_Helpers' ) )
6757
            return false;
6758
6759
        $params = (object) $params;
6760
        $params->type = 'helper';
6761
        return $this->load_object( $params );
6762
    }
6763
6764
    /**
6765
     * @see PodsAPI::load_objects
6766
     *
6767
     * Load Multiple Pod Helpers
6768
     *
6769
     * $params['where'] string The WHERE clause of query
6770
     * $params['options'] array Pod Option(s) key=>value array to filter by
6771
     * $params['orderby'] string ORDER BY clause of query
6772
     * $params['limit'] string Number of pages to return
6773
     *
6774
     * @param array $params (optional) An associative array of parameters
6775
     *
6776
     * @return array
6777
     *
6778
     * @since 2.0
6779
     */
6780 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...
6781
        if ( !class_exists( 'Pods_Helpers' ) )
6782
            return array();
6783
6784
        $params = (object) $params;
6785
        $params->type = 'helper';
6786
        return $this->load_objects( $params );
6787
    }
6788
6789
    /**
6790
     * Load the pod item object
6791
     *
6792
     * $params['pod'] string The datatype name
6793
     * $params['id'] int (optional) The item's ID
6794
     *
6795
     * @param array $params An associative array of parameters
6796
     *
6797
     * @return bool|\Pods
6798
     *
6799
     * @uses pods()
6800
     *
6801
     * @since 2.0
6802
     */
6803
    public function load_pod_item ( $params ) {
6804
        $params = (object) pods_sanitize( $params );
6805
6806 View Code Duplication
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6807
            return pods_error( __( 'Pod name required', 'pods' ), $this );
6808 View Code Duplication
        if ( !isset( $params->id ) || empty( $params->id ) )
6809
            return pods_error( __( 'Item ID required', 'pods' ), $this );
6810
6811
        $pod = false;
6812
6813
        if ( pods_api_cache() )
6814
            $pod = pods_cache_get( $params->id, 'pods_item_object_' . $params->pod );
6815
6816
        if ( false !== $pod )
6817
            return $pod;
6818
6819
        $pod = pods( $params->pod, $params->id );
6820
6821
        if ( pods_api_cache() )
6822
            pods_cache_set( $params->id, $pod, 'pods_item_object_' . $params->pod );
6823
6824
        return $pod;
6825
    }
6826
6827
    /**
6828
     * Load potential sister fields for a specific field
6829
     *
6830
     * $params['pod'] int The Pod name
6831
     * $params['related_pod'] string The related Pod name
6832
     *
6833
     * @param array $params An associative array of parameters
6834
     * @param array $pod (optional) Array of Pod data to use (to avoid lookup)
6835
     *
6836
     * @return array|bool
6837
     *
6838
     * @since 1.7.9
6839
     *
6840
     * @uses PodsAPI::load_pod
6841
     */
6842
    public function load_sister_fields ( $params, $pod = null ) {
6843
        $params = (object) pods_sanitize( $params );
6844
6845
        if ( empty( $pod ) ) {
6846
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ), false );
6847
6848
            if ( false === $pod )
6849
                return pods_error( __( 'Pod not found', 'pods' ), $this );
6850
        }
6851
6852
        $params->pod_id = $pod[ 'id' ];
6853
        $params->pod = $pod[ 'name' ];
6854
6855
        $type = false;
6856
6857
        if ( 0 === strpos( $params->related_pod, 'pod-' ) ) {
6858
            $params->related_pod = pods_str_replace( 'pod-', '', $params->related_pod, 1 );
6859
            $type = 'pod';
6860
        }
6861 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'post_type-' ) ) {
6862
            $params->related_pod = pods_str_replace( 'post_type-', '', $params->related_pod, 1 );
6863
            $type = 'post_type';
6864
        }
6865 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'taxonomy-' ) ) {
6866
            $params->related_pod = pods_str_replace( 'taxonomy-', '', $params->related_pod, 1 );
6867
            $type = 'taxonomy';
6868
        }
6869
        elseif ( 'comment' === $params->related_pod ) {
6870
            $type = $params->related_pod;
6871
        }
6872
6873
        $related_pod = $this->load_pod( array( 'name' => $params->related_pod, 'table_info' => false ), false );
6874
6875
        if ( false === $related_pod || ( false !== $type && 'pod' != $type && $type != $related_pod[ 'type' ] ) )
6876
            return pods_error( __( 'Related Pod not found', 'pods' ), $this );
6877
6878
        $params->related_pod_id = $related_pod[ 'id' ];
6879
        $params->related_pod = $related_pod[ 'name' ];
6880
6881
        $sister_fields = array();
6882
6883
        foreach ( $related_pod[ 'fields' ] as $field ) {
6884
            if ( 'pick' == $field[ 'type' ] && in_array( $field[ 'pick_object' ], array( $pod[ 'type' ], 'pod' ) ) && ( $params->pod == $field[ 'pick_object' ] || $params->pod == $field[ 'pick_val' ] ) )
6885
                $sister_fields[ $field[ 'id' ] ] = esc_html( $field[ 'label' ] . ' (' . $field[ 'name' ] . ')' );
6886
        }
6887
6888
        return $sister_fields;
6889
    }
6890
6891
    /**
6892
     * Takes a sql field such as tinyint and returns the pods field type, such as num.
6893
     *
6894
     * @param string $sql_field The SQL field to look for
6895
     *
6896
     * @return string The field type
6897
     *
6898
     * @since 2.0
6899
     */
6900
    public static function detect_pod_field_from_sql_data_type ( $sql_field ) {
6901
        $sql_field = strtolower( $sql_field );
6902
6903
        $field_to_field_map = array(
6904
            'tinyint' => 'number',
6905
            'smallint' => 'number',
6906
            'mediumint' => 'number',
6907
            'int' => 'number',
6908
            'bigint' => 'number',
6909
            'float' => 'number',
6910
            'double' => 'number',
6911
            'decimal' => 'number',
6912
            'date' => 'date',
6913
            'datetime' => 'datetime',
6914
            'timestamp' => 'datetime',
6915
            'time' => 'time',
6916
            'year' => 'date',
6917
            'varchar' => 'text',
6918
            'text' => 'paragraph',
6919
            'mediumtext' => 'paragraph',
6920
            'longtext' => 'paragraph'
6921
        );
6922
6923
        return ( array_key_exists( $sql_field, $field_to_field_map ) ) ? $field_to_field_map[ $sql_field ] : 'paragraph';
6924
    }
6925
6926
    /**
6927
     * Gets all field types
6928
     *
6929
     * @return array Array of field types
6930
     *
6931
     * @uses PodsForm::field_loader
6932
     *
6933
     * @since 2.0
6934
     * @deprecated
6935
     */
6936
    public function get_field_types () {
6937
        return PodsForm::field_types();
6938
    }
6939
6940
    /**
6941
     * Gets the schema definition of a field.
6942
     *
6943
     * @param string $type Field type to look for
6944
     * @param array $options (optional) Options of the field to pass to the schema function.
6945
     *
6946
     * @return array|bool|mixed|null
6947
     *
6948
     * @since 2.0
6949
     */
6950
    private function get_field_definition ( $type, $options = null ) {
6951
        $definition = PodsForm::field_method( $type, 'schema', $options );
6952
6953
        return $this->do_hook( 'field_definition', $definition, $type, $options );
6954
    }
6955
6956
    /**
6957
     * @see PodsForm:validate
6958
     *
6959
     * Validates the value of a field.
6960
     *
6961
     * @param mixed $value The value to validate
6962
     * @param string $field Field to use for validation
6963
     * @param array $object_fields Fields of the object we're validating
6964
     * @param array $fields Array of all fields data
6965
     * @param array|Pods $pod Array of pod data (or Pods object)
6966
     * @param array|object $params Extra parameters to pass to the validation function of the field.
6967
     *
6968
     * @return array|bool
6969
     *
6970
     * @uses PodsForm::validate
6971
     *
6972
     * @since 2.0
6973
     */
6974
    public function handle_field_validation ( &$value, $field, $object_fields, $fields, $pod, $params ) {
6975
        $tableless_field_types = PodsForm::tableless_field_types();
6976
6977
        $fields = array_merge( $fields, $object_fields );
6978
6979
        $options = $fields[ $field ];
6980
6981
        $id = ( is_object( $params ) ? $params->id : ( is_object( $pod ) ? $pod->id() : 0 ) );
6982
6983
        if ( is_object( $pod ) )
6984
            $pod = $pod->pod_data;
6985
6986
        $type = $options[ 'type' ];
6987
        $label = $options[ 'label' ];
6988
        $label = empty( $label ) ? $field : $label;
6989
6990
        // Verify required fields
6991
        if ( 1 == pods_var( 'required', $options[ 'options' ], 0 ) && 'slug' != $type ) {
6992
            if ( '' == $value || null === $value || array() === $value )
6993
                return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this );
6994
6995
            if ( 'multi' == pods_var( 'pick_format_type', $options[ 'options' ] ) && 'autocomplete' != pods_var( 'pick_format_multi', $options[ 'options' ] ) ) {
6996
                $has_value = false;
6997
6998
                $check_value = (array) $value;
6999
7000
                foreach ( $check_value as $val ) {
7001
                    if ( '' != $val && null !== $val && 0 !== $val && '0' !== $val ) {
7002
                        $has_value = true;
7003
7004
                        continue;
7005
                    }
7006
                }
7007
7008
                if ( !$has_value )
7009
                    return pods_error( sprintf( __( '%s is required', 'pods' ), $label ), $this );
7010
            }
7011
7012
        }
7013
7014
        // @todo move this to after pre-save preparations
7015
        // Verify unique fields
7016
        if ( 1 == pods_var( 'unique', $options[ 'options' ], 0 ) && '' !== $value && null !== $value && array() !== $value ) {
7017
            if ( empty( $pod ) )
7018
                return false;
7019
7020
            if ( !in_array( $type, $tableless_field_types ) ) {
7021
                $exclude = '';
7022
7023
                if ( !empty( $id ) )
7024
                    $exclude = "AND `id` != {$id}";
7025
7026
                $check = false;
7027
7028
                $check_value = pods_sanitize( $value );
7029
7030
                // @todo handle meta-based fields
7031
                // Trigger an error if not unique
7032
                if ( 'table' == $pod[ 'storage' ] )
7033
                    $check = pods_query( "SELECT `id` FROM `@wp_pods_" . $pod[ 'name' ] . "` WHERE `{$field}` = '{$check_value}' {$exclude} LIMIT 1", $this );
7034
7035
                if ( !empty( $check ) )
7036
                    return pods_error( sprintf( __( '%s needs to be unique', 'pods' ), $label ), $this );
7037
            }
7038
            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...
7039
                // @todo handle tableless check
7040
            }
7041
        }
7042
7043
        $validate = PodsForm::validate( $options[ 'type' ], $value, $field, array_merge( $options, pods_var( 'options', $options, array() ) ), $fields, $pod, $id, $params );
7044
7045
        $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params );
7046
7047
        return $validate;
7048
    }
7049
7050
    /**
7051
     * Find items related to a parent field
7052
     *
7053
     * @param int $field_id The Field ID
7054
     * @param int $pod_id The Pod ID
7055
     * @param mixed $ids A comma-separated string (or array) of item IDs
7056
     * @param array $field Field data array
7057
     * @param array $pod Pod data array
7058
     *
7059
     * @return int[]
7060
     *
7061
     * @since 2.0
7062
     *
7063
     * @uses pods_query()
7064
     */
7065
    public function lookup_related_items ( $field_id, $pod_id, $ids, $field = null, $pod = null ) {
7066
        $related_ids = array();
7067
7068
        if ( !is_array( $ids ) )
7069
            $ids = explode( ',', $ids );
7070
7071
        $ids = array_map( 'absint', $ids );
7072
7073
        $ids = array_unique( array_filter( $ids ) );
7074
7075
	    $idstring = implode( ',', $ids );
7076
7077
	    if ( 0 != $pod_id && 0 != $field_id && isset( self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] ) ) {
7078
		    // Check cache first, no point in running the same query multiple times
7079
		    return self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ];
7080
	    }
7081
7082
        $tableless_field_types = PodsForm::tableless_field_types();
7083
7084
		$field_type = pods_v( 'type', $field );
7085
7086
        if ( empty( $ids ) || !in_array( $field_type, $tableless_field_types ) )
7087
            return array();
7088
7089
        $related_pick_limit = 0;
7090
7091
		if ( empty( $field ) ) {
7092
			$field = $this->load_field( array( 'id' => $field_id ) );
7093
		}
7094
7095
        if ( !empty( $field ) ) {
7096
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7097
7098
            $related_pick_limit = (int) pods_v( $field_type . '_limit', $options, 0 );
7099
7100
            if ( 'single' == pods_var_raw( $field_type . '_format_type', $options ) )
7101
                $related_pick_limit = 1;
7102
7103
            // Temporary hack until there's some better handling here
7104
            $related_pick_limit = $related_pick_limit * count( $ids );
7105
        }
7106
7107
		if ( 'taxonomy' == $field_type ) {
7108
			$related = wp_get_object_terms( $ids, pods_v( 'name', $field ), array( 'fields' => 'ids' ) );
7109
7110
			if ( !is_wp_error( $related ) ) {
7111
				$related_ids = $related;
7112
			}
7113
		} elseif ( 'comment' == $field_type ) {
7114
			$comment_args = array(
7115
				'post__in' => $ids,
7116
				'fields' => 'ids',
7117
			);
7118
7119
			$related = get_comments( $comment_args );
7120
7121
			if ( ! is_wp_error( $related ) ) {
7122
				$related_ids = $related;
7123
			}
7124
		} elseif ( !pods_tableless() ) {
7125
            $ids = implode( ', ', $ids );
7126
7127
            $field_id = (int) $field_id;
7128
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7129
7130
            $related_where = "
7131
                `field_id` = {$field_id}
7132
                AND `item_id` IN ( {$ids} )
7133
            ";
7134
7135
            $sql = "
7136
                SELECT item_id, related_item_id, related_field_id
7137
                FROM `@wp_podsrel`
7138
                WHERE
7139
                    {$related_where}
7140
                ORDER BY `weight`
7141
            ";
7142
7143
            $relationships = pods_query( $sql );
7144
7145
            if ( !empty( $relationships ) ) {
7146
                foreach ( $relationships as $relation ) {
7147
                    if ( !in_array( $relation->related_item_id, $related_ids ) )
7148
                        $related_ids[] = (int) $relation->related_item_id;
7149
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->item_id, $related_ids ) )
7150
                        $related_ids[] = (int) $relation->item_id;
7151
                }
7152
            }
7153
        }
7154 View Code Duplication
        else {
7155
            if ( !is_array( $pod ) )
7156
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7157
7158
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
7159
                $meta_type = $pod[ 'type' ];
7160
7161
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
7162
                    $meta_type = 'post';
7163
                elseif ( 'taxonomy' == $meta_type )
7164
                    $meta_type = 'term';
7165
7166
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7167
7168
                if ( !$no_conflict )
7169
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7170
7171
                foreach ( $ids as $id ) {
7172
                    if ( 'settings' == $meta_type ) {
7173
                        $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7174
7175
                        if ( empty( $related_id ) )
7176
                            $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7177
7178
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
7179
                            foreach ( $related_id as $related ) {
7180
                                if ( is_array( $related ) && !empty( $related ) ) {
7181
                                    if ( isset( $related[ 'id' ] ) )
7182
                                        $related_ids[] = (int) $related[ 'id' ];
7183
                                    else {
7184
                                        foreach ( $related as $r ) {
7185
                                            $related_ids[] = (int) $r;
7186
                                        }
7187
                                    }
7188
                                }
7189
                                else
7190
                                    $related_ids[] = (int) $related;
7191
                            }
7192
                        }
7193
                    }
7194
                    else {
7195
                        $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7196
7197
                        if ( empty( $related_id ) )
7198
                            $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7199
7200
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
7201
                            foreach ( $related_id as $related ) {
7202
                                if ( is_array( $related ) && !empty( $related ) ) {
7203
                                    if ( isset( $related[ 'id' ] ) )
7204
                                        $related_ids[] = (int) $related[ 'id' ];
7205
                                    else {
7206
                                        foreach ( $related as $r ) {
7207
                                            if ( isset( $related[ 'id' ] ) )
7208
                                                $related_ids[] = (int) $r[ 'id' ];
7209
                                            else
7210
                                                $related_ids[] = (int) $r;
7211
                                        }
7212
                                    }
7213
                                }
7214
                                else
7215
                                    $related_ids[] = (int) $related;
7216
                            }
7217
                        }
7218
                    }
7219
                }
7220
7221
                if ( !$no_conflict )
7222
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7223
            }
7224
        }
7225
7226
        if ( is_array( $related_ids ) ) {
7227
            $related_ids = array_unique( array_filter( $related_ids ) );
7228
7229
            if ( 0 < $related_pick_limit && !empty( $related_ids ) )
7230
                $related_ids = array_slice( $related_ids, 0, $related_pick_limit );
7231
        }
7232
	    if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) {
7233
                    // Only cache if $pod_id and $field_id were passed
7234
		    self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] = $related_ids;
7235
	    }
7236
7237
        return $related_ids;
7238
    }
7239
7240
    /**
7241
     * Find related items related to an item
7242
     *
7243
     * @param int $field_id The Field ID
7244
     * @param int $pod_id The Pod ID
7245
     * @param int $id Item ID to get related IDs from
7246
     * @param array $field Field data array
7247
     * @param array $pod Pod data array
7248
     *
7249
     * @return array|bool
7250
     *
7251
     * @since 2.3
7252
     *
7253
     * @uses pods_query()
7254
     */
7255
    public function lookup_related_items_from ( $field_id, $pod_id, $id, $field = null, $pod = null ) {
7256
        $related_ids = false;
7257
7258
        $id = (int) $id;
7259
7260
        $tableless_field_types = PodsForm::tableless_field_types();
7261
7262
        if ( empty( $id ) || !in_array( pods_v( 'type', $field ), $tableless_field_types ) )
7263
            return false;
7264
7265
        $related_pick_limit = 0;
7266
7267
        if ( !empty( $field ) ) {
7268
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7269
7270
            $related_pick_limit = (int) pods_v( 'pick_limit', $options, 0 );
7271
7272
            if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
7273
                $related_pick_limit = 1;
7274
        }
7275
7276
        if ( !pods_tableless() ) {
7277
            $field_id = (int) $field_id;
7278
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7279
7280
            $related_where = "
7281
                `field_id` = {$field_id}
7282
                AND `related_item_id` = {$id}
7283
            ";
7284
7285
            $sql = "
7286
                SELECT *
7287
                FROM `@wp_podsrel`
7288
                WHERE
7289
                    {$related_where}
7290
                ORDER BY `weight`
7291
            ";
7292
7293
            $relationships = pods_query( $sql );
7294
7295
            if ( !empty( $relationships ) ) {
7296
                $related_ids = array();
7297
7298
                foreach ( $relationships as $relation ) {
7299
                    if ( $field_id == $relation->field_id && !in_array( $relation->item_id, $related_ids ) )
7300
                        $related_ids[] = (int) $relation->item_id;
7301
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->related_item_id, $related_ids ) )
7302
                        $related_ids[] = (int) $relation->related_item_id;
7303
                }
7304
            }
7305
        }
7306 View Code Duplication
        else {
7307
            // @todo handle meta-based lookups
7308
            return false;
7309
7310
            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...
7311
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7312
7313
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
7314
                $related_ids = array();
7315
7316
                $meta_type = $pod[ 'type' ];
7317
7318
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
7319
                    $meta_type = 'post';
7320
                elseif ( 'taxonomy' == $meta_type )
7321
                    $meta_type = 'term';
7322
7323
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7324
7325
                if ( !$no_conflict )
7326
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7327
7328
                if ( 'settings' == $meta_type ) {
7329
                    $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7330
7331
                    if ( empty( $related_id ) )
7332
                        $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7333
7334
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7335
                        foreach ( $related_id as $related ) {
7336
                            if ( is_array( $related ) && !empty( $related ) ) {
7337
                                if ( isset( $related[ 'id' ] ) )
7338
                                    $related_ids[] = (int) $related[ 'id' ];
7339
                                else {
7340
                                    foreach ( $related as $r ) {
7341
                                        $related_ids[] = (int) $r;
7342
                                    }
7343
                                }
7344
                            }
7345
                            else
7346
                                $related_ids[] = (int) $related;
7347
                        }
7348
                    }
7349
                }
7350
                else {
7351
                    $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7352
7353
                    if ( empty( $related_id ) )
7354
                        $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7355
7356
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7357
                        foreach ( $related_id as $related ) {
7358
                            if ( is_array( $related ) && !empty( $related ) ) {
7359
                                if ( isset( $related[ 'id' ] ) )
7360
                                    $related_ids[] = (int) $related[ 'id' ];
7361
                                else {
7362
                                    foreach ( $related as $r ) {
7363
                                        if ( isset( $related[ 'id' ] ) )
7364
                                            $related_ids[] = (int) $r[ 'id' ];
7365
                                        else
7366
                                            $related_ids[] = (int) $r;
7367
                                    }
7368
                                }
7369
                            }
7370
                            else
7371
                                $related_ids[] = (int) $related;
7372
                        }
7373
                    }
7374
                }
7375
7376
                if ( !$no_conflict )
7377
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7378
            }
7379
        }
7380
7381
        if ( is_array( $related_ids ) )
7382
            $related_ids = array_unique( array_filter( $related_ids ) );
7383
7384
        return $related_ids;
7385
    }
7386
7387
	/**
7388
	 *
7389
	 * Load the information about an objects MySQL table
7390
	 *
7391
	 * @param $object_type
7392
	 * @param string $object The object to look for
7393
	 * @param null $name (optional) Name of the pod to load
7394
	 * @param array $pod (optional) Array with pod information
7395
	 *
7396
	 * @return array
7397
	 *
7398
	 * @since 2.5
7399
	 */
7400
	public function get_table_info_load ( $object_type, $object, $name = null, $pod = null ) {
7401
7402
		$info = array();
7403
7404
		if ( 'pod' == $object_type && null === $pod ) {
7405 View Code Duplication
			if ( empty( $name ) ) {
7406
				$prefix = 'pod-';
7407
7408
				// Make sure we actually have the prefix before trying anything with the name
7409
				if ( 0 === strpos( $object_type, $prefix ) )
7410
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7411
			}
7412
7413
			if ( empty( $name ) && !empty( $object ) )
7414
				$name = $object;
7415
7416
			$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7417
7418
			if ( !empty( $pod ) ) {
7419
				$object_type = $pod[ 'type' ];
7420
				$name = $pod[ 'name' ];
7421
				$object = $pod[ 'object' ];
7422
7423
				$info[ 'pod' ] = $pod;
7424
			}
7425
		}
7426
		elseif ( null === $pod ) {
7427
			if ( empty( $name ) ) {
7428
				$prefix = $object_type . '-';
7429
7430
				// Make sure we actually have the prefix before trying anything with the name
7431
				if ( 0 === strpos( $object_type, $prefix ) )
7432
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7433
			}
7434
7435
			if ( empty( $name ) && !empty( $object ) )
7436
				$name = $object;
7437
7438
			if ( !empty( $name ) ) {
7439
				$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7440
7441
				if ( !empty( $pod ) && ( null === $object_type || $object_type == $pod[ 'type' ] ) ) {
7442
					$object_type = $pod[ 'type' ];
7443
					$name = $pod[ 'name' ];
7444
					$object = $pod[ 'object' ];
7445
7446
					$info[ 'pod' ] = $pod;
7447
				}
7448
			}
7449
		}
7450
		elseif ( !empty( $pod ) )
7451
			$info[ 'pod' ] = $pod;
7452
7453
		if ( 0 === strpos( $object_type, 'pod' ) ) {
7454 View Code Duplication
			if ( empty( $name ) ) {
7455
				$prefix = 'pod-';
7456
7457
				// Make sure we actually have the prefix before trying anything with the name
7458
				if ( 0 === strpos( $object_type, $prefix ) )
7459
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7460
			}
7461
7462
			$info[ 'type' ] = 'pod';
7463
			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...
7464
7465
			$info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object );
7466
7467
			if ( is_array( $info[ 'pod' ] ) && 'pod' == pods_v( 'type', $info[ 'pod' ] ) ) {
7468
				$info[ 'pod_field_index' ] = $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_v( 'pod_index', $info[ 'pod' ][ 'options' ], 'id', true );
7469
7470
				$slug_field = get_posts( array(
7471
					'post_type' => '_pods_field',
7472
					'posts_per_page' => 1,
7473
					'nopaging' => true,
7474
					'post_parent' => $info[ 'pod' ][ 'id' ],
7475
					'orderby' => 'menu_order',
7476
					'order' => 'ASC',
7477
					'meta_query' => array(
7478
						array(
7479
							'key' => 'type',
7480
							'value' => 'slug',
7481
						)
7482
					)
7483
				) );
7484
7485
				if ( !empty( $slug_field ) ) {
7486
					$slug_field = $slug_field[ 0 ];
7487
7488
					$info[ 'field_slug' ] = $info[ 'pod_field_slug' ] = $slug_field->post_name;
7489
				}
7490
7491
				if ( 1 == pods_v( 'hierarchical', $info[ 'pod' ][ 'options' ], 0 ) ) {
7492
					$parent_field = pods_v( 'pod_parent', $info[ 'pod' ][ 'options' ], 'id', true );
7493
7494
					if ( !empty( $parent_field ) && isset( $info[ 'pod' ][ 'fields' ][ $parent_field ] ) ) {
7495
						$info[ 'object_hierarchical' ] = true;
7496
7497
						$info[ 'pod_field_parent' ] = $info[ 'field_parent' ] = $parent_field . '_select';
7498
						$info[ 'field_parent_select' ] = '`' . $parent_field . '`.`id` AS `' . $info[ 'field_parent' ] . '`';
7499
					}
7500
				}
7501
			}
7502
		}
7503
		return $info;
7504
	}
7505
7506
    /**
7507
     * Get information about an objects MySQL table
7508
     *
7509
     * @param string $object_type
7510
     * @param string $object The object to look for
7511
     * @param null $name (optional) Name of the pod to load
7512
     * @param array $pod (optional) Array with pod information
7513
     * @param array $field (optional) Array with field information
7514
     *
7515
     * @return array|bool
7516
     *
7517
     * @since 2.0
7518
     */
7519
    public function get_table_info ( $object_type, $object, $name = null, $pod = null, $field = null ) {
7520
7521
	    /**
7522
	     * @var $wpdb                         wpdb
7523
	     * @var $sitepress                    SitePress
7524
	     * @var $polylang                     object
7525
	     */
7526
	    /*
7527
	     * @todo wpml-comp Remove global object usage
7528
	     */
7529
        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...
7530
7531
		// @todo Handle $object arrays for Post Types, Taxonomies, Comments (table pulled from first object in array)
7532
7533
        $info = array(
7534
            //'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...
7535
            'object_type' => $object_type,
7536
            'type' => null,
7537
            'object_name' => $object,
7538
            'object_hierarchical' => false,
7539
7540
            'table' => $object,
7541
            'meta_table' => $object,
7542
            'pod_table' => $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object ),
7543
7544
            'field_id' => 'id',
7545
            'field_index' => 'name',
7546
            'field_slug' => null,
7547
            'field_type' => null,
7548
            'field_parent' => null,
7549
            'field_parent_select' => null,
7550
7551
            'meta_field_id' => 'id',
7552
            'meta_field_index' => 'name',
7553
            'meta_field_value' => 'name',
7554
7555
            'pod_field_id' => 'id',
7556
            'pod_field_index' => 'name',
7557
            'pod_field_slug' => null,
7558
            'pod_field_parent' => null,
7559
7560
            'join' => array(),
7561
7562
            'where' => null,
7563
            'where_default' => null,
7564
7565
            'orderby' => null,
7566
7567
            'pod' => null,
7568
            'recurse' => false
7569
        );
7570
7571
        if ( empty( $object_type ) ) {
7572
            $object_type = 'post_type';
7573
            $object = 'post';
7574
        }
7575
	    elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ) ) ) {
7576
		    $object = $object_type;
7577
	    }
7578
7579
        $pod_name = $pod;
7580
7581 View Code Duplication
        if ( is_array( $pod_name ) )
7582
            $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...
7583
	    else {
7584
		    $pod_name = $object;
7585
	    }
7586
7587
        $field_name = $field;
7588
7589 View Code Duplication
        if ( is_array( $field_name ) )
7590
            $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...
7591
7592
        $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7593
7594
        $current_language = false;
7595
        $current_language_t_id = $current_language_tt_id = 0;
7596
7597
	    // Get current language data
7598
		$lang_data = PodsInit::$i18n->get_current_language_data();
0 ignored issues
show
Bug introduced by
The property i18n 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...
7599
7600
	    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...
7601
		    if ( ! empty( $lang_data['language'] ) ) {
7602
			    $current_language = $lang_data['language'];
7603
		    }
7604
7605
		    if ( ! empty( $lang_data['t_id'] ) ) {
7606
			    $current_language_t_id = $lang_data['t_id'];
7607
		    }
7608
7609
		    if ( ! empty( $lang_data['tt_id'] ) ) {
7610
			    $current_language_tt_id = $lang_data['tt_id'];
7611
		    }
7612
7613
		    if ( ! empty( $lang_data['tl_t_id'] ) ) {
7614
			    $current_language_tl_t_id = $lang_data['tl_t_id'];
7615
		    }
7616
7617
		    if ( ! empty( $lang_data['tl_tt_id'] ) ) {
7618
			    $current_language_tl_tt_id = $lang_data['tl_tt_id'];
7619
		    }
7620
	    }
7621
7622
        if ( !empty( $current_language ) )
7623
            $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7624
7625
        $_info = false;
7626
7627
	    if ( isset( self::$table_info_cache[ $transient ] ) ) {
7628
		    // Prefer info from the object internal cache
7629
		    $_info = self::$table_info_cache[ $transient ];
7630
	    } elseif ( pods_api_cache() ) {
7631
		    $_info = pods_transient_get( $transient );
7632
		    if ( false === $_info && ! did_action( 'init' ) ) {
7633
			    $_info = pods_transient_get( $transient . '_pre_init' );
7634
		    }
7635
	    }
7636
7637
	    if ( false !== $_info && is_array( $_info ) ) {
7638
		    // Data was cached, use that
7639
		    $info = $_info;
7640
	    } else {
7641
	        // Data not cached, load it up
7642
		    $_info = $this->get_table_info_load( $object_type, $object, $name, $pod );
7643
		    if ( isset( $_info[ 'type' ] ) ) {
7644
			    // Allow function to override $object_type
7645
			    $object_type = $_info[ 'type' ];
7646
		    }
7647
		    $info = array_merge( $info, $_info );
7648
	    }
7649
7650
	    if ( 0 === strpos( $object_type, 'post_type' ) || 'media' == $object_type || in_array( pods_var_raw( 'type', $info[ 'pod' ] ), array( 'post_type', 'media' ) ) ) {
7651
		    $info[ 'table' ] = $wpdb->posts;
7652
		    $info[ 'meta_table' ] = $wpdb->postmeta;
7653
7654
		    $info[ 'field_id' ] = 'ID';
7655
		    $info[ 'field_index' ] = 'post_title';
7656
		    $info[ 'field_slug' ] = 'post_name';
7657
		    $info[ 'field_type' ] = 'post_type';
7658
		    $info[ 'field_parent' ] = 'post_parent';
7659
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7660
7661
		    $info[ 'meta_field_id' ] = 'post_id';
7662
		    $info[ 'meta_field_index' ] = 'meta_key';
7663
		    $info[ 'meta_field_value' ] = 'meta_value';
7664
7665
		    if ( 'media' == $object_type )
7666
			    $object = 'attachment';
7667
7668
		    if ( empty( $name ) ) {
7669
			    $prefix = 'post_type-';
7670
7671
			    // Make sure we actually have the prefix before trying anything with the name
7672
			    if ( 0 === strpos( $object_type, $prefix ) )
7673
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7674
		    }
7675
7676
		    if ( 'media' != $object_type )
7677
			    $object_type = 'post_type';
7678
7679
		    $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7680
7681
		    if ( 'attachment' == $post_type || 'media' == $object_type )
7682
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_media';
7683
		    else
7684
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $post_type, true, false );
7685
7686
		    $post_type_object = get_post_type_object( $post_type );
7687
7688
		    if ( is_object( $post_type_object ) && $post_type_object->hierarchical )
7689
			    $info[ 'object_hierarchical' ] = true;
7690
7691
            // Post Status default
7692
            $post_status = array( 'publish' );
7693
7694
            // Pick field post_status option
7695
            if ( ! empty( $field['pick_post_status'] ) ) {
7696
                $post_status = (array) $field['pick_post_status'];
7697
            }
7698
7699
		    /**
7700
		     * Default Post Status to query for.
7701
		     *
7702
		     * Use to change "default" post status from publish to any other status or statuses.
7703
		     *
7704
		     * @param  array $post_status List of post statuses. Default is 'publish' or field setting (if available)
7705
		     * @param  string $post_type Post type of current object
7706
		     * @param  array $info Array of information about the object.
7707
		     * @param  string $object	Type of object
7708
		     * @param  string $name Name of pod to load
7709
		     * @param  array $pod Array with Pod information. Result of PodsAPI::load_pod()
7710
		     * @param  array $field		Array with field information
7711
		     *
7712
		     * @since unknown
7713
		     */
7714
		    $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', $post_status, $post_type, $info, $object_type, $object, $name, $pod, $field );
7715
7716
		    $info[ 'where' ] = array(
7717
			    //'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...
7718
			    'post_type' => '`t`.`' . $info[ 'field_type' ] . '` = "' . $post_type . '"'
7719
		    );
7720
7721
		    if ( 'post_type' == $object_type )
7722
			    $info[ 'where_default' ] = '`t`.`post_status` IN ( "' . implode( '", "', $post_status ) . '" )';
7723
7724
		    $info[ 'orderby' ] = '`t`.`menu_order`, `t`.`' . $info[ 'field_index' ] . '`, `t`.`post_date`';
7725
7726
            /*
7727
             * @todo wpml-comp Check if WPML filters can be applied afterwards
7728
             */
7729
		    // WPML support
7730
		    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' )) {
7731
			    $info[ 'join' ][ 'wpml_translations' ] = "
7732
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7733
                            ON `wpml_translations`.`element_id` = `t`.`ID`
7734
                                AND `wpml_translations`.`element_type` = 'post_{$post_type}'
7735
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7736
                    ";
7737
7738
			    $info[ 'join' ][ 'wpml_languages' ] = "
7739
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7740
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7741
                    ";
7742
7743
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7744
		    }
7745
		    // Polylang support
7746 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 ) ) {
7747
			    $info[ 'join' ][ 'polylang_languages' ] = "
7748
                        LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7749
                            ON `polylang_languages`.`object_id` = `t`.`ID`
7750
                                AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id}
7751
                    ";
7752
7753
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7754
		    }
7755
7756
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7757
	    }
7758
	    elseif ( 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, array( 'nav_menu', 'post_format' ) ) || 'taxonomy' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7759
		    $info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->terms;
7760
7761
		    $info[ 'join' ][ 'tt' ] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`";
7762
		    $info[ 'join' ][ 'tr' ] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`";
7763
		    $info[ 'field_id' ] = $info[ 'meta_field_id' ] = 'term_id';
7764
		    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = 'name';
7765
		    $info[ 'field_slug' ] = 'slug';
7766
		    $info[ 'field_type' ] = 'taxonomy';
7767
		    $info[ 'field_parent' ] = 'parent';
7768
		    $info[ 'field_parent_select' ] = '`tt`.`' . $info[ 'field_parent' ] . '`';
7769
7770
            if ( ! empty( $wpdb->termmeta ) ) {
7771
                $info[ 'meta_table' ] = $wpdb->termmeta;
7772
7773
                $info[ 'meta_field_id' ] = 'term_id';
7774
                $info[ 'meta_field_index' ] = 'meta_key';
7775
                $info[ 'meta_field_value' ] = 'meta_value';
7776
            }
7777
7778
		    if ( 'nav_menu' == $object_type )
7779
			    $object = 'nav_menu';
7780
		    elseif ( 'post_format' == $object_type )
7781
			    $object = 'post_format';
7782
7783
		    if ( empty( $name ) ) {
7784
			    $prefix = 'taxonomy-';
7785
7786
			    // Make sure we actually have the prefix before trying anything with the name
7787
			    if ( 0 === strpos( $object_type, $prefix ) )
7788
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7789
		    }
7790
7791
		    if ( !in_array( $object_type, array( 'nav_menu', 'post_format' ) ) )
7792
			    $object_type = 'taxonomy';
7793
7794
		    $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7795
7796
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $taxonomy, true, false );
7797
7798
		    $taxonomy_object = get_taxonomy( $taxonomy );
7799
7800
		    if ( is_object( $taxonomy_object ) && $taxonomy_object->hierarchical )
7801
			    $info[ 'object_hierarchical' ] = true;
7802
7803
		    $info[ 'where' ] = array(
7804
			    'tt.taxonomy' => '`tt`.`' . $info[ 'field_type' ] . '` = "' . $taxonomy . '"'
7805
		    );
7806
7807
            /*
7808
             * @todo wpml-comp WPML API call for is_translated_taxononomy
7809
             * @todo wpml-comp Check if WPML filters can be applied afterwards
7810
             */
7811
		    // WPML Support
7812
		    if ( is_object( $sitepress ) && !empty( $current_language ) && $sitepress->is_translated_taxonomy( $taxonomy ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
7813
			    $info[ 'join' ][ 'wpml_translations' ] = "
7814
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7815
                            ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id`
7816
                                AND `wpml_translations`.`element_type` = 'tax_{$taxonomy}'
7817
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7818
                    ";
7819
7820
			    $info[ 'join' ][ 'wpml_languages' ] = "
7821
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7822
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7823
                    ";
7824
7825
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7826
		    }
7827
		    // Polylang support
7828 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 ) ) {
7829
				$info[ 'join' ][ 'polylang_languages' ] = "
7830
					LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7831
						ON `polylang_languages`.`object_id` = `t`.`term_id`
7832
							AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tl_tt_id}
7833
				";
7834
7835
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7836
		    }
7837
7838
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7839
	    }
7840
	    elseif ( 'user' == $object_type || 'user' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7841
		    $info[ 'table' ] = $wpdb->users;
7842
		    $info[ 'meta_table' ] = $wpdb->usermeta;
7843
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_user';
7844
7845
		    $info[ 'field_id' ] = 'ID';
7846
		    $info[ 'field_index' ] = 'display_name';
7847
		    $info[ 'field_slug' ] = 'user_nicename';
7848
7849
		    $info[ 'meta_field_id' ] = 'user_id';
7850
		    $info[ 'meta_field_index' ] = 'meta_key';
7851
		    $info[ 'meta_field_value' ] = 'meta_value';
7852
7853
		    $info[ 'where' ] = array(
7854
			    'user_status' => '`t`.`user_status` = 0'
7855
		    );
7856
7857
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7858
	    }
7859
	    elseif ( 'comment' == $object_type || 'comment' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7860
		    //$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...
7861
7862
		    $info[ 'table' ] = $wpdb->comments;
7863
		    $info[ 'meta_table' ] = $wpdb->commentmeta;
7864
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_comment';
7865
7866
		    $info[ 'field_id' ] = 'comment_ID';
7867
		    $info[ 'field_index' ] = 'comment_date';
7868
		    $info[ 'field_type' ] = 'comment_type';
7869
		    $info[ 'field_parent' ] = 'comment_parent';
7870
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7871
7872
		    $info[ 'meta_field_id' ] = 'comment_id';
7873
		    $info[ 'meta_field_index' ] = 'meta_key';
7874
		    $info[ 'meta_field_value' ] = 'meta_value';
7875
7876
		    $object = 'comment';
7877
7878
		    $comment_type = ( empty( $object ) ? $name : $object );
7879
7880
		    $comment_type_clause = '`t`.`' . $info[ 'field_type' ] . '` = "' . $comment_type . '"';
7881
7882
		    if ( 'comment' == $comment_type ) {
7883
			    $comment_type_clause = '( ' . $comment_type_clause . ' OR `t`.`' . $info[ 'field_type' ] . '` = "" )';
7884
		    }
7885
7886
		    $info[ 'where' ] = array(
7887
			    'comment_approved' => '`t`.`comment_approved` = 1',
7888
			    'comment_type' => $comment_type_clause
7889
		    );
7890
7891
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` DESC, `t`.`' . $info[ 'field_id' ] . '`';
7892
	    }
7893 View Code Duplication
	    elseif ( in_array( $object_type, array( 'option', 'settings' ) ) || 'settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7894
		    $info[ 'table' ] = $wpdb->options;
7895
		    $info[ 'meta_table' ] = $wpdb->options;
7896
7897
		    $info[ 'field_id' ] = 'option_id';
7898
		    $info[ 'field_index' ] = 'option_name';
7899
7900
		    $info[ 'meta_field_id' ] = 'option_id';
7901
		    $info[ 'meta_field_index' ] = 'option_name';
7902
		    $info[ 'meta_field_value' ] = 'option_value';
7903
7904
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7905
	    }
7906 View Code Duplication
	    elseif ( is_multisite() && ( in_array( $object_type, array( 'site_option', 'site_settings' ) ) || 'site_settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) ) {
7907
		    $info[ 'table' ] = $wpdb->sitemeta;
7908
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7909
7910
		    $info[ 'field_id' ] = 'site_id';
7911
		    $info[ 'field_index' ] = 'meta_key';
7912
7913
		    $info[ 'meta_field_id' ] = 'site_id';
7914
		    $info[ 'meta_field_index' ] = 'meta_key';
7915
		    $info[ 'meta_field_value' ] = 'meta_value';
7916
7917
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7918
	    }
7919
	    elseif ( is_multisite() && 'network' == $object_type ) { // Network = Site
7920
		    $info[ 'table' ] = $wpdb->site;
7921
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7922
7923
		    $info[ 'field_id' ] = 'id';
7924
		    $info[ 'field_index' ] = 'domain';
7925
7926
		    $info[ 'meta_field_id' ] = 'site_id';
7927
		    $info[ 'meta_field_index' ] = 'meta_key';
7928
		    $info[ 'meta_field_value' ] = 'meta_value';
7929
7930
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7931
	    }
7932
	    elseif ( is_multisite() && 'site' == $object_type ) { // Site = Blog
7933
		    $info[ 'table' ] = $wpdb->blogs;
7934
7935
		    $info[ 'field_id' ] = 'blog_id';
7936
		    $info[ 'field_index' ] = 'domain';
7937
		    $info[ 'field_type' ] = 'site_id';
7938
7939
		    $info[ 'where' ] = array(
7940
			    'archived' => '`t`.`archived` = 0',
7941
			    'spam' => '`t`.`spam` = 0',
7942
			    'deleted' => '`t`.`deleted` = 0',
7943
			    'site_id' => '`t`.`' . $info[ 'field_type' ] . '` = ' . (int) get_current_site()->id
7944
		    );
7945
7946
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7947
	    }
7948
	    elseif ( 'table' == $object_type || 'table' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7949
		    $info[ 'table' ] = ( empty( $object ) ? $name : $object );
7950
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . $info[ 'table' ];
7951
7952
		    if ( !empty( $field ) && is_array( $field ) ) {
7953
			    $info[ 'table' ] = pods_var_raw( 'pick_table', pods_var_raw( 'options', $field, $field ) );
7954
			    $info[ 'field_id' ] = pods_var_raw( 'pick_table_id', pods_var_raw( 'options', $field, $field ) );
7955
			    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_var_raw( 'pick_table_index', pods_var_raw( 'options', $field, $field ) );
7956
		    }
7957
	    }
7958
7959
	    $info[ 'table' ] = pods_clean_name( $info[ 'table' ], false, false );
7960
	    $info[ 'meta_table' ] = pods_clean_name( $info[ 'meta_table' ], false, false );
7961
	    $info[ 'pod_table' ] = pods_clean_name( $info[ 'pod_table' ], false, false );
7962
7963
	    $info[ 'field_id' ] = pods_clean_name( $info[ 'field_id' ], false, false );
7964
	    $info[ 'field_index' ] = pods_clean_name( $info[ 'field_index' ], false, false );
7965
	    $info[ 'field_slug' ] = pods_clean_name( $info[ 'field_slug' ], false, false );
7966
7967
	    $info[ 'meta_field_id' ] = pods_clean_name( $info[ 'meta_field_id' ], false, false );
7968
	    $info[ 'meta_field_index' ] = pods_clean_name( $info[ 'meta_field_index' ], false, false );
7969
	    $info[ 'meta_field_value' ] = pods_clean_name( $info[ 'meta_field_value' ], false, false );
7970
7971 View Code Duplication
	    if ( empty( $info[ 'orderby' ] ) )
7972
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '`, `t`.`' . $info[ 'field_id' ] . '`';
7973
7974
	    if ( 'table' == pods_var_raw( 'storage', $info[ 'pod' ] ) && !in_array( $object_type, array( 'pod', 'table' ) ) ) {
7975
		    $info[ 'join' ][ 'd' ] = 'LEFT JOIN `' . $info[ 'pod_table' ] . '` AS `d` ON `d`.`id` = `t`.`' . $info[ 'field_id' ] . '`';
7976
		    //$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...
7977
	    }
7978
7979
	    if ( !empty( $info[ 'pod' ] ) && is_array( $info[ 'pod' ] ) )
7980
		    $info[ 'recurse' ] = true;
7981
7982
	    $info[ 'type' ] = $object_type;
7983
	    $info[ 'object_name' ] = $object;
7984
7985
	    if ( pods_api_cache() ) {
7986
		    if ( ! did_action( 'init' ) ) {
7987
			    $transient .= '_pre_init';
7988
		    }
7989
		    pods_transient_set( $transient, $info );
7990
	    }
7991
7992
7993
	    self::$table_info_cache[ $transient ] = apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
7994
7995
        return self::$table_info_cache[ $transient ];
7996
    }
7997
7998
    /**
7999
     * Export a package
8000
     *
8001
     * $params['pod'] string Pod Type IDs to export
8002
     * $params['template'] string Template IDs to export
8003
     * $params['podpage'] string Pod Page IDs to export
8004
     * $params['helper'] string Helper IDs to export
8005
     *
8006
     * @param array $params An associative array of parameters
8007
     *
8008
     * @return array|bool
8009
     *
8010
     * @since 1.9.0
8011
     * @deprecated 2.0
8012
     */
8013
    public function export_package ( $params ) {
8014
        if ( class_exists( 'Pods_Migrate_Packages' ) )
8015
            return Pods_Migrate_Packages::export( $params );
8016
8017
        return false;
8018
    }
8019
8020
    /**
8021
     * Replace an existing package
8022
     *
8023
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
8024
     *
8025
     * @return bool
8026
     *
8027
     * @since 1.9.8
8028
     * @deprecated 2.0
8029
     */
8030
    public function replace_package ( $data = false ) {
8031
        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...
8032
    }
8033
8034
    /**
8035
     * Import a package
8036
     *
8037
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
8038
     * @param bool $replace (optional) Replace existing items when found
8039
     *
8040
     * @return bool
8041
     *
8042
     * @since 1.9.0
8043
     * @deprecated 2.0
8044
     */
8045
    public function import_package ( $data = false, $replace = false ) {
8046
        if ( class_exists( 'Pods_Migrate_Packages' ) )
8047
            return Pods_Migrate_Packages::import( $data, $replace );
8048
8049
        return false;
8050
    }
8051
8052
    /**
8053
     * Validate a package
8054
     *
8055
     * @param array|string $data (optional) An associative array containing a package, or the json encoded package
8056
     * @param bool $output (optional)
8057
     *
8058
     * @return array|bool
8059
     *
8060
     * @since 1.9.0
8061
     * @deprecated 2.0
8062
     */
8063
    public function validate_package ( $data = false, $output = false ) {
8064
        return true;
8065
    }
8066
8067
    /**
8068
     * Import data from an array or a CSV file.
8069
     *
8070
     * @param mixed $import_data PHP associative array or CSV input
8071
     * @param bool $numeric_mode Use IDs instead of the name field when matching
8072
     * @param string $format Format of import data, options are php or csv
8073
     *
8074
     * @return array IDs of imported items
8075
     *
8076
     * @since 1.7.1
8077
     * @todo This needs some love and use of table_info etc for relationships
8078
     */
8079
    public function import ( $import_data, $numeric_mode = false, $format = null ) {
8080
        /**
8081
         * @var $wpdb wpdb
8082
         */
8083
        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...
8084
8085
        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...
8086
            $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...
8087
8088
        if ( 'csv' == $format && !is_array( $import_data ) ) {
8089
            $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...
8090
8091
            $import_data = $data[ 'items' ];
8092
        }
8093
8094
        pods_query( "SET NAMES utf8" );
8095
        pods_query( "SET CHARACTER SET utf8" );
8096
8097
        // Loop through the array of items
8098
        $ids = array();
8099
8100
        // Test to see if it's an array of arrays
8101
        if ( !is_array( @current( $import_data ) ) )
8102
            $import_data = array( $import_data );
8103
8104
        $pod = $this->load_pod( array( 'name' => $this->pod ) );
8105
8106
        if ( false === $pod )
8107
            return pods_error( __( 'Pod not found', 'pods' ), $this );
8108
8109
        $fields = array_merge( $pod[ 'fields' ], $pod[ 'object_fields' ] );
8110
8111
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
8112
8113
        foreach ( $import_data as $key => $data_row ) {
8114
            $data = array();
8115
8116
            // Loop through each field (use $fields so only valid fields get parsed)
8117
            foreach ( $fields as $field_name => $field_data ) {
8118
                if ( !isset( $data_row[ $field_name ] ) && !isset( $data_row[ $field_data[ 'label' ] ] ) )
8119
                    continue;
8120
8121
                $field_id = $field_data[ 'id' ];
8122
                $type = $field_data[ 'type' ];
8123
                $pick_object = isset( $field_data[ 'pick_object' ] ) ? $field_data[ 'pick_object' ] : '';
8124
                $pick_val = isset( $field_data[ 'pick_val' ] ) ?  $field_data[ 'pick_val' ] : '';
8125
8126
                if ( isset( $data_row[ $field_name] ) )
8127
                    $field_value = $data_row[ $field_name ];
8128
                else
8129
                    $field_value = $data_row[ $field_data[ 'label' ] ];
8130
8131
                if ( null !== $field_value && false !== $field_value && '' !== $field_value ) {
8132
                    if ( 'pick' == $type || in_array( $type, PodsForm::file_field_types() ) ) {
8133
                        $field_values = is_array( $field_value ) ? $field_value : array( $field_value );
8134
                        $pick_values = array();
8135
8136
                        foreach ( $field_values as $pick_value ) {
8137
                            if ( in_array( $type, PodsForm::file_field_types() ) || 'media' == $pick_object ) {
8138
                                $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'";
8139
8140 View Code Duplication
                                if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8141
                                    $where = "`ID` = " . pods_absint( $pick_value );
8142
8143
                                $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = 'attachment' AND {$where} ORDER BY `ID`", $this );
8144
8145
                                if ( !empty( $result ) )
8146
                                    $pick_values[] = $result[ 0 ]->id;
8147
                            }
8148
                            // @todo This could and should be abstracted better and simplified
8149
                            elseif ( 'pick' == $type ) {
8150
                                $related_pod = false;
8151
8152
                                if ( 'pod' == $pick_object )
8153
                                    $related_pod = $this->load_pod( array( 'name' => $pick_val, 'table_info' => true ), false );
8154
8155
                                if ( empty( $related_pod ) ) {
8156
                                    $related_pod = array(
8157
                                        'id' => 0,
8158
                                        'type' => $pick_object
8159
                                    );
8160
                                }
8161
8162
                                if ( in_array( 'taxonomy', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8163
                                    $where = "`t`.`name` = '" . pods_sanitize( $pick_value ) . "'";
8164
8165 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8166
                                        $where = "`tt`.`term_id` = " . pods_absint( $pick_value );
8167
8168
                                    $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` LIMIT 1", $this );
8169
8170
                                    if ( !empty( $result ) )
8171
                                        $pick_values[] = $result[ 0 ]->id;
8172
                                }
8173
                                elseif ( in_array( 'post_type', array( $pick_object, $related_pod[ 'type' ] ) ) || in_array( 'media', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8174
                                    $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'";
8175
8176 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8177
                                        $where = "`ID` = " . pods_absint( $pick_value );
8178
8179
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = '{$pick_val}' AND {$where} ORDER BY `ID` LIMIT 1", $this );
8180
8181
                                    if ( !empty( $result ) )
8182
                                        $pick_values[] = $result[ 0 ]->id;
8183
                                }
8184
                                elseif ( in_array( 'user', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8185
                                    $where = "`user_login` = '" . pods_sanitize( $pick_value ) . "'";
8186
8187 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8188
                                        $where = "`ID` = " . pods_absint( $pick_value );
8189
8190
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->users}` WHERE {$where} ORDER BY `ID` LIMIT 1", $this );
8191
8192
                                    if ( !empty( $result ) )
8193
                                        $pick_values[] = $result[ 0 ]->id;
8194
                                }
8195
                                elseif ( in_array( 'comment', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8196
                                    $where = "`comment_ID` = " . pods_absint( $pick_value );
8197
8198
                                    $result = pods_query( "SELECT `comment_ID` AS `id` FROM `{$wpdb->comments}` WHERE {$where} ORDER BY `ID` LIMIT 1", $this );
8199
8200
                                    if ( !empty( $result ) )
8201
                                        $pick_values[] = $result[ 0 ]->id;
8202
                                }
8203
                                elseif ( in_array( $pick_object, $simple_tableless_objects ) )
8204
                                    $pick_values[] = $pick_value;
8205
                                elseif ( !empty( $related_pod[ 'id' ] ) ) {
8206
                                    $where = "`" . $related_pod[ 'field_index' ] . "` = '" . pods_sanitize( $pick_value ) . "'";
8207
8208
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8209
                                        $where = "`" . $related_pod[ 'field_id' ] . "` = " . pods_absint( $pick_value );
8210
8211
                                    $result = pods_query( "SELECT `" . $related_pod[ 'field_id' ] . "` AS `id` FROM `" . $related_pod[ 'table' ] . "` WHERE {$where} ORDER BY `" . $related_pod[ 'field_id' ] . "` LIMIT 1", $this );
8212
8213
                                    if ( !empty( $result ) )
8214
                                        $pick_values[] = $result[ 0 ]->id;
8215
                                }
8216
                            }
8217
                        }
8218
8219
                        $field_value = implode( ',', $pick_values );
8220
                    }
8221
8222
                    $data[ $field_name ] = $field_value;
8223
                }
8224
            }
8225
8226
            if ( !empty( $data ) ) {
8227
                $params = array(
8228
                    'pod' => $this->pod,
8229
                    'data' => $data
8230
                );
8231
8232
                $ids[] = $this->save_pod_item( $params );
8233
            }
8234
        }
8235
8236
        return $ids;
8237
    }
8238
8239
    /**
8240
     * Export data from a Pod
8241
     *
8242
     * @param string|object $pod The pod name or Pods object
8243
     * @param array $params An associative array of parameters
8244
     *
8245
     * @return array Data arrays of all exported pod items
8246
     * @since 1.7.1
8247
     */
8248
    public function export ( $pod = null, $params = null ) {
8249
8250
        if ( empty( $pod ) ) {
8251
            $pod = $this->pod;
8252
        }
8253
8254
        $find = array(
8255
            'limit' => -1,
8256
            'search' => false,
8257
            'pagination' => false
8258
        );
8259
8260
        if ( !empty( $params ) && isset( $params[ 'params' ] ) ) {
8261
            $find = array_merge( $find, (array) $params[ 'params' ] );
8262
8263
            unset( $params[ 'params' ] );
8264
8265
            $pod = pods( $pod, $find );
8266
        }
8267
        elseif ( !is_object( $pod ) ) {
8268
            $pod = pods( $pod, $find );
8269
        }
8270
8271
        $data = array();
8272
8273
        while ( $pod->fetch() ) {
8274
            $data[ $pod->id() ] = $this->export_pod_item( $params, $pod );
8275
        }
8276
8277
        $data = $this->do_hook( 'export', $data, $pod->pod, $pod );
8278
8279
        return $data;
8280
    }
8281
8282
    /**
8283
     * Convert CSV to a PHP array
8284
     *
8285
     * @param string $data The CSV input
8286
     *
8287
     * @return array
8288
     * @since 1.7.1
8289
     *
8290
     * @deprecated 2.3.5
8291
     */
8292
    public function csv_to_php ( $data, $delimiter = ',' ) {
8293
        pods_deprecated( "PodsAPI->csv_to_php", '2.3.5' );
8294
8295
        $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...
8296
8297
        return $data[ 'items' ];
8298
    }
8299
8300
    /**
8301
     * Clear Pod-related cache
8302
     *
8303
     * @param array $pod
8304
     *
8305
     * @return void
8306
     *
8307
     * @since 2.0
8308
     */
8309
    public function cache_flush_pods ( $pod = null ) {
8310
        /**
8311
         * @var $wpdb wpdb
8312
         */
8313
        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...
8314
8315
        pods_transient_clear( 'pods' );
8316
        pods_transient_clear( 'pods_components' );
8317
8318
        if ( null !== $pod && is_array( $pod ) ) {
8319
            pods_transient_clear( 'pods_pod_' . $pod[ 'name' ] );
8320
            pods_cache_clear( $pod[ 'name' ], 'pods-class' );
8321
8322
            foreach ( $pod[ 'fields' ] as $field ) {
8323
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
8324
            }
8325
8326
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) )
8327
                pods_transient_clear( 'pods_wp_cpt_ct' );
8328
        }
8329
        else
8330
            pods_transient_clear( 'pods_wp_cpt_ct' );
8331
8332
        // Delete transients in the database
8333
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" );
8334
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" );
8335
8336
        // Delete Pods Options Cache in the database
8337
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_pods_option_%'" );
8338
8339
        pods_cache_clear( true );
8340
8341
        pods_transient_set( 'pods_flush_rewrites', 1 );
8342
8343
        do_action( 'pods_cache_flushed' );
8344
    }
8345
8346
    /**
8347
     * Process a Pod-based form
8348
     *
8349
     * @param mixed $params
8350
     * @param object $obj Pod object
8351
     * @param array $fields Fields being submitted in form ( key => settings )
8352
     * @param string $thank_you URL to send to upon success
8353
     *
8354
     * @return mixed
8355
     *
8356
     * @since 2.0
8357
     */
8358
    public function process_form ( $params, $obj = null, $fields = null, $thank_you = null ) {
8359
        $this->display_errors = false;
8360
8361
        $form = null;
8362
8363
        $nonce = pods_var( '_pods_nonce', $params );
8364
        $pod = pods_var( '_pods_pod', $params );
8365
        $id = pods_var( '_pods_id', $params );
8366
        $uri = pods_var( '_pods_uri', $params );
8367
        $form = pods_var( '_pods_form', $params );
8368
        $location = pods_var( '_pods_location', $params );
8369
8370
        if ( is_object( $obj ) ) {
8371
            $pod = $obj->pod;
8372
            $id = $obj->id();
8373
        }
8374
8375
        if ( !empty( $fields ) ) {
8376
            $fields = array_keys( $fields );
8377
            $form = implode( ',', $fields );
8378
        }
8379
        else
8380
            $fields = explode( ',', $form );
8381
8382
        if ( empty( $nonce ) || empty( $pod ) || empty( $uri ) || empty( $fields ) )
8383
            return pods_error( __( 'Invalid submission', 'pods' ), $this );
8384
8385
        $uid = @session_id();
8386
8387
        if ( is_user_logged_in() )
8388
            $uid = 'user_' . get_current_user_id();
8389
8390
		$field_hash = wp_create_nonce( 'pods_fields_' . $form );
8391
8392
        $action = 'pods_form_' . $pod . '_' . $uid . '_' . $id . '_' . $uri . '_' . $field_hash;
8393
8394
        if ( empty( $uid ) )
8395
            return pods_error( __( 'Access denied for your session, please refresh and try again.', 'pods' ), $this );
8396
8397
        if ( false === wp_verify_nonce( $nonce, $action ) )
8398
            return pods_error( __( 'Access denied, please refresh and try again.', 'pods' ), $this );
8399
8400
        $data = array();
8401
8402
        foreach ( $fields as $field ) {
8403
            $data[ $field ] = pods_var_raw( 'pods_field_' . $field, $params, '' );
8404
        }
8405
8406
        $params = array(
8407
            'pod' => $pod,
8408
            'id' => $id,
8409
            'data' => $data,
8410
            'from' => 'process_form',
8411
			'location' => $location
8412
        );
8413
8414
        $id = $this->save_pod_item( $params );
8415
8416
	    /**
8417
	     * Fires after the form has been processed and save_pod_item has run.
8418
	     *
8419
	     * @param int       $id     Item ID.
8420
	     * @param array     $params save_pod_item parameters.
8421
	     * @param null|Pods $obj    Pod object (if set).
8422
	     */
8423
        do_action( 'pods_api_processed_form', $id, $params, $obj );
8424
8425
        if ( 0 < $id && !empty( $thank_you ) ) {
8426
            $thank_you = str_replace( 'X_ID_X', $id, $thank_you );
8427
8428
            pods_redirect( $thank_you );
8429
        }
8430
8431
        return $id;
8432
    }
8433
8434
    /**
8435
     * Handle filters / actions for the class
8436
     *
8437
     * @since 2.0
8438
     */
8439 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...
8440
        $args = func_get_args();
8441
        if ( empty( $args ) )
8442
            return false;
8443
        $name = array_shift( $args );
8444
        return pods_do_hook( "api", $name, $args, $this );
8445
    }
8446
8447
    /**
8448
     * Handle variables that have been deprecated
8449
     *
8450
     * @since 2.0
8451
     */
8452
    public function __get ( $name ) {
8453
        $name = (string) $name;
8454
8455 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8456
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8457
            $this->deprecated = new PodsAPI_Deprecated( $this );
8458
        }
8459
8460
        $var = null;
8461
8462
        if ( isset( $this->deprecated->{$name} ) ) {
8463
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8464
8465
            $var = $this->deprecated->{$name};
8466
        }
8467
        else
8468
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8469
8470
        return $var;
8471
    }
8472
8473
    /**
8474
     * Handle methods that have been deprecated
8475
     *
8476
     * @since 2.0
8477
     */
8478
    public function __call ( $name, $args ) {
8479
        $name = (string) $name;
8480
8481 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8482
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8483
            $this->deprecated = new PodsAPI_Deprecated( $this );
8484
        }
8485
8486
        if ( method_exists( $this->deprecated, $name ) )
8487
            return call_user_func_array( array( $this->deprecated, $name ), $args );
8488
        else
8489
            pods_deprecated( "PodsAPI::{$name}", '2.0' );
8490
    }
8491
}
8492