Completed
Push — 2.x ( 7fcf3e...a4c7e7 )
by Scott Kingsley
09:05 queued 01:59
created

PodsAPI::load_pods()   F

Complexity

Conditions 99
Paths > 20000

Size

Total Lines 263
Code Lines 174

Duplication

Lines 37
Ratio 14.07 %
Metric Value
dl 37
loc 263
rs 2
cc 99
eloc 174
nc 429496.7295
nop 1

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;
1 ignored issue
show
Coding Style introduced by
We recommend specifying an explicit visibility for the field $instance.
Loading history...
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();
1 ignored issue
show
Coding Style introduced by
We recommend specifying an explicit visibility for the field $instances.
Loading history...
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
        } else {
653
			if ( !$conflicted )
654
				pods_no_conflict_off( 'taxonomy' );
655
656
			return pods_error( __( 'Taxonomy term data is required but is either invalid or empty', 'pods' ), $this );
657
		}
658
659
        if ( is_wp_error( $term_data['term_id'] ) ) {
660
            if ( !$conflicted )
661
                pods_no_conflict_off( 'taxonomy' );
662
663
            /**
664
             * @var $term_error WP_Error
665
             */
666
            $term_error = $term_data[ 'term_id' ];
667
668
            return pods_error( $term_error->get_error_message(), $this );
669
        }
670
        elseif ( is_array( $term_data['term_id'] ) )
671
            $term_data['term_id'] = $term_data['term_id'][ 'term_id' ];
672
673
        $this->save_term_meta( $term_data['term_id'], $term_meta, $strict, $fields );
674
675
        if ( !$conflicted )
676
            pods_no_conflict_off( 'taxonomy' );
677
678
        return $term_data['term_id'];
679
    }
680
681
    /**
682
     * Save a term's meta
683
     *
684
     * @param int $id Term ID
685
     * @param array $term_meta All meta to be saved (set value to null to delete)
686
     * @param bool $strict Whether to delete previously saved meta not in $term_meta
687
     * @param array $fields (optional) The array of fields and their options, for further processing with
688
     *
689
     * @return int Id of the term with the meta
690
     *
691
     * @since 2.0
692
     */
693 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...
694
        if ( ! function_exists( 'get_term_meta' ) ) {
695
        	return $id;
696
        }
697
698
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
699
700
        $conflicted = pods_no_conflict_check( 'taxonomy' );
701
702
        if ( !$conflicted )
703
            pods_no_conflict_on( 'taxonomy' );
704
705
        if ( !is_array( $term_meta ) )
706
            $term_meta = array();
707
708
        $id = (int) $id;
709
710
        $meta = get_term_meta( $id );
711
712
        foreach ( $meta as $k => $value ) {
713
            if ( is_array( $value ) && 1 == count( $value ) )
714
                $meta[ $k ] = current( $value );
715
        }
716
717
        foreach ( $term_meta as $meta_key => $meta_value ) {
718
            if ( null === $meta_value || ( $strict && '' === $term_meta[ $meta_key ] ) ) {
719
                $old_meta_value = '';
720
721
                if ( isset( $meta[ $meta_key ] ) )
722
                    $old_meta_value = $meta[ $meta_key ];
723
724
                delete_term_meta( $id, $meta_key, $old_meta_value );
725
            }
726
            else {
727
				$simple = false;
728
729
				if ( isset( $fields[ $meta_key ] ) ) {
730
					$field_data = $fields[ $meta_key ];
731
732
					$simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
733
				}
734
735
				if ( $simple ) {
736
					delete_term_meta( $id, $meta_key );
737
738
					update_term_meta( $id, '_pods_' . $meta_key, $meta_value );
739
740
					if ( ! is_array( $meta_value ) ) {
741
						$meta_value = array( $meta_value );
742
					}
743
744
					foreach ( $meta_value as $value ) {
745
						add_term_meta( $id, $meta_key, $value );
746
					}
747
				}
748
				else {
749
                	update_term_meta( $id, $meta_key, $meta_value );
750
				}
751
			}
752
        }
753
754
        if ( $strict ) {
755
            foreach ( $meta as $meta_key => $meta_value ) {
756
                if ( !isset( $term_meta[ $meta_key ] ) )
757
                    delete_term_meta( $id, $meta_key, $meta_value );
758
            }
759
        }
760
761
        if ( !$conflicted )
762
            pods_no_conflict_off( 'taxonomy' );
763
764
        return $id;
765
    }
766
767
    /**
768
     * Save a set of options
769
     *
770
     * @param string $setting Setting group name
771
     * @param array $option_data All option data to be saved
772
     * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
773
     *
774
     * @return bool
775
     *
776
     * @since 2.3
777
     */
778
    public function save_setting ( $setting, $option_data, $sanitized = false ) {
779 View Code Duplication
        if ( !is_array( $option_data ) || empty( $option_data ) )
780
            return pods_error( __( 'Setting data is required but is either invalid or empty', 'pods' ), $this );
781
782
        $conflicted = pods_no_conflict_check( 'settings' );
783
784
        if ( !$conflicted )
785
            pods_no_conflict_on( 'settings' );
786
787
        if ( $sanitized )
788
            $option_data = pods_unsanitize( $option_data );
789
790
        foreach ( $option_data as $option => $value ) {
791
            if ( !empty( $setting ) )
792
                $option = $setting . '_' . $option;
793
794
            update_option( $option, $value );
795
        }
796
797
        if ( !$conflicted )
798
            pods_no_conflict_off( 'settings' );
799
800
        return true;
801
    }
802
803
    /**
804
     * Rename a WP object's type
805
     *
806
     * @param string $object_type Object type: post|taxonomy|comment|setting
807
     * @param string $old_name The old name
808
     * @param string $new_name The new name
809
     *
810
     * @return bool
811
     *
812
     * @since 2.0
813
     */
814
    public function rename_wp_object_type ( $object_type, $old_name, $new_name ) {
815
        /**
816
         * @var $wpdb wpdb
817
         */
818
        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...
819
820
        if ( 'post_type' == $object_type )
821
            $object_type = 'post';
822
823
        if ( 'post' == $object_type ) {
824
            pods_query( "UPDATE `{$wpdb->posts}` SET `post_type` = %s WHERE `post_type` = %s", array(
825
                $new_name,
826
                $old_name
827
            ) );
828
        }
829
        elseif ( 'taxonomy' == $object_type ) {
830
            pods_query( "UPDATE `{$wpdb->term_taxonomy}` SET `taxonomy` = %s WHERE `taxonomy` = %s", array(
831
                $new_name,
832
                $old_name
833
            ) );
834
        }
835
        elseif ( 'comment' == $object_type ) {
836
            pods_query( "UPDATE `{$wpdb->comments}` SET `comment_type` = %s WHERE `comment_type` = %s", array(
837
                $new_name,
838
                $old_name
839
            ) );
840
        }
841
        elseif ( 'settings' == $object_type ) {
842
            pods_query( "UPDATE `{$wpdb->options}` SET `option_name` = REPLACE( `option_name`, %s, %s ) WHERE `option_name` LIKE '" . pods_sanitize_like( $old_name ) . "_%'", array(
843
                $new_name . '_',
844
                $old_name . '_'
845
            ) );
846
        }
847
848
        return true;
849
    }
850
851
    /**
852
     * Get a list of core WP object fields for a specific object
853
     *
854
     * @param string $object The pod type to look for, possible values: post_type, user, comment, taxonomy
855
     * @param array $pod Array of Pod data
856
     * @param boolean $refresh Whether to force refresh the information
857
     *
858
     * @return array Array of fields
859
     *
860
     * @since 2.0
861
     */
862
    public function get_wp_object_fields ( $object = 'post_type', $pod = null, $refresh = false ) {
863
        $pod_name = pods_var_raw( 'name', $pod, $object, null, true );
864
865
		if ( 'media' == $pod_name ) {
866
			$object = 'post_type';
867
			$pod_name = 'attachment';
868
		}
869
870
        $fields = false;
871
872
        if ( pods_api_cache() )
873
            $fields = pods_transient_get( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ) );
874
875
        if ( false !== $fields && !$refresh )
876
            return $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
877
878
        $fields = array();
879
880
        if ( 'post_type' == $object ) {
881
            $fields = array(
882
	            'ID' => array(
883
		            'name' => 'ID',
884
		            'label' => 'ID',
885
		            'type' => 'number',
886
		            'alias' => array( 'id' ),
887
	                'options' => array(
888
                        'number_format' => '9999.99'
889
	                )
890
	            ),
891
                'post_title' => array(
892
                    'name' => 'post_title',
893
                    'label' => 'Title',
894
                    'type' => 'text',
895
                    'alias' => array( 'title', 'name' ),
896
                    'options' => array(
897
                        'display_filter' => 'the_title',
898
                        'display_filter_args' => array( 'post_ID' )
899
                    )
900
                ),
901
                'post_content' => array(
902
                    'name' => 'post_content',
903
                    'label' => 'Content',
904
                    'type' => 'wysiwyg',
905
                    'alias' => array( 'content' ),
906
                    'options' => array(
907
                        'wysiwyg_allowed_html_tags' => '',
908
                        'display_filter' => 'the_content',
909
                        'pre_save' => 0
910
                    )
911
                ),
912
                'post_excerpt' => array(
913
                    'name' => 'post_excerpt',
914
                    'label' => 'Excerpt',
915
                    'type' => 'paragraph',
916
                    'alias' => array( 'excerpt' ),
917
                    'options' => array(
918
                        'paragraph_allow_html' => 1,
919
                        'paragraph_allowed_html_tags' => '',
920
                        'display_filter' => 'the_excerpt',
921
                        'pre_save' => 0
922
                    )
923
                ),
924
                'post_author' => array(
925
                    'name' => 'post_author',
926
                    'label' => 'Author',
927
                    'type' => 'pick',
928
                    'alias' => array( 'author' ),
929
                    'pick_object' => 'user',
930
                    'options' => array(
931
                        'pick_format_type' => 'single',
932
                        'pick_format_single' => 'autocomplete',
933
                        'default_value' => '{@user.ID}'
934
                    )
935
                ),
936
                'post_date' => array(
937
                    'name' => 'post_date',
938
                    'label' => 'Publish Date',
939
                    'type' => 'datetime',
940
                    'alias' => array( 'created', 'date' )
941
                ),
942
                'post_date_gmt' => array(
943
                    'name' => 'post_date_gmt',
944
                    'label' => 'Publish Date (GMT)',
945
                    'type' => 'datetime',
946
                    'alias' => array(),
947
                    'hidden' => true
948
                ),
949
                'post_status' => array(
950
                    'name' => 'post_status',
951
                    'label' => 'Status',
952
                    'type' => 'pick',
953
                    'pick_object' => 'post-status',
954
                    'default' => $this->do_hook( 'default_status_' . $pod_name, pods_var( 'default_status', pods_var_raw( 'options', $pod ), 'draft', null, true ), $pod ),
955
                    'alias' => array( 'status' )
956
                ),
957
                'comment_status' => array(
958
                    'name' => 'comment_status',
959
                    'label' => 'Comment Status',
960
                    'type' => 'text',
961
                    'default' => get_option( 'default_comment_status', 'open' ),
962
                    'alias' => array(),
963
                    'data' => array(
964
                        'open' => __( 'Open', 'pods' ),
965
                        'closed' => __( 'Closed', 'pods' )
966
                    )
967
                ),
968
                'ping_status' => array(
969
                    'name' => 'ping_status',
970
                    'label' => 'Ping Status',
971
                    'default' => get_option( 'default_ping_status', 'open' ),
972
                    'type' => 'text',
973
                    'alias' => array(),
974
                    'data' => array(
975
                        'open' => __( 'Open', 'pods' ),
976
                        'closed' => __( 'Closed', 'pods' )
977
                    )
978
                ),
979
                'post_password' => array(
980
                    'name' => 'post_password',
981
                    'label' => 'Password',
982
                    'type' => 'text',
983
                    'alias' => array()
984
                ),
985
                'post_name' => array(
986
                    'name' => 'post_name',
987
                    'label' => 'Permalink',
988
                    'type' => 'slug',
989
                    'alias' => array( 'slug', 'permalink' )
990
                ),
991
                'to_ping' => array(
992
                    'name' => 'to_ping',
993
                    'label' => 'To Ping',
994
                    'type' => 'text',
995
                    'alias' => array(),
996
                    'hidden' => true
997
                ),
998
                'pinged' => array(
999
                    'name' => 'pinged',
1000
                    'label' => 'Pinged',
1001
                    'type' => 'text',
1002
                    'alias' => array(),
1003
                    'hidden' => true
1004
                ),
1005
                'post_modified' => array(
1006
                    'name' => 'post_modified',
1007
                    'label' => 'Last Modified Date',
1008
                    'type' => 'datetime',
1009
                    'alias' => array( 'modified' ),
1010
                    'hidden' => true
1011
                ),
1012
                'post_modified_gmt' => array(
1013
                    'name' => 'post_modified_gmt',
1014
                    'label' => 'Last Modified Date (GMT)',
1015
                    'type' => 'datetime',
1016
                    'alias' => array(),
1017
                    'hidden' => true
1018
                ),
1019
                'post_content_filtered' => array(
1020
                    'name' => 'post_content_filtered',
1021
                    'label' => 'Content (filtered)',
1022
                    'type' => 'paragraph',
1023
                    'alias' => array(),
1024
                    'hidden' => true,
1025
                    'options' => array(
1026
                        'paragraph_allow_html' => 1,
1027
                        'paragraph_oembed' => 1,
1028
                        'paragraph_wptexturize' => 1,
1029
                        'paragraph_convert_chars' => 1,
1030
                        'paragraph_wpautop' => 1,
1031
                        'paragraph_allow_shortcode' => 1,
1032
                        'paragraph_allowed_html_tags' => ''
1033
                    )
1034
                ),
1035
                'post_parent' => array(
1036
                    'name' => 'post_parent',
1037
                    'label' => 'Parent',
1038
                    'type' => 'pick',
1039
                    'pick_object' => 'post_type',
1040
                    'pick_val' => '__current__',
1041
                    'alias' => array( 'parent' ),
1042
                    'data' => array(),
1043
                    'hidden' => true
1044
                ),
1045
                'guid' => array(
1046
                    'name' => 'guid',
1047
                    'label' => 'GUID',
1048
                    'type' => 'text',
1049
                    'alias' => array(),
1050
                    'hidden' => true
1051
                ),
1052
                'menu_order' => array(
1053
                    'name' => 'menu_order',
1054
                    'label' => 'Menu Order',
1055
                    'type' => 'number',
1056
                    'alias' => array(),
1057
	                'options' => array(
1058
                        'number_format' => '9999.99'
1059
	                )
1060
                ),
1061
                'post_type' => array(
1062
                    'name' => 'post_type',
1063
                    'label' => 'Type',
1064
                    'type' => 'text',
1065
                    'alias' => array( 'type' ),
1066
                    'hidden' => true
1067
                ),
1068
                'post_mime_type' => array(
1069
                    'name' => 'post_mime_type',
1070
                    'label' => 'Mime Type',
1071
                    'type' => 'text',
1072
                    'alias' => array(),
1073
                    'hidden' => true
1074
                ),
1075
                'comment_count' => array(
1076
                    'name' => 'comment_count',
1077
                    'label' => 'Comment Count',
1078
                    'type' => 'number',
1079
                    'alias' => array(),
1080
                    'hidden' => true
1081
                )
1082
            );
1083
1084
            if ( !empty( $pod ) ) {
1085
                $taxonomies = get_object_taxonomies( $pod_name, 'objects' );
1086
1087
                foreach ( $taxonomies as $taxonomy ) {
1088
                    $fields[ $taxonomy->name ] = array(
1089
                        'name' => $taxonomy->name,
1090
                        'label' => $taxonomy->labels->name,
1091
                        'type' => 'taxonomy',
1092
						'pick_object' => 'taxonomy',
1093
						'pick_val' => $taxonomy->name,
1094
                        'alias' => array(),
1095
                        'hidden' => true,
1096
						'options' => array(
1097
							'taxonomy_format_type' => 'multi'
1098
						)
1099
                    );
1100
                }
1101
            }
1102
        }
1103
        elseif ( 'user' == $object ) {
1104
            $fields = array(
1105
	            'ID' => array(
1106
		            'name' => 'ID',
1107
		            'label' => 'ID',
1108
		            'type' => 'number',
1109
		            'alias' => array( 'id' ),
1110
	                'options' => array(
1111
                        'number_format' => '9999.99'
1112
	                )
1113
	            ),
1114
                'user_login' => array(
1115
                    'name' => 'user_login',
1116
                    'label' => 'Title',
1117
                    'type' => 'text',
1118
                    'alias' => array( 'login' ),
1119
                    'options' => array(
1120
                        'required' => 1
1121
                    )
1122
                ),
1123
                'user_nicename' => array(
1124
                    'name' => 'user_nicename',
1125
                    'label' => 'Permalink',
1126
                    'type' => 'slug',
1127
                    'alias' => array( 'nicename', 'slug', 'permalink' )
1128
                ),
1129
                'display_name' => array(
1130
                    'name' => 'display_name',
1131
                    'label' => 'Display Name',
1132
                    'type' => 'text',
1133
                    'alias' => array( 'title', 'name' )
1134
                ),
1135
                'user_pass' => array(
1136
                    'name' => 'user_pass',
1137
                    'label' => 'Password',
1138
                    'type' => 'text',
1139
                    'alias' => array( 'password', 'pass' ),
1140
                    'options' => array(
1141
                        'required' => 1,
1142
                        'text_format_type' => 'password'
1143
                    )
1144
                ),
1145
                'user_email' => array(
1146
                    'name' => 'user_email',
1147
                    'label' => 'E-mail',
1148
                    'type' => 'text',
1149
                    'alias' => array( 'email' ),
1150
                    'options' => array(
1151
                        'required' => 1,
1152
                        'text_format_type' => 'email'
1153
                    )
1154
                ),
1155
                'user_url' => array(
1156
                    'name' => 'user_url',
1157
                    'label' => 'URL',
1158
                    'type' => 'text',
1159
                    'alias' => array( 'url', 'website' ),
1160
                    'options' => array(
1161
                        'required' => 0,
1162
                        'text_format_type' => 'website',
1163
                        'text_format_website' => 'normal'
1164
                    )
1165
                ),
1166
                'user_registered' => array(
1167
                    'name' => 'user_registered',
1168
                    'label' => 'Registration Date',
1169
                    'type' => 'date',
1170
                    'alias' => array( 'created', 'date', 'registered' ),
1171
                    'options' => array(
1172
                        'date_format_type' => 'datetime'
1173
                    )
1174
                )
1175
            );
1176
        }
1177
        elseif ( 'comment' == $object ) {
1178
            $fields = array(
1179
	            'comment_ID' => array(
1180
		            'name' => 'comment_ID',
1181
		            'label' => 'ID',
1182
		            'type' => 'number',
1183
		            'alias' => array( 'id', 'ID', 'comment_id' ),
1184
	                'options' => array(
1185
                        'number_format' => '9999.99'
1186
	                )
1187
	            ),
1188
                'comment_content' => array(
1189
                    'name' => 'comment_content',
1190
                    'label' => 'Content',
1191
                    'type' => 'wysiwyg',
1192
                    'alias' => array( 'content' )
1193
                ),
1194
                'comment_approved' => array(
1195
                    'name' => 'comment_approved',
1196
                    'label' => 'Approved',
1197
                    'type' => 'number',
1198
                    'alias' => array( 'approved' ),
1199
	                'options' => array(
1200
                        'number_format' => '9999.99'
1201
	                )
1202
                ),
1203
                'comment_post_ID' => array(
1204
                    'name' => 'comment_post_ID',
1205
                    'label' => 'Post',
1206
                    'type' => 'pick',
1207
                    'alias' => array( 'post', 'post_id' ),
1208
                    'data' => array()
1209
                ),
1210
                'user_id' => array(
1211
                    'name' => 'user_id',
1212
                    'label' => 'Author',
1213
                    'type' => 'pick',
1214
                    'alias' => array( 'author' ),
1215
                    'pick_object' => 'user',
1216
                    'data' => array()
1217
                ),
1218
                'comment_date' => array(
1219
                    'name' => 'comment_date',
1220
                    'label' => 'Date',
1221
                    'type' => 'date',
1222
                    'alias' => array( 'created', 'date' ),
1223
                    'options' => array(
1224
                        'date_format_type' => 'datetime'
1225
                    )
1226
                ),
1227
                'comment_author' => array(
1228
                    'name' => 'comment_author',
1229
                    'label' => 'Author',
1230
                    'type' => 'text',
1231
                    'alias' => array( 'author' )
1232
                ),
1233
                'comment_author_email' => array(
1234
                    'name' => 'comment_author_email',
1235
                    'label' => 'Author E-mail',
1236
                    'type' => 'email',
1237
                    'alias' => array( 'author_email' )
1238
                ),
1239
                'comment_author_url' => array(
1240
                    'name' => 'comment_author_url',
1241
                    'label' => 'Author URL',
1242
                    'type' => 'text',
1243
                    'alias' => array( 'author_url' )
1244
                ),
1245
                'comment_author_IP' => array(
1246
                    'name' => 'comment_author_IP',
1247
                    'label' => 'Author IP',
1248
                    'type' => 'text',
1249
                    'alias' => array( 'author_IP' )
1250
                ),
1251
                'comment_type' => array(
1252
                    'name' => 'comment_type',
1253
                    'label' => 'Type',
1254
                    'type' => 'text',
1255
                    'alias' => array( 'type' ),
1256
                    'hidden' => true
1257
                ),
1258
                'comment_parent' => array(
1259
                    'name' => 'comment_parent',
1260
                    'label' => 'Parent',
1261
                    'type' => 'pick',
1262
                    'pick_object' => 'comment',
1263
                    'pick_val' => '__current__',
1264
                    'alias' => array( 'parent' ),
1265
                    'data' => array(),
1266
                    'hidden' => true
1267
                )
1268
            );
1269
        }
1270
        elseif ( 'taxonomy' == $object ) {
1271
            $fields = array(
1272
	            'term_id' => array(
1273
		            'name' => 'term_id',
1274
		            'label' => 'ID',
1275
		            'type' => 'number',
1276
		            'alias' => array( 'id', 'ID' ),
1277
	                'options' => array(
1278
                        'number_format' => '9999.99'
1279
	                )
1280
	            ),
1281
                'name' => array(
1282
                    'name' => 'name',
1283
                    'label' => 'Title',
1284
                    'type' => 'text',
1285
                    'alias' => array( 'title' )
1286
                ),
1287
                'slug' => array(
1288
                    'name' => 'slug',
1289
                    'label' => 'Permalink',
1290
                    'type' => 'slug',
1291
                    'alias' => array( 'permalink' )
1292
                ),
1293
                'description' => array(
1294
                    'name' => 'description',
1295
                    'label' => 'Description',
1296
                    'type' => 'wysiwyg',
1297
                    'alias' => array( 'content' )
1298
                ),
1299
                'taxonomy' => array(
1300
                    'name' => 'taxonomy',
1301
                    'label' => 'Taxonomy',
1302
                    'type' => 'pick',
1303
                    'alias' => array()
1304
                ),
1305
                'parent' => array(
1306
                    'name' => 'parent',
1307
                    'label' => 'Parent',
1308
                    'type' => 'pick',
1309
                    'pick_object' => 'taxonomy',
1310
                    'pick_val' => '__current__',
1311
                    'alias' => array( 'parent' ),
1312
                    'data' => array(),
1313
                    'hidden' => true
1314
                ),
1315
                'term_taxonomy_id' => array(
1316
                    'name' => 'term_taxonomy_id',
1317
                    'label' => 'Term Taxonomy ID',
1318
                    'type' => 'number',
1319
                    'alias' => array(),
1320
                    'hidden' => true,
1321
	                'options' => array(
1322
                        'number_format' => '9999.99'
1323
	                )
1324
                ),
1325
                'term_group' => array(
1326
                    'name' => 'term_group',
1327
                    'label' => 'Term Group',
1328
                    'type' => 'number',
1329
                    'alias' => array( 'group' ),
1330
                    'hidden' => true,
1331
	                'options' => array(
1332
                        'number_format' => '9999.99'
1333
	                )
1334
                ),
1335
                'count' => array(
1336
                    'name' => 'count',
1337
                    'label' => 'Count',
1338
                    'type' => 'number',
1339
                    'alias' => array(),
1340
                    'hidden' => true,
1341
	                'options' => array(
1342
                        'number_format' => '9999.99'
1343
	                )
1344
                )
1345
            );
1346
        }
1347
1348
        $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
1349
1350
        foreach ( $fields as $field => $options ) {
1351
            if ( !isset( $options[ 'alias' ] ) )
1352
                $options[ 'alias' ] = array();
1353
            else
1354
                $options[ 'alias' ] = (array) $options[ 'alias' ];
1355
1356
            if ( !isset( $options[ 'name' ] ) )
1357
                $options[ 'name' ] = $field;
1358
1359
            $fields[ $field ] = $options;
1360
        }
1361
1362
        $fields = PodsForm::fields_setup( $fields );
1363
1364 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
1365
            pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields );
1366
1367
        return $fields;
1368
    }
1369
1370
    /**
1371
     *
1372
     * @see PodsAPI::save_pod
1373
     *
1374
     * Add a Pod via the Wizard
1375
     *
1376
     * $params['create_extend'] string Create or Extend a Content Type
1377
     * $params['create_pod_type'] string Pod Type (for Creating)
1378
     * $params['create_name'] string Pod Name (for Creating)
1379
     * $params['create_label_plural'] string Plural Label (for Creating)
1380
     * $params['create_label_singular'] string Singular Label (for Creating)
1381
     * $params['create_storage'] string Storage Type (for Creating Post Types)
1382
     * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies)
1383
     * $params['extend_pod_type'] string Pod Type (for Extending)
1384
     * $params['extend_post_type'] string Post Type (for Extending Post Types)
1385
     * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies)
1386
     * $params['extend_storage'] string Storage Type (for Extending Post Types / Users / Comments)
1387
     *
1388
     * @param array $params An associative array of parameters
1389
     *
1390
     * @return bool|int Pod ID
1391
     * @since 2.0
1392
     */
1393
    public function add_pod ( $params ) {
1394
        $defaults = array(
1395
            'create_extend' => 'create',
1396
            'create_pod_type' => 'post_type',
1397
1398
            'create_name' => '',
1399
            'create_label_singular' => '',
1400
            'create_label_plural' => '',
1401
            'create_storage' => 'meta',
1402
            'create_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' ),
1403
1404
            'create_setting_name' => '',
1405
            'create_label_title' => '',
1406
            'create_label_menu' => '',
1407
            'create_menu_location' => 'settings',
1408
1409
            'extend_pod_type' => 'post_type',
1410
            'extend_post_type' => 'post',
1411
            'extend_taxonomy' => 'category',
1412
            'extend_table' => '',
1413
            'extend_storage' => 'meta',
1414
            'extend_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'table' ),
1415
        );
1416
1417
        $params = (object) array_merge( $defaults, (array) $params );
1418
1419
        if ( empty( $params->create_extend ) || !in_array( $params->create_extend, array( 'create', 'extend' ) ) )
1420
            return pods_error( __( 'Please choose whether to Create or Extend a Content Type', 'pods' ), $this );
1421
1422
        $pod_params = array(
1423
            'name' => '',
1424
            'label' => '',
1425
            'type' => '',
1426
            'storage' => 'table',
1427
            'object' => '',
1428
            'options' => array()
1429
        );
1430
1431
        if ( 'create' == $params->create_extend ) {
1432
            $label = ucwords( str_replace( '_', ' ', $params->create_name ) );
1433
1434
            if ( !empty( $params->create_label_singular ) )
1435
                $label = $params->create_label_singular;
1436
1437
            $pod_params[ 'name' ] = $params->create_name;
1438
            $pod_params[ 'label' ] = ( !empty( $params->create_label_plural ) ? $params->create_label_plural : $label );
1439
            $pod_params[ 'type' ] = $params->create_pod_type;
1440
            $pod_params[ 'options' ] = array(
1441
                'label_singular' => ( !empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params[ 'label' ] ),
1442
                'public' => 1,
1443
                'show_ui' => 1
1444
            );
1445
1446
            // Auto-generate name if not provided
1447
            if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'options' ][ 'label_singular' ] ) )
1448
                $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'options' ][ 'label_singular' ] );
1449
1450
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1451
                if ( empty(  $pod_params[ 'name' ] ) )
1452
                    return pods_error( 'Please enter a Name for this Pod', $this );
1453
1454
                $pod_params[ 'storage' ] = $params->create_storage;
1455
1456
                if ( pods_tableless() )
1457
                    $pod_params[ 'storage' ] = 'meta';
1458
            }
1459 View Code Duplication
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1460
                if ( empty(  $pod_params[ 'name' ] ) )
1461
                    return pods_error( 'Please enter a Name for this Pod', $this );
1462
1463
                $pod_params[ 'storage' ] = $params->create_storage_taxonomy;
1464
1465
                if ( pods_tableless() )
1466
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1467
            }
1468 View Code Duplication
            elseif ( 'pod' == $pod_params[ 'type' ] ) {
1469
                if ( empty(  $pod_params[ 'name' ] ) )
1470
                    return pods_error( 'Please enter a Name for this Pod', $this );
1471
1472
                if ( pods_tableless() ) {
1473
                    $pod_params[ 'type' ] = 'post_type';
1474
                    $pod_params[ 'storage' ] = 'meta';
1475
                }
1476
            }
1477
            elseif ( 'settings' == $pod_params[ 'type' ] ) {
1478
                $pod_params[ 'name' ] = $params->create_setting_name;
1479
                $pod_params[ 'label' ] = ( !empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) );
1480
                $pod_params[ 'options' ] = array(
1481
                    'menu_name' => ( !empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params[ 'label' ] ),
1482
                    'menu_location' => $params->create_menu_location
1483
                );
1484
                $pod_params[ 'storage' ] = 'none';
1485
1486
                // Auto-generate name if not provided
1487
                if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'label' ] ) )
1488
                    $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'label' ] );
1489
1490
                if ( empty( $pod_params[ 'name' ] ) )
1491
                    return pods_error( 'Please enter a Name for this Pod', $this );
1492
            }
1493
        }
1494
        elseif ( 'extend' == $params->create_extend ) {
1495
            $pod_params[ 'type' ] = $params->extend_pod_type;
1496
1497
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1498
                $pod_params[ 'storage' ] = $params->extend_storage;
1499
1500
                if ( pods_tableless() )
1501
                    $pod_params[ 'storage' ] = 'meta';
1502
1503
                $pod_params[ 'name' ] = $params->extend_post_type;
1504
            }
1505
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1506
                $pod_params[ 'storage' ] = $params->extend_storage_taxonomy;
1507
1508
                if ( pods_tableless() )
1509
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1510
1511
                $pod_params[ 'name' ] = $params->extend_taxonomy;
1512
            }
1513
            elseif ( 'table' == $pod_params[ 'type' ] ) {
1514
                $pod_params[ 'storage' ] = 'table';
1515
                $pod_params[ 'name' ] = $params->extend_table;
1516
            }
1517
            else {
1518
                $pod_params[ 'storage' ] = $params->extend_storage;
1519
1520
                if ( pods_tableless() )
1521
                    $pod_params[ 'storage' ] = 'meta';
1522
1523
                $pod_params[ 'name' ] = $params->extend_pod_type;
1524
            }
1525
1526
            $pod_params[ 'label' ] = ucwords( str_replace( '_', ' ', $pod_params[ 'name' ] ) );
1527
            $pod_params[ 'object' ] = $pod_params[ 'name' ];
1528
        }
1529
1530
        if ( empty( $pod_params[ 'object' ] ) ) {
1531
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1532
                $check = get_post_type_object( $pod_params[ 'name' ] );
1533
1534 View Code Duplication
                if ( !empty( $check ) )
1535
                    return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1536
1537
                $pod_params[ 'options' ][ 'supports_title' ] = 1;
1538
                $pod_params[ 'options' ][ 'supports_editor' ] = 1;
1539
            }
1540
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1541
                $check = get_taxonomy( $pod_params[ 'name' ] );
1542
1543 View Code Duplication
                if ( !empty( $check ) )
1544
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1545
            }
1546
        }
1547
1548
        if ( !empty( $pod_params ) )
1549
            return $this->save_pod( $pod_params );
1550
1551
        return false;
1552
    }
1553
1554
    /**
1555
     * Add or edit a Pod
1556
     *
1557
     * $params['id'] int The Pod ID
1558
     * $params['name'] string The Pod name
1559
     * $params['label'] string The Pod label
1560
     * $params['type'] string The Pod type
1561
     * $params['object'] string The object being extended (if any)
1562
     * $params['storage'] string The Pod storage
1563
     * $params['options'] array Options
1564
     *
1565
     * @param array $params An associative array of parameters
1566
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
1567
     * @param bool|int $db (optional) Whether to save into the DB or just return Pod array.
1568
     *
1569
     * @return int Pod ID
1570
     * @since 1.7.9
1571
     */
1572
    public function save_pod ( $params, $sanitized = false, $db = true ) {
1573
        $tableless_field_types = PodsForm::tableless_field_types();
1574
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
1575
1576
        $load_params = (object) $params;
1577
1578
        if ( isset( $load_params->id ) && isset( $load_params->name ) )
1579
            unset( $load_params->name );
1580
1581
        if ( isset( $load_params->old_name ) )
1582
            $load_params->name = $load_params->old_name;
1583
1584
        $load_params->table_info = true;
1585
1586
        $pod = $this->load_pod( $load_params, false );
1587
1588
        $params = (object) $params;
1589
1590
        if ( false === $sanitized )
1591
            $params = pods_sanitize( $params );
1592
1593
        $old_id = $old_name = $old_storage = null;
1594
1595
        $old_fields = $old_options = array();
1596
1597
		if ( isset( $params->name ) && ! isset( $params->object ) ) {
1598
			$params->name = pods_clean_name( $params->name );
1599
		}
1600
1601
        if ( !empty( $pod ) ) {
1602
            if ( isset( $params->id ) && 0 < $params->id )
1603
                $old_id = $params->id;
1604
1605
            $params->id = $pod[ 'id' ];
1606
1607
            $old_name = $pod[ 'name' ];
1608
            $old_storage = $pod[ 'storage' ];
1609
            $old_fields = $pod[ 'fields' ];
1610
            $old_options = $pod[ 'options' ];
1611
1612
            if ( !isset( $params->name ) && empty( $params->name ) )
1613
                $params->name = $pod[ 'name' ];
1614
1615
            if ( $old_name != $params->name && false !== $this->pod_exists( array( 'name' => $params->name ) ) )
1616
                return pods_error( sprintf( __( 'Pod %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1617
1618
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'user', 'comment', 'media' ) ) && in_array( $pod[ 'object' ], array( 'user', 'comment', 'media' ) ) )
1619
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1620
1621
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && !empty( $pod[ 'object' ] ) && $pod[ 'object' ] == $old_name )
1622
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1623
1624
            if ( $old_id != $params->id ) {
1625
                if ( $params->type == $pod[ 'type' ] && isset( $params->object ) && $params->object == $pod[ 'object' ] )
1626
                    return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this );
1627
                else
1628
                    return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this );
1629
            }
1630
        }
1631
		elseif ( in_array( $params->name, array( 'order','orderby','post_type' ) ) && 'post_type' == pods_var( 'type', $params ) ) {
1632
			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 );
1633
		}
1634
        else {
1635
            $pod = array(
1636
                'id' => 0,
1637
                'name' => $params->name,
1638
                'label' => $params->name,
1639
                'description' => '',
1640
                'type' => 'pod',
1641
                'storage' => 'table',
1642
                'object' => '',
1643
                'alias' => '',
1644
                'options' => array(),
1645
                'fields' => array()
1646
            );
1647
        }
1648
1649
        // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite)
1650
        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1651
            $pod[ 'fields' ] = array();
1652
            $pod[ 'options' ] = array();
1653
        }
1654
1655
        // Setup options
1656
        $options = get_object_vars( $params );
1657
1658
        if ( isset( $options[ 'method' ] ) )
1659
            unset( $options[ 'method' ] );
1660
1661
        $options_ignore = array(
1662
            'object_type',
1663
            'object_name',
1664
            'table',
1665
            'meta_table',
1666
            'pod_table',
1667
            'field_id',
1668
            'field_index',
1669
            'field_slug',
1670
            'field_type',
1671
            'field_parent',
1672
            'field_parent_select',
1673
            'meta_field_id',
1674
            'meta_field_index',
1675
            'meta_field_value',
1676
            'pod_field_id',
1677
            'pod_field_index',
1678
            'object_fields',
1679
            'join',
1680
            'where',
1681
            'where_default',
1682
            'orderby',
1683
            'pod',
1684
            'recurse',
1685
            'table_info',
1686
            'attributes',
1687
            'group',
1688
            'grouped',
1689
            'developer_mode',
1690
            'dependency',
1691
            'depends-on',
1692
            'excludes-on'
1693
        );
1694
1695
        foreach ( $options_ignore as $ignore ) {
1696
            if ( isset( $options[ $ignore ] ) )
1697
                unset( $options[ $ignore ] );
1698
        }
1699
1700
        $exclude = array(
1701
            'id',
1702
            'name',
1703
            'label',
1704
            'description',
1705
            'type',
1706
            'storage',
1707
            'object',
1708
            'alias',
1709
            'options',
1710
            'fields'
1711
        );
1712
1713 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
1714
            $aliases = array( $exclude_field );
1715
1716
            if ( is_array( $exclude_field ) ) {
1717
                $aliases = array_merge( array( $k ), $exclude_field );
1718
                $exclude_field = $k;
1719
            }
1720
1721
            foreach ( $aliases as $alias ) {
1722
                if ( isset( $options[ $alias ] ) ) {
1723
                    $pod[ $exclude_field ] = pods_trim( $options[ $alias ] );
1724
1725
                    unset( $options[ $alias ] );
1726
                }
1727
            }
1728
        }
1729
1730
        if ( pods_tableless() && !in_array( $pod[ 'type' ], array( 'settings', 'table' ) ) ) {
1731
            if ( 'pod' == $pod[ 'type' ] )
1732
                $pod[ 'type' ] = 'post_type';
1733
1734 View Code Duplication
            if ( 'table' == $pod[ 'storage' ] ) {
1735
                if ( 'taxonomy' == $pod[ 'type' ] && ! function_exists( 'get_term_meta' ) )
1736
                    $pod[ 'storage' ] = 'none';
1737
                else
1738
                    $pod[ 'storage' ] = 'meta';
1739
            }
1740
        }
1741
1742
        $pod[ 'options' ][ 'type' ] = $pod[ 'type' ];
1743
        $pod[ 'options' ][ 'storage' ] = $pod[ 'storage' ];
1744
        $pod[ 'options' ][ 'object' ] = $pod[ 'object' ];
1745
        $pod[ 'options' ][ 'alias' ] = $pod[ 'alias' ];
1746
1747
        $pod[ 'options' ] = array_merge( $pod[ 'options' ], $options );
1748
1749
		/**
1750
		 * @var WP_Query
1751
		 */
1752
		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...
1753
1754
		$reserved_query_vars = array(
1755
			'post_type',
1756
			'taxonomy',
1757
			'output'
1758
		);
1759
1760
		if ( is_object( $wp_query ) ) {
1761
			$reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
1762
		}
1763
1764 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var_string' ] ) ) {
1765
			if ( in_array( $pod[ 'options' ][ 'query_var_string' ], $reserved_query_vars ) ) {
1766
				$pod[ 'options' ][ 'query_var_string' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var_string' ];
1767
			}
1768
		}
1769
1770 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var' ] ) ) {
1771
			if ( in_array( $pod[ 'options' ][ 'query_var' ], $reserved_query_vars ) ) {
1772
				$pod[ 'options' ][ 'query_var' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var' ];
1773
			}
1774
		}
1775
1776
        if ( strlen( $pod[ 'label' ] ) < 1 )
1777
            $pod[ 'label' ] = $pod[ 'name' ];
1778
1779
        if ( 'post_type' == $pod[ 'type' ] ) {
1780
            // Max length for post types are 20 characters
1781
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 20 );
1782
        }
1783
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1784
            // Max length for taxonomies are 32 characters
1785
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 32 );
1786
        }
1787
1788
        $params->id = $pod[ 'id' ];
1789
        $params->name = $pod[ 'name' ];
1790
1791
        if ( null !== $old_name && $old_name != $params->name && empty( $pod[ 'object' ] ) ) {
1792
            if ( 'post_type' == $pod[ 'type' ] ) {
1793
                $check = get_post_type_object( $params->name );
1794
1795 View Code Duplication
                if ( !empty( $check ) )
1796
                    return pods_error( sprintf( __( 'Post Type %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1797
            }
1798
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1799
                $check = get_taxonomy( $params->name );
1800
1801 View Code Duplication
                if ( !empty( $check ) )
1802
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1803
            }
1804
        }
1805
1806
        $field_table_operation = true;
1807
1808
        // Add new pod
1809
        if ( empty( $params->id ) ) {
1810
            if ( strlen( $params->name ) < 1 )
1811
                return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this );
1812
1813
            $post_data = array(
1814
                'post_name' => $pod[ 'name' ],
1815
                'post_title' => $pod[ 'label' ],
1816
                'post_content' => $pod[ 'description' ],
1817
                'post_type' => '_pods_pod',
1818
                'post_status' => 'publish'
1819
            );
1820
1821
            if ( 'pod' == $pod[ 'type' ] && ( !is_array( $pod[ 'fields' ] ) || empty( $pod[ 'fields' ] ) ) ) {
1822
                $pod[ 'fields' ] = array();
1823
1824
                $pod[ 'fields' ][ 'name' ] = array(
1825
                    'name' => 'name',
1826
                    'label' => 'Name',
1827
                    'type' => 'text',
1828
                    'options' => array(
1829
                        'required' => '1'
1830
                    )
1831
                );
1832
1833
                $pod[ 'fields' ][ 'created' ] = array(
1834
                    'name' => 'created',
1835
                    'label' => 'Date Created',
1836
                    'type' => 'datetime',
1837
                    'options' => array(
1838
                        'datetime_format' => 'ymd_slash',
1839
                        'datetime_time_type' => '12',
1840
                        'datetime_time_format' => 'h_mm_ss_A'
1841
                    )
1842
                );
1843
1844
                $pod[ 'fields' ][ 'modified' ] = array(
1845
                    'name' => 'modified',
1846
                    'label' => 'Date Modified',
1847
                    'type' => 'datetime',
1848
                    'options' => array(
1849
                        'datetime_format' => 'ymd_slash',
1850
                        'datetime_time_type' => '12',
1851
                        'datetime_time_format' => 'h_mm_ss_A'
1852
                    )
1853
                );
1854
1855
                $pod[ 'fields' ][ 'author' ] = array(
1856
                    'name' => 'author',
1857
                    'label' => 'Author',
1858
                    'type' => 'pick',
1859
                    'pick_object' => 'user',
1860
                    'options' => array(
1861
                        'pick_format_type' => 'single',
1862
                        'pick_format_single' => 'autocomplete',
1863
                        'default_value' => '{@user.ID}'
1864
                    )
1865
                );
1866
1867
                $pod[ 'fields' ][ 'permalink' ] = array(
1868
                    'name' => 'permalink',
1869
                    'label' => 'Permalink',
1870
                    'type' => 'slug',
1871
                    'description' => 'Leave blank to auto-generate from Name'
1872
                );
1873
1874
                if ( !isset( $pod[ 'options' ][ 'pod_index' ] ) )
1875
                    $pod[ 'options' ][ 'pod_index' ] = 'name';
1876
            }
1877
1878
            $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db );
1879
1880
            $field_table_operation = false;
1881
        }
1882
        else {
1883
            $post_data = array(
1884
                'ID' => $pod[ 'id' ],
1885
                'post_name' => $pod[ 'name' ],
1886
                'post_title' => $pod[ 'label' ],
1887
                'post_content' => $pod[ 'description' ],
1888
                'post_status' => 'publish'
1889
            );
1890
        }
1891
1892 View Code Duplication
        if ( true === $db ) {
1893
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
1894
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
1895
1896
            $conflicted = false;
1897
1898
            // Headway compatibility fix
1899
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
1900
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1901
1902
                $conflicted = true;
1903
            }
1904
1905
            $params->id = $this->save_wp_object( 'post', $post_data, $pod[ 'options' ], true, true );
1906
1907
            if ( $conflicted )
1908
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1909
1910
            if ( false === $params->id )
1911
                return pods_error( __( 'Cannot save Pod', 'pods' ), $this );
1912
        }
1913
        elseif ( empty( $params->id ) )
1914
            $params->id = (int) $db;
1915
1916
        $pod[ 'id' ] = $params->id;
1917
1918
        // Setup / update tables
1919
        if ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $old_storage != $pod[ 'storage' ] && $db ) {
1920
            $definitions = array( "`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY" );
1921
1922
            $defined_fields = array();
1923
1924
            foreach ( $pod[ 'fields' ] as $field ) {
1925
                if ( !is_array( $field ) || !isset( $field[ 'name' ] ) || in_array( $field[ 'name' ], $defined_fields ) )
1926
                    continue;
1927
1928
                $defined_fields[] = $field[ 'name' ];
1929
1930
                if ( !in_array( $field[ 'type' ], $tableless_field_types ) || ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) ) {
1931
                    $definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, pods_var_raw( 'options', $field, array() ) ) );
1932
1933
                    if ( 0 < strlen( $definition ) )
1934
                        $definitions[] = "`{$field['name']}` " . $definition;
1935
                }
1936
            }
1937
1938
            pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`" );
1939
1940
            $result = pods_query( "CREATE TABLE `@wp_pods_{$params->name}` (" . implode( ', ', $definitions ) . ") DEFAULT CHARSET utf8", $this );
1941
1942
            if ( empty( $result ) )
1943
                return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this );
1944
1945
        }
1946
        elseif ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $pod[ 'storage' ] == $old_storage && null !== $old_name && $old_name != $params->name && $db ) {
1947
            $result = pods_query( "ALTER TABLE `@wp_pods_{$old_name}` RENAME `@wp_pods_{$params->name}`", $this );
1948
1949
            if ( empty( $result ) )
1950
                return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this );
1951
        }
1952
1953
        /**
1954
         * @var $wpdb wpdb
1955
         */
1956
        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...
1957
1958
		if ( null !== $old_name && $old_name != $params->name && $db ) {
1959
        	// Rename items in the DB pointed at the old WP Object names
1960
			if ( 'post_type' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1961
				$this->rename_wp_object_type( 'post', $old_name, $params->name );
1962
			}
1963 View Code Duplication
			elseif ( 'taxonomy' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1964
				$this->rename_wp_object_type( 'taxonomy', $old_name, $params->name );
1965
			}
1966 View Code Duplication
			elseif ( 'comment' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1967
				$this->rename_wp_object_type( 'comment', $old_name, $params->name );
1968
			}
1969
			elseif ( 'settings' == $pod[ 'type' ] ) {
1970
				$this->rename_wp_object_type( 'settings', $old_name, $params->name );
1971
			}
1972
1973
        	// Sync any related fields if the name has changed
1974
            $fields = pods_query( "
1975
                SELECT `p`.`ID`
1976
                FROM `{$wpdb->posts}` AS `p`
1977
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1978
                LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID`
1979
                WHERE
1980
                    `p`.`post_type` = '_pods_field'
1981
                    AND `pm`.`meta_key` = 'pick_object'
1982
                    AND (
1983
                    	`pm`.`meta_value` = 'pod'
1984
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "'
1985
					)
1986
                    AND `pm2`.`meta_key` = 'pick_val'
1987
                    AND `pm2`.`meta_value` = '{$old_name}'
1988
            " );
1989
1990 View Code Duplication
            if ( !empty( $fields ) ) {
1991
                foreach ( $fields as $field ) {
1992
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
1993
                    update_post_meta( $field->ID, 'pick_val', $params->name );
1994
                }
1995
            }
1996
1997
            $fields = pods_query( "
1998
                SELECT `p`.`ID`
1999
                FROM `{$wpdb->posts}` AS `p`
2000
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
2001
                WHERE
2002
                    `p`.`post_type` = '_pods_field'
2003
                    AND `pm`.`meta_key` = 'pick_object'
2004
                    AND (
2005
                    	`pm`.`meta_value` = 'pod-{$old_name}'
2006
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "-{$old_name}'
2007
					)
2008
            " );
2009
2010 View Code Duplication
            if ( !empty( $fields ) ) {
2011
                foreach ( $fields as $field ) {
2012
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
2013
                    update_post_meta( $field->ID, 'pick_val', $params->name );
2014
                }
2015
            }
2016
        }
2017
2018
        // Sync built-in options for post types and taxonomies
2019
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) && $db ) {
2020
            // Build list of 'built_in' for later
2021
            $built_in = array();
2022
2023
            foreach ( $pod[ 'options' ] as $key => $val ) {
2024
                if ( false === strpos( $key, 'built_in_' ) )
2025
                    continue;
2026
                elseif ( false !== strpos( $key, 'built_in_post_types_' ) )
2027
                    $built_in_type = 'post_type';
2028
                elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) )
2029
                    $built_in_type = 'taxonomy';
2030
                else
2031
                    continue;
2032
2033
                if ( $built_in_type == $pod[ 'type' ] )
2034
                    continue;
2035
2036
                if ( !isset( $built_in[ $built_in_type ] ) )
2037
                    $built_in[ $built_in_type ] = array();
2038
2039
                $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key );
2040
2041
                $built_in[ $built_in_type ][ $built_in_object ] = (int) $val;
2042
            }
2043
2044
            $lookup_option = $lookup_built_in = false;
2045
2046
            $lookup_name = $pod[ 'name' ];
2047
2048
            if ( 'post_type' == $pod[ 'type' ] ) {
2049
                $lookup_option = 'built_in_post_types_' . $lookup_name;
2050
                $lookup_built_in = 'taxonomy';
2051
            }
2052
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
2053
                $lookup_option = 'built_in_taxonomies_' . $lookup_name;
2054
                $lookup_built_in = 'post_type';
2055
            }
2056
2057
            if ( !empty( $lookup_option ) && !empty( $lookup_built_in ) && isset( $built_in[ $lookup_built_in ] ) ) {
2058
                foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) {
2059
                    $search_val = 1;
2060
2061
                    if ( 1 == $val )
2062
                        $search_val = 0;
2063
2064
                    $query = "SELECT p.ID FROM {$wpdb->posts} AS p
2065
                                LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}'
2066
                                LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}'
2067
                                LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = ''
2068
                                WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}'
2069
                                    AND pm2.meta_id IS NOT NULL
2070
                                    AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )";
2071
2072
                    $results = pods_query( $query );
2073
2074
                    if ( !empty( $results ) ) {
2075
                        foreach ( $results as $the_pod ) {
2076
                            delete_post_meta( $the_pod->ID, $lookup_option );
2077
2078
                            add_post_meta( $the_pod->ID, $lookup_option, $val );
2079
                        }
2080
                    }
2081
                }
2082
            }
2083
        }
2084
2085
        $saved = array();
2086
        $errors = array();
2087
2088
        $field_index_change = false;
2089
        $field_index_id = 0;
2090
2091
        $id_required = false;
2092
2093
        $field_index = pods_var( 'pod_index', $pod[ 'options' ], 'id', null, true );
2094
2095
        if ( 'pod' == $pod[ 'type' ] && !empty( $pod[ 'fields' ] ) && isset( $pod[ 'fields' ][ $field_index ] ) )
2096
            $field_index_id = $pod[ 'fields' ][ $field_index ];
2097
2098
        if ( isset( $params->fields ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
2099
            $fields = array();
2100
2101
            if ( isset( $params->fields ) ) {
2102
                $params->fields = (array) $params->fields;
2103
2104
                $weight = 0;
2105
2106
                foreach ( $params->fields as $field ) {
2107
                    if ( !is_array( $field ) || !isset( $field[ 'name' ] ) )
2108
                        continue;
2109
2110
                    if ( !isset( $field[ 'weight' ] ) ) {
2111
                        $field[ 'weight' ] = $weight;
2112
2113
                        $weight++;
2114
                    }
2115
2116
                    $fields[ $field[ 'name' ] ] = $field;
2117
                }
2118
            }
2119
2120
            $weight = 0;
2121
2122
            $saved_field_ids = array();
2123
2124
            foreach ( $pod[ 'fields' ] as $k => $field ) {
2125
                if ( !empty( $old_id ) && ( !is_array( $field ) || !isset( $field[ 'name' ] ) || !isset( $fields[ $field[ 'name' ] ] ) ) ) {
2126
                    // Iterative change handling for setup-edit.php
2127
                    if ( !is_array( $field ) && isset( $old_fields[ $k ] ) )
2128
                        $saved[ $old_fields[ $k ][ 'name' ] ] = true;
2129
2130
                    continue;
2131
                }
2132
2133
                if ( !empty( $old_id ) )
2134
                    $field = array_merge( $field, $fields[ $field[ 'name' ] ] );
2135
2136
                $field[ 'pod' ] = $pod;
2137
2138
                if ( !isset( $field[ 'weight' ] ) ) {
2139
                    $field[ 'weight' ] = $weight;
2140
2141
                    $weight++;
2142
                }
2143
2144
                if ( 0 < $field_index_id && pods_var( 'id', $field ) == $field_index_id )
2145
                    $field_index_change = $field[ 'name' ];
2146
2147
                if ( 0 < pods_var( 'id', $field ) )
2148
                    $id_required = true;
2149
2150
                if ( $id_required )
2151
                    $field[ 'id_required' ] = true;
2152
2153
                $field_data = $field;
2154
2155
                $field = $this->save_field( $field_data, $field_table_operation, true, $db );
2156
2157
                if ( true !== $db ) {
2158
                    $pod[ 'fields' ][ $k ] = $field;
2159
                    $saved_field_ids[] = $field[ 'id' ];
2160
                }
2161
                else {
2162
                    if ( !empty( $field ) && 0 < $field ) {
2163
                        $saved[ $field_data[ 'name' ] ] = true;
2164
                        $saved_field_ids[] = $field;
2165
                    }
2166
                    else
2167
                        $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data[ 'name' ] );
2168
                }
2169
            }
2170
2171
            if ( true === $db ) {
2172
                foreach ( $old_fields as $field ) {
2173
                    if ( isset( $pod[ 'fields' ][ $field[ 'name' ] ] ) || isset( $saved[ $field[ 'name' ] ] ) || in_array( $field[ 'id' ], $saved_field_ids ) )
2174
                        continue;
2175
2176
                    if ( $field[ 'id' ] == $field_index_id )
2177
                        $field_index_change = 'id';
2178
                    elseif ( $field[ 'name' ] == $field_index )
2179
                        $field_index_change = 'id';
2180
2181
                    $this->delete_field( array(
2182
                        'id' => (int) $field[ 'id' ],
2183
                        'name' => $field[ 'name' ],
2184
                        'pod' => $pod
2185
                    ), $field_table_operation );
2186
                }
2187
            }
2188
2189
            // Update field index if the name has changed or the field has been removed
2190
            if ( false !== $field_index_change && true === $db )
2191
                update_post_meta( $pod[ 'id' ], 'pod_index', $field_index_change );
2192
        }
2193
2194
        if ( !empty( $errors ) )
2195
            return pods_error( $errors, $this );
2196
2197
        $this->cache_flush_pods( $pod );
2198
2199
        if ( 'post_type' == $pod[ 'type' ] )
2200
            PodsMeta::$post_types[ $pod[ 'id' ] ] = $this->load_pod( array( 'name' => $pod[ 'name' ] ) );
2201
        elseif ( 'taxonomy' == $pod[ 'type' ] )
2202
            PodsMeta::$taxonomies[ $pod[ 'id' ] ] = $this->load_pod( array( 'name' => $pod[ 'name' ] ) );
2203
        elseif ( 'media' == $pod[ 'type' ] )
2204
            PodsMeta::$media[ $pod[ 'id' ] ] = $this->load_pod( array( 'name' => $pod[ 'name' ] ) );
2205 View Code Duplication
        elseif ( 'user' == $pod[ 'type' ] )
2206
            PodsMeta::$user[ $pod[ 'id' ] ] = $this->load_pod( array( 'name' => $pod[ 'name' ] ) );
2207
        elseif ( 'comment' == $pod[ 'type' ] )
2208
            PodsMeta::$comment[ $pod[ 'id' ] ] = $this->load_pod( array( 'name' => $pod[ 'name' ] ) );
2209
2210
        // Register Post Types / Taxonomies post-registration from PodsInit
2211
        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...
2212
            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...
2213
2214
            $pods_init->setup_content_types( true );
2215
        }
2216
2217
        if ( true === $db )
2218
            return $pod[ 'id' ];
2219
        else
2220
            return $pod;
2221
    }
2222
2223
    /**
2224
     * Add or edit a field within a Pod
2225
     *
2226
     * $params['id'] int Field ID (id OR pod_id+pod+name required)
2227
     * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
2228
     * $params['pod'] string Pod name (id OR pod_id+pod+name required)
2229
     * $params['name'] string Field name (id OR pod_id+pod+name required)
2230
     * $params['label'] string (optional) Field label
2231
     * $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)
2232
     * $params['pick_object'] string (optional) Related Object (for relationships)
2233
     * $params['pick_val'] string (optional) Related Object name (for relationships)
2234
     * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
2235
     * $params['weight'] int (optional) Order in which the field appears
2236
     * $params['options'] array (optional) Options
2237
     *
2238
     * @param array $params An associative array of parameters
2239
     * @param bool $table_operation (optional) Whether or not to handle table operations
2240
     * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2241
     * @param bool|int $db (optional) Whether to save into the DB or just return field array.
2242
     *
2243
     * @return int|array The field ID or field array (if !$db)
2244
     * @since 1.7.9
2245
     */
2246
    public function save_field ( $params, $table_operation = true, $sanitized = false, $db = true ) {
2247
        /**
2248
         * @var $wpdb wpdb
2249
         */
2250
        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...
2251
2252
        if ( true !== $db )
2253
            $table_operation = false;
2254
2255
        $tableless_field_types = PodsForm::tableless_field_types();
2256
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
2257
2258
        $params = (object) $params;
2259
2260
        if ( false === $sanitized )
2261
            $params = pods_sanitize( $params );
2262
2263
        if ( isset( $params->pod_id ) )
2264
            $params->pod_id = pods_absint( $params->pod_id );
2265
2266
        if ( true !== $db )
2267
            $params->pod_id = (int) $db;
2268
2269
        $pod = null;
2270
        $save_pod = false;
2271
        $id_required = false;
2272
2273
        if ( isset( $params->id_required ) ) {
2274
            unset( $params->id_required );
2275
2276
            $id_required = true;
2277
        }
2278
2279 View Code Duplication
        if ( ( !isset( $params->pod ) || empty( $params->pod ) ) && ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) )
2280
            return pods_error( __( 'Pod ID or name is required', 'pods' ), $this );
2281
2282
        if ( isset( $params->pod ) && is_array( $params->pod ) ) {
2283
            $pod = $params->pod;
2284
2285
            $save_pod = true;
2286
        }
2287 View Code Duplication
        elseif ( ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) )
2288
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
2289 View Code Duplication
        elseif ( !isset( $params->pod ) && ( true === $db || 0 < $db ) )
2290
            $pod = $this->load_pod( array( 'id' => $params->pod_id, 'table_info' => true ) );
2291 View Code Duplication
        elseif ( true === $db || 0 < $db )
2292
            $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
2293
2294
        if ( empty( $pod ) && true === $db )
2295
            return pods_error( __( 'Pod not found', 'pods' ), $this );
2296
2297
        $params->pod_id = $pod[ 'id' ];
2298
        $params->pod = $pod[ 'name' ];
2299
        $params->pod_data = $pod;
2300
2301
        $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2302
2303
        if ( !isset( $params->id ) )
2304
            $params->id = 0;
2305
2306
        if ( empty( $params->name ) )
2307
            return pods_error( 'Pod field name is required', $this );
2308
2309
        $field = $this->load_field( $params );
2310
2311
        unset( $params->pod_data );
2312
2313
        $old_id = $old_name = $old_type = $old_definition = $old_simple = $old_options = $old_sister_id = null;
2314
2315
        if ( !empty( $field ) ) {
2316
            $old_id = pods_var( 'id', $field );
2317
            $old_name = pods_clean_name( $field[ 'name' ], true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2318
            $old_type = $field[ 'type' ];
2319
            $old_options = $field[ 'options' ];
2320
            $old_sister_id = (int) pods_var( 'sister_id', $old_options, 0 );
2321
2322
            $old_simple = ( 'pick' == $old_type && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
2323
2324
            if ( isset( $params->name ) && !empty( $params->name ) )
2325
                $field[ 'name' ] = $params->name;
2326
2327
            if ( $old_name != $field[ 'name' ] && false !== $this->field_exists( $params ) )
2328
                return pods_error( sprintf( __( 'Field %s already exists, you cannot rename %s to that', 'pods' ), $field[ 'name' ], $old_name ), $this );
2329
2330
            if ( ( $id_required || !empty( $params->id ) ) && ( empty( $old_id ) || $old_id != $params->id ) )
2331
                return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field[ 'name' ] ), $this );
2332
2333
            if ( empty( $params->id ) )
2334
                $params->id = $old_id;
2335
2336
            if ( !in_array( $old_type, $tableless_field_types ) || $old_simple ) {
2337
                $definition = $this->get_field_definition( $old_type, array_merge( $field, $old_options ) );
2338
2339
                if ( 0 < strlen( $definition ) )
2340
                    $old_definition = "`{$old_name}` " . $definition;
2341
            }
2342
        }
2343
        else {
2344
            $field = array(
2345
                'id' => 0,
2346
                'pod_id' => $params->pod_id,
2347
                'name' => $params->name,
2348
                'label' => $params->name,
2349
                'description' => '',
2350
                'type' => 'text',
2351
                'pick_object' => '',
2352
                'pick_val' => '',
2353
                'sister_id' => '',
2354
                'weight' => null,
2355
                'options' => array()
2356
            );
2357
        }
2358
2359
        // Setup options
2360
        $options = get_object_vars( $params );
2361
2362
        $options_ignore = array(
2363
            'method',
2364
            'table_info',
2365
            'attributes',
2366
            'group',
2367
            'grouped',
2368
            'developer_mode',
2369
            'dependency',
2370
            'depends-on',
2371
            'excludes-on'
2372
        );
2373
2374
        foreach ( $options_ignore as $ignore ) {
2375
            if ( isset( $options[ $ignore ] ) )
2376
                unset( $options[ $ignore ] );
2377
        }
2378
2379
        if ( isset( $options[ 'method' ] ) )
2380
            unset( $options[ 'method' ] );
2381
        elseif ( isset( $options[ 'table_info' ] ) )
2382
            unset( $options[ 'table_info' ] );
2383
2384
        $exclude = array(
2385
            'id',
2386
            'pod_id',
2387
            'pod',
2388
            'name',
2389
            'label',
2390
            'description',
2391
            'type',
2392
            'pick_object',
2393
            'pick_val',
2394
            'sister_id',
2395
            'weight',
2396
            'options'
2397
        );
2398
2399 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2400
            $aliases = array( $exclude_field );
2401
2402
            if ( is_array( $exclude_field ) ) {
2403
                $aliases = array_merge( array( $k ), $exclude_field );
2404
                $exclude_field = $k;
2405
            }
2406
2407
            foreach ( $aliases as $alias ) {
2408
                if ( isset( $options[ $alias ] ) ) {
2409
                    $field[ $exclude_field ] = pods_trim( $options[ $alias ] );
2410
2411
                    unset( $options[ $alias ] );
2412
                }
2413
            }
2414
        }
2415
2416
        if ( strlen( $field[ 'label' ] ) < 1 )
2417
            $field[ 'label' ] = $field[ 'name' ];
2418
2419
        $field[ 'options' ][ 'type' ] = $field[ 'type' ];
2420
2421
        if ( in_array( $field[ 'options' ][ 'type' ], $tableless_field_types ) ) {
2422
            // Clean up special drop-down in field editor and save out pick_val
2423
            $field[ 'pick_object' ] = pods_var( 'pick_object', $field, '', null, true );
2424
2425
            if ( 0 === strpos( $field[ 'pick_object' ], 'pod-' ) ) {
2426
                $field[ 'pick_val' ] = pods_str_replace( 'pod-', '', $field[ 'pick_object' ], 1 );
2427
                $field[ 'pick_object' ] = 'pod';
2428
            }
2429 View Code Duplication
            elseif ( 0 === strpos( $field[ 'pick_object' ], 'post_type-' ) ) {
2430
                $field[ 'pick_val' ] = pods_str_replace( 'post_type-', '', $field[ 'pick_object' ], 1 );
2431
                $field[ 'pick_object' ] = 'post_type';
2432
            }
2433 View Code Duplication
            elseif ( 0 === strpos( $field[ 'pick_object' ], 'taxonomy-' ) ) {
2434
                $field[ 'pick_val' ] = pods_str_replace( 'taxonomy-', '', $field[ 'pick_object' ], 1 );
2435
                $field[ 'pick_object' ] = 'taxonomy';
2436
            }
2437
            elseif ( 'table' == $field[ 'pick_object' ] && 0 < strlen( pods_var_raw( 'pick_table', $field[ 'options' ] ) ) ) {
2438
                $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_table' ];
2439
                $field[ 'pick_object' ] = 'table';
2440
            }
2441
            elseif ( false === strpos( $field[ 'pick_object' ], '-' ) && !in_array( $field[ 'pick_object' ], array( 'pod', 'post_type', 'taxonomy' ) ) ) {
2442
                $field[ 'pick_val' ] = '';
2443
			}
2444
			elseif ( 'custom-simple' == $field[ 'pick_object' ] ) {
2445
                $field[ 'pick_val' ] = '';
2446
			}
2447
2448
            $field[ 'options' ][ 'pick_object' ] = $field[ 'pick_object' ];
2449
            $field[ 'options' ][ 'pick_val' ] = $field[ 'pick_val' ];
2450
            $field[ 'options' ][ 'sister_id' ] = pods_var( 'sister_id', $field );
2451
2452
            unset( $field[ 'pick_object' ] );
2453
            unset( $field[ 'pick_val' ] );
2454
2455
            if ( isset( $field[ 'sister_id' ] ) )
2456
                unset( $field[ 'sister_id' ] );
2457
        }
2458
2459
        $field[ 'options' ] = array_merge( $field[ 'options' ], $options );
2460
2461
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
2462
2463
        if ( 0 < $old_id && defined( 'PODS_FIELD_STRICT' ) && !PODS_FIELD_STRICT )
2464
            $params->id = $field[ 'id' ] = $old_id;
2465
2466
        // Add new field
2467
        if ( !isset( $params->id ) || empty( $params->id ) || empty( $field ) ) {
2468
            if ( $table_operation && in_array( $field[ 'name' ], array( 'created', 'modified' ) ) && !in_array( $field[ 'type' ], array( 'date', 'datetime' ) ) && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2469
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2470
2471
            if ( $table_operation && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2472
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2473
2474 View Code Duplication
            if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) )
2475
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2476
2477
            foreach ( $object_fields as $object_field => $object_field_opt ) {
2478
                if ( $object_field == $field[ 'name' ] || in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2479
                    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 );
2480
            }
2481
2482
            if ( in_array( $field[ 'name' ], array( 'rss' ) ) ) // Reserved post_name values that can't be used as field names
2483
                $field[ 'name' ] .= '2';
2484
2485
            if ( 'slug' == $field[ 'type' ] && true === $db ) {
2486 View Code Duplication
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy', 'user' ) ) )
2487
                    return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this );
2488
2489
                $slug_field = get_posts( array(
2490
                    'post_type' => '_pods_field',
2491
                    'orderby' => 'menu_order',
2492
                    'order' => 'ASC',
2493
                    'posts_per_page' => 1,
2494
                    'post_parent' => $field[ 'pod_id' ],
2495
                    'meta_query' => array(
2496
                        array(
2497
                            'key' => 'type',
2498
                            'value' => 'slug'
2499
                        )
2500
                    )
2501
                ) );
2502
2503
                if ( !empty( $slug_field ) )
2504
                    return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this );
2505
            }
2506
2507
            // Sink the new field to the bottom of the list
2508
            if ( null === $field[ 'weight' ] ) {
2509
                $field[ 'weight' ] = 0;
2510
2511
                $bottom_most_field = get_posts( array(
2512
                    'post_type' => '_pods_field',
2513
                    'orderby' => 'menu_order',
2514
                    'order' => 'DESC',
2515
                    'posts_per_page' => 1,
2516
                    'post_parent' => $field[ 'pod_id' ]
2517
                ) );
2518
2519
                if ( !empty( $bottom_most_field ) )
2520
                    $field[ 'weight' ] = pods_absint( $bottom_most_field[ 0 ]->menu_order ) + 1;
2521
            }
2522
2523
            $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2524
2525
            $post_data = array(
2526
                'post_name' => $field[ 'name' ],
2527
                'post_title' => $field[ 'label' ],
2528
                'post_content' => $field[ 'description' ],
2529
                'post_type' => '_pods_field',
2530
                'post_parent' => $field[ 'pod_id' ],
2531
                'post_status' => 'publish',
2532
                'menu_order' => $field[ 'weight' ]
2533
            );
2534
        }
2535
        else {
2536
            if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) ) {
2537 View Code Duplication
                if ( null !== $old_name )
2538
                    return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2539
                else
2540
                    return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2541
            }
2542
2543
            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 ) )
2544
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2545
2546
            if ( null !== $old_name && $field[ 'name' ] != $old_name && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2547
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2548
2549
            foreach ( $object_fields as $object_field => $object_field_opt ) {
2550
                if ( $object_field != $field[ 'name' ] && !in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2551
                    continue;
2552
2553 View Code Duplication
                if ( null !== $old_name )
2554
                    return pods_error( sprintf( __( '%s is reserved for internal WordPress or 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
            $post_data = array(
2560
                'ID' => $field[ 'id' ],
2561
                'post_name' => $field[ 'name' ],
2562
                'post_title' => $field[ 'label' ],
2563
                'post_content' => $field[ 'description' ]
2564
            );
2565
2566
            if ( null !== $field[ 'weight' ] ) {
2567
                $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2568
2569
                $post_data[ 'menu_order' ] = $field[ 'weight' ];
2570
            }
2571
        }
2572
2573 View Code Duplication
        if ( true === $db ) {
2574
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
2575
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
2576
2577
            $conflicted = false;
2578
2579
            // Headway compatibility fix
2580
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
2581
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2582
2583
                $conflicted = true;
2584
            }
2585
2586
            $params->id = $this->save_wp_object( 'post', $post_data, $field[ 'options' ], true, true );
2587
2588
            if ( $conflicted )
2589
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2590
2591
            if ( false === $params->id )
2592
                return pods_error( __( 'Cannot save Field', 'pods' ), $this );
2593
        }
2594
        else
2595
            $params->id = $field[ 'name' ];
2596
2597
        $field[ 'id' ] = $params->id;
2598
2599
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field[ 'options' ] ), $simple_tableless_objects ) );
2600
2601
        $definition = false;
2602
2603
        if ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) {
2604
            $field_definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, $field[ 'options' ] ) );
2605
2606
            if ( 0 < strlen( $field_definition ) )
2607
                $definition = '`' . $field[ 'name' ] . '` ' . $field_definition;
2608
        }
2609
2610
        $sister_id = (int) pods_var( 'sister_id', $field[ 'options' ], 0 );
2611
2612
        if ( $table_operation && 'table' == $pod[ 'storage' ] && !pods_tableless() ) {
2613
            if ( !empty( $old_id ) ) {
2614
                if ( ( $field[ 'type' ] != $old_type || $old_simple != $simple ) && empty( $definition ) )
2615
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false );
2616
                elseif ( 0 < strlen( $definition ) ) {
2617
                    if ( $old_name != $field[ 'name' ] || $old_simple != $simple ) {
2618
                        $test = false;
2619
2620 View Code Duplication
                        if ( 0 < strlen( $old_definition ) )
2621
                            $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2622
2623
                        // If the old field doesn't exist, continue to add a new field
2624
                        if ( false === $test )
2625
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2626
                    }
2627
                    elseif ( null !== $old_definition && $definition != $old_definition ) {
2628
                        $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2629
2630
                        // If the old field doesn't exist, continue to add a new field
2631
                        if ( false === $test )
2632
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2633
                    }
2634
                }
2635
            }
2636
            elseif ( 0 < strlen( $definition ) ) {
2637
                $test = false;
2638
2639 View Code Duplication
                if ( 0 < strlen( $old_definition ) )
2640
                    $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `" . $field[ 'name' ] . "` {$definition}", false );
2641
2642
                // If the old field doesn't exist, continue to add a new field
2643
                if ( false === $test )
2644
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2645
            }
2646
        }
2647
2648
        if ( !empty( $old_id ) && 'meta' == $pod[ 'storage' ] && $old_name != $field[ 'name' ] && $pod[ 'meta_table' ] != $pod[ 'table' ] ) {
2649
            $prepare = array(
2650
                $field[ 'name' ],
2651
                $old_name
2652
            );
2653
2654
            // Users don't have a type
2655
            if ( !empty( $pod[ 'field_type' ] ) )
2656
                $prepare[] = $pod[ 'name' ];
2657
2658
            pods_query( "
2659
                UPDATE `{$pod[ 'meta_table' ]}` AS `m`
2660
                LEFT JOIN `{$pod[ 'table' ]}` AS `t`
2661
                    ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}`
2662
                SET
2663
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2664
                WHERE
2665
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2666
            " . ( !empty( $pod[ 'field_type' ] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ),
2667
                $prepare
2668
            );
2669
        }
2670
2671
        if ( $field[ 'type' ] != $old_type && in_array( $old_type, $tableless_field_types ) ) {
2672
            delete_post_meta( $old_sister_id, 'sister_id' );
2673
2674
            if ( true === $db ) {
2675
                pods_query( "
2676
                        DELETE pm
2677
                        FROM {$wpdb->postmeta} AS pm
2678
                        LEFT JOIN {$wpdb->posts} AS p
2679
                            ON p.post_type = '_pods_field'
2680
                            AND p.ID = pm.post_id
2681
                        WHERE
2682
                            p.ID IS NOT NULL
2683
                            AND pm.meta_key = 'sister_id'
2684
                            AND pm.meta_value = %d
2685
                    ", array(
2686
                        $params->id
2687
                    )
2688
                );
2689
2690
                if ( !pods_tableless() ) {
2691
                    pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false );
2692
2693
                    pods_query( "
2694
                            UPDATE `@wp_podsrel`
2695
                            SET `related_field_id` = 0
2696
                            WHERE `field_id` = %d
2697
                        ", array(
2698
                            $old_sister_id
2699
                        )
2700
                    );
2701
                }
2702
            }
2703
        }
2704 View Code Duplication
        elseif ( 0 < $sister_id ) {
2705
            update_post_meta( $sister_id, 'sister_id', $params->id );
2706
2707
            if ( true === $db && ( !pods_tableless() ) ) {
2708
                pods_query( "
2709
                        UPDATE `@wp_podsrel`
2710
                        SET `related_field_id` = %d
2711
                        WHERE `field_id` = %d
2712
                    ",
2713
                    array(
2714
                        $params->id,
2715
                        $sister_id
2716
                    )
2717
                );
2718
            }
2719
        }
2720 View Code Duplication
        elseif ( 0 < $old_sister_id ) {
2721
            delete_post_meta( $old_sister_id, 'sister_id' );
2722
2723
            if ( true === $db && ( !pods_tableless() ) ) {
2724
                pods_query( "
2725
                        UPDATE `@wp_podsrel`
2726
                        SET `related_field_id` = 0
2727
                        WHERE `field_id` = %d
2728
                    ", array(
2729
                        $old_sister_id
2730
                    )
2731
                );
2732
            }
2733
        }
2734
2735
        if ( !empty( $old_id ) && $old_name != $field[ 'name' ] && true === $db ) {
2736
            pods_query( "
2737
                    UPDATE `@wp_postmeta`
2738
                    SET `meta_value` = %s
2739
                    WHERE
2740
                        `post_id` = %d
2741
                        AND `meta_key` = 'pod_index'
2742
                        AND `meta_value` = %s
2743
                ", array(
2744
                    $field[ 'name' ],
2745
                    $pod[ 'id' ],
2746
                    $old_name
2747
                )
2748
            );
2749
        }
2750
2751
        if ( !$save_pod )
2752
            $this->cache_flush_pods( $pod );
2753
        else {
2754
            pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
2755
2756
            if ( !empty( $old_id ) && $old_name != $field[ 'name' ] )
2757
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $old_name );
2758
        }
2759
2760
        if ( true === $db )
2761
            return $params->id;
2762
        else
2763
            return $field;
2764
    }
2765
2766
    /**
2767
     * Fix Pod / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name)
2768
     *
2769
     * @param string $slug Unique slug value
2770
     * @param int $post_ID Post ID
2771
     * @param string $post_status Post Status
2772
     * @param string $post_type Post Type
2773
     * @param int $post_parent Post Parent ID
2774
     * @param string $original_slug Original slug value
2775
     *
2776
     * @return string Final slug value
2777
     *
2778
     * @since 2.3.3
2779
     */
2780
    public function save_slug_fix ( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) {
2781
        if ( in_array( $post_type, array( '_pods_field', '_pods_pod' ) ) && false !== strpos( $slug, '-' ) )
2782
            $slug = $original_slug;
2783
2784
        return $slug;
2785
    }
2786
2787
    /**
2788
     * Add or Edit a Pods Object
2789
     *
2790
     * $params['id'] int The Object ID
2791
     * $params['name'] string The Object name
2792
     * $params['type'] string The Object type
2793
     * $params['options'] Associative array of Object options
2794
     *
2795
     * @param array|object $params An associative array of parameters
2796
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
2797
     *
2798
     * @return int The Object ID
2799
     * @since 2.0
2800
     */
2801
    public function save_object ( $params, $sanitized = false ) {
2802
        $params = (object) $params;
2803
2804
        if ( false === $sanitized )
2805
            $params = pods_sanitize( $params );
2806
2807 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
2808
            return pods_error( __( 'Name must be given to save an Object', 'pods' ), $this );
2809
2810 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
2811
            return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this );
2812
2813
        $object = array(
2814
            'id' => 0,
2815
            'name' => $params->name,
2816
            'type' => $params->type,
2817
            'code' => '',
2818
            'options' => array()
2819
        );
2820
2821
        // Setup options
2822
        $options = get_object_vars( $params );
2823
2824
        if ( isset( $options[ 'method' ] ) )
2825
            unset( $options[ 'method' ] );
2826
2827
        $exclude = array(
2828
            'id',
2829
            'name',
2830
            'helper_type',
2831
            'code',
2832
            'options',
2833
            'status'
2834
        );
2835
2836 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2837
            $aliases = array( $exclude_field );
2838
2839
            if ( is_array( $exclude_field ) ) {
2840
                $aliases = array_merge( array( $k ), $exclude_field );
2841
                $exclude_field = $k;
2842
            }
2843
2844
            foreach ( $aliases as $alias ) {
2845
                if ( isset( $options[ $alias ] ) ) {
2846
                    $object[ $exclude_field ] = pods_trim( $options[ $alias ] );
2847
2848
                    unset( $options[ $alias ] );
2849
                }
2850
            }
2851
        }
2852
2853
        if ( 'helper' == $object[ 'type' ] )
2854
            $object[ 'options' ][ 'helper_type' ] = $object[ 'helper_type' ];
2855
2856
        if ( isset( $object[ 'options' ][ 'code' ] ) )
2857
            unset( $object[ 'options' ][ 'code' ] );
2858
2859
        $object[ 'options' ] = array_merge( $object[ 'options' ], $options );
2860
2861
        $post_data = array(
2862
            'post_name' => pods_clean_name( $object[ 'name' ], true),
2863
            'post_title' => $object[ 'name' ],
2864
            'post_content' => $object[ 'code' ],
2865
            'post_type' => '_pods_' . $object[ 'type' ],
2866
            'post_status' => 'publish'
2867
        );
2868
2869
        if ( !empty( $object[ 'id' ] ) )
2870
            $post_data[ 'ID' ] = $object[ 'id' ];
2871
2872
        if ( null !== pods_var( 'status', $object, null, null, true ) )
2873
            $post_data[ 'post_status' ] = pods_var( 'status', $object, null, null, true );
2874
2875
        remove_filter( 'content_save_pre', 'balanceTags', 50 );
2876
2877
        $post_data = pods_sanitize( $post_data );
2878
2879
        $params->id = $this->save_post( $post_data, $object[ 'options' ], true, true );
2880
2881
        pods_transient_clear( 'pods_objects_' . $params->type );
2882
        pods_transient_clear( 'pods_objects_' . $params->type . '_get' );
2883
2884
        return $params->id;
2885
    }
2886
2887
    /**
2888
     * @see PodsAPI::save_object
2889
     *
2890
     * Add or edit a Pod Template
2891
     *
2892
     * $params['id'] int The template ID
2893
     * $params['name'] string The template name
2894
     * $params['code'] string The template code
2895
     *
2896
     * @param array|object $params An associative array of parameters
2897
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2898
     *
2899
     * @return int The Template ID
2900
     *
2901
     * @since 1.7.9
2902
     */
2903
    public function save_template ( $params, $sanitized = false ) {
2904
        $params = (object) $params;
2905
2906
        $params->type = 'template';
2907
2908
        return $this->save_object( $params, $sanitized );
2909
    }
2910
2911
    /**
2912
     * @see PodsAPI::save_object
2913
     *
2914
     * Add or edit a Pod Page
2915
     *
2916
     * $params['id'] int The page ID
2917
     * $params['name'] string The page URI
2918
     * $params['code'] string The page code
2919
     *
2920
     * @param array|object $params An associative array of parameters
2921
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2922
     *
2923
     * @return int The page ID
2924
     * @since 1.7.9
2925
     */
2926
    public function save_page ( $params, $sanitized = false ) {
2927
        $params = (object) $params;
2928
2929
        if ( !isset( $params->name ) ) {
2930
            $params->name = $params->uri;
2931
            unset( $params->uri );
2932
        }
2933
2934
        if ( isset( $params->phpcode ) ) {
2935
            $params->code = $params->phpcode;
2936
            unset( $params->phpcode );
2937
        }
2938
2939
        $params->name = trim( $params->name, '/' );
2940
        $params->type = 'page';
2941
2942
        return $this->save_object( $params, $sanitized );
2943
    }
2944
2945
    /**
2946
     * @see PodsAPI::save_object
2947
     *
2948
     * Add or edit a Pod Helper
2949
     *
2950
     * $params['id'] int The helper ID
2951
     * $params['name'] string The helper name
2952
     * $params['helper_type'] string The helper type ("pre_save", "display", etc)
2953
     * $params['code'] string The helper code
2954
     *
2955
     * @param array $params An associative array of parameters
2956
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2957
     *
2958
     * @return int The helper ID
2959
     * @since 1.7.9
2960
     */
2961
    public function save_helper ( $params, $sanitized = false ) {
2962
        $params = (object) $params;
2963
2964
        if ( isset( $params->phpcode ) ) {
2965
            $params->code = $params->phpcode;
2966
            unset( $params->phpcode );
2967
        }
2968
2969
        if ( isset( $params->type ) ) {
2970
            $params->helper_type = $params->type;
2971
            unset( $params->type );
2972
        }
2973
2974
        $params->type = 'helper';
2975
2976
        return $this->save_object( $params, $sanitized );
2977
    }
2978
2979
    /**
2980
     * Add or edit a single pod item
2981
     *
2982
     * $params['pod'] string The Pod name (pod or pod_id is required)
2983
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
2984
     * $params['id'] int The item ID
2985
     * $params['data'] array (optional) Associative array of field names + values
2986
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
2987
	 * $params['track_changed_fields'] bool Set to true to enable tracking of saved fields via PodsAPI::get_changed_fields()
2988
     *
2989
     * @param array|object $params An associative array of parameters
2990
     *
2991
     * @return int The item ID
2992
     *
2993
     * @since 1.7.9
2994
     */
2995
    public function save_pod_item ( $params ) {
2996
2997
		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...
2998
2999
        $params = (object) pods_str_replace( '@wp_', '{prefix}', $params );
3000
3001
        $tableless_field_types = PodsForm::tableless_field_types();
3002
        $repeatable_field_types = PodsForm::repeatable_field_types();
3003
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
3004
3005
        // @deprecated 2.0
3006
        if ( isset( $params->datatype ) ) {
3007
            pods_deprecated( '$params->pod instead of $params->datatype', '2.0' );
3008
3009
            $params->pod = $params->datatype;
3010
3011
            unset( $params->datatype );
3012
3013
            if ( isset( $params->pod_id ) ) {
3014
                pods_deprecated( '$params->id instead of $params->pod_id', '2.0' );
3015
3016
                $params->id = $params->pod_id;
3017
3018
                unset( $params->pod_id );
3019
            }
3020
3021
            if ( isset( $params->data ) && !empty( $params->data ) && is_array( $params->data ) ) {
3022
                $check = current( $params->data );
3023
3024
                if ( is_array( $check ) ) {
3025
                    pods_deprecated( 'PodsAPI::save_pod_items', '2.0' );
3026
3027
                    return $this->save_pod_items( $params, $params->data );
3028
                }
3029
            }
3030
        }
3031
3032
        // @deprecated 2.0
3033
        if ( isset( $params->tbl_row_id ) ) {
3034
            pods_deprecated( '$params->id instead of $params->tbl_row_id', '2.0' );
3035
3036
            $params->id = $params->tbl_row_id;
3037
3038
            unset( $params->tbl_row_id );
3039
        }
3040
3041
        // @deprecated 2.0
3042
        if ( isset( $params->columns ) ) {
3043
            pods_deprecated( '$params->data instead of $params->columns', '2.0' );
3044
3045
            $params->data = $params->columns;
3046
3047
            unset( $params->columns );
3048
        }
3049
3050
        if ( !isset( $params->pod ) )
3051
            $params->pod = false;
3052 View Code Duplication
        if ( isset( $params->pod_id ) )
3053
            $params->pod_id = pods_absint( $params->pod_id );
3054
        else
3055
            $params->pod_id = 0;
3056
3057 View Code Duplication
        if ( isset( $params->id ) )
3058
            $params->id = pods_absint( $params->id );
3059
        else
3060
            $params->id = 0;
3061
3062
        if ( !isset( $params->from ) )
3063
            $params->from = 'save';
3064
3065
        if ( !isset( $params->location ) )
3066
            $params->location = null;
3067
3068
        if ( !isset( $params->track_changed_fields ) )
3069
            $params->track_changed_fields = false;
3070
3071
		/**
3072
		 * Override $params['track_changed_fields']
3073
		 *
3074
		 * Use for globally setting field change tracking.
3075
		 *
3076
		 * @param bool
3077
		 *
3078
		 * @since 2.3.19
3079
		 */
3080
		$track_changed_fields = apply_filters( 'pods_api_save_pod_item_track_changed_fields_' . $params->pod, (boolean) $params->track_changed_fields, $params );
3081
		$changed_fields = array();
3082
3083
		if ( !isset( $params->clear_slug_cache ) ) {
3084
			$params->clear_slug_cache = true;
3085
		}
3086
3087
        // Support for bulk edit
3088
        if ( isset( $params->id ) && !empty( $params->id ) && is_array( $params->id ) ) {
3089
            $ids = array();
3090
            $new_params = $params;
3091
3092
            foreach ( $params->id as $id ) {
3093
                $new_params->id = $id;
3094
3095
                $ids[] = $this->save_pod_item( $new_params );
3096
            }
3097
3098
            return $ids;
3099
        }
3100
3101
        // Allow Helpers to know what's going on, are we adding or saving?
3102
        $is_new_item = false;
3103
3104
        if ( empty( $params->id ) )
3105
            $is_new_item = true;
3106
3107
        if ( isset( $params->is_new_item ) )
3108
            $is_new_item = (boolean) $params->is_new_item;
3109
3110
        // Allow Helpers to bypass subsequent helpers in recursive save_pod_item calls
3111
        $bypass_helpers = false;
3112
3113
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
3114
            $bypass_helpers = true;
3115
3116
        // Allow Custom Fields not defined by Pods to be saved
3117
        $allow_custom_fields = false;
3118
3119
        if ( isset( $params->allow_custom_fields ) && false !== $params->allow_custom_fields )
3120
            $allow_custom_fields = true;
3121
3122
        // Get array of Pods
3123
        $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
3124
3125
        if ( false === $pod )
3126
            return pods_error( __( 'Pod not found', 'pods' ), $this );
3127
3128
        $params->pod = $pod[ 'name' ];
3129
        $params->pod_id = $pod[ 'id' ];
3130
3131
        if ( 'settings' == $pod[ 'type' ] )
3132
            $params->id = $pod[ 'id' ];
3133
3134
        $fields = $pod[ 'fields' ];
3135
3136
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
3137
3138
        $fields_active = array();
3139
        $custom_data = array();
3140
3141
        // Find the active fields (loop through $params->data to retain order)
3142
        if ( !empty( $params->data ) && is_array( $params->data ) ) {
3143
            $custom_fields = array();
3144
3145
            foreach ( $params->data as $field => $value ) {
3146
                if ( isset( $object_fields[ $field ] ) ) {
3147
                    $object_fields[ $field ][ 'value' ] = $value;
3148
                    $fields_active[] = $field;
3149
                }
3150
                elseif ( isset( $fields[ $field ] ) ) {
3151
                    if ( 'save' == $params->from || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3152
                        $fields[ $field ][ 'value' ] = $value;
3153
                        $fields_active[] = $field;
3154
                    }
3155
                    elseif ( !pods_has_permissions( $fields[ $field ][ 'options' ] ) && pods_var( 'hidden', $fields[ $field ][ 'options' ], false ) ) {
3156
                        $fields[ $field ][ 'value' ] = $value;
3157
                        $fields_active[] = $field;
3158
                    }
3159
                }
3160
                else {
3161
                    $found = false;
3162
3163
                    foreach ( $object_fields as $object_field => $object_field_opt ) {
3164
                        if ( in_array( $field, $object_field_opt[ 'alias' ] ) ) {
3165
                            $object_fields[ $object_field ][ 'value' ] = $value;
3166
                            $fields_active[] = $object_field;
3167
3168
                            $found = true;
3169
3170
                            break;
3171
                        }
3172
                    }
3173
3174
                    if ( $allow_custom_fields && !$found )
3175
                        $custom_fields[] = $field;
3176
                }
3177
            }
3178
3179
            if ( $allow_custom_fields && !empty( $custom_fields ) ) {
3180
                foreach ( $custom_fields as $field ) {
3181
                    $custom_data[ $field ] = $params->data[ $field ];
3182
                }
3183
            }
3184
3185
           unset( $params->data );
3186
        }
3187
3188 View Code Duplication
		if ( empty( $params->id ) && !in_array( 'created', $fields_active ) && isset( $fields[ 'created' ] ) && in_array( $fields[ 'created' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3189
			$fields[ 'created' ][ 'value' ] = current_time( 'mysql' );
3190
			$fields_active[] = 'created';
3191
		}
3192
3193 View Code Duplication
		if ( !in_array( 'modified', $fields_active ) && isset( $fields[ 'modified' ] ) && in_array( $fields[ 'modified' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3194
			$fields[ 'modified' ][ 'value' ] = current_time( 'mysql' );
3195
			$fields_active[] = 'modified';
3196
		}
3197
3198
        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' ] ] ) ) {
3199
			$fields[ $pod[ 'pod_field_slug' ] ][ 'value' ] = ''; // this will get picked up by slug pre_save method
3200
			$fields_active[] = $pod[ 'pod_field_slug' ];
3201
        }
3202
3203
        // Handle hidden fields
3204
        if ( empty( $params->id ) ) {
3205
            foreach ( $fields as $field => $field_data ) {
3206
                if ( in_array( $field, $fields_active ) )
3207
                    continue;
3208
3209
                if ( in_array( $params->from, array( 'save', 'process_form' ) ) || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3210
                    $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 );
3211
3212
                    if ( null !== $value && '' !== $value && false !== $value ) {
3213
                        $fields[ $field ][ 'value' ] = $value;
3214
                        $fields_active[] = $field;
3215
                    }
3216
                }
3217
            }
3218
3219
			// Set default field values for object fields
3220
			if ( !empty( $object_fields ) ) {
3221 View Code Duplication
				foreach ( $object_fields as $field => $field_data ) {
3222
					if ( in_array( $field, $fields_active ) ) {
3223
						continue;
3224
					}
3225
					elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3226
						continue;
3227
					}
3228
3229
                    $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 );
3230
3231
                    if ( null !== $value && '' !== $value && false !== $value ) {
3232
                        $object_fields[ $field ][ 'value' ] = $value;
3233
                        $fields_active[] = $field;
3234
                    }
3235
				}
3236
			}
3237
3238
			// Set default field values for Pod fields
3239 View Code Duplication
			foreach ( $fields as $field => $field_data ) {
3240
				if ( in_array( $field, $fields_active ) ) {
3241
					continue;
3242
				}
3243
				elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3244
					continue;
3245
				}
3246
3247
				$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 );
3248
3249
				if ( null !== $value && '' !== $value && false !== $value ) {
3250
					$fields[ $field ][ 'value' ] = $value;
3251
					$fields_active[] = $field;
3252
				}
3253
			}
3254
        }
3255
3256
        $columns =& $fields; // @deprecated 2.0
3257
        $active_columns =& $fields_active; // @deprecated 2.0
3258
        $params->tbl_row_id =& $params->id; // @deprecated 2.0
3259
3260
        $pre_save_helpers = $post_save_helpers = array();
3261
3262
		$pieces = array(
3263
			'fields',
3264
			'params',
3265
			'pod',
3266
			'fields_active',
3267
			'object_fields',
3268
			'custom_fields',
3269
			'custom_data',
3270
			'track_changed_fields',
3271
			'changed_fields'
3272
		);
3273
3274
        if ( false === $bypass_helpers ) {
3275
            // Plugin hooks
3276
            $hooked = $this->do_hook( 'pre_save_pod_item', compact( $pieces ), $is_new_item, $params->id );
3277
3278
            if ( is_array( $hooked ) && !empty( $hooked ) )
3279
                extract( $hooked );
3280
3281
            $hooked = $this->do_hook( "pre_save_pod_item_{$params->pod}", compact( $pieces ), $is_new_item, $params->id );
3282
3283
            if ( is_array( $hooked ) && !empty( $hooked ) )
3284
                extract( $hooked );
3285
3286
            if ( $is_new_item ) {
3287
                $hooked = $this->do_hook( 'pre_create_pod_item', compact( $pieces ) );
3288
3289
                if ( is_array( $hooked ) && !empty( $hooked ) )
3290
                    extract( $hooked );
3291
3292
                $hooked = $this->do_hook( "pre_create_pod_item_{$params->pod}", compact( $pieces ) );
3293
3294
                if ( is_array( $hooked ) && !empty( $hooked ) )
3295
                    extract( $hooked );
3296
            }
3297
            else {
3298
                $hooked = $this->do_hook( 'pre_edit_pod_item', compact( $pieces ), $params->id );
3299
3300
                if ( is_array( $hooked ) && !empty( $hooked ) )
3301
                    extract( $hooked );
3302
3303
                $hooked = $this->do_hook( "pre_edit_pod_item_{$params->pod}", compact( $pieces ), $params->id );
3304
3305
                if ( is_array( $hooked ) && !empty( $hooked ) )
3306
                    extract( $hooked );
3307
            }
3308
3309
            // Call any pre-save helpers (if not bypassed)
3310 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3311
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
3312
                    $helpers = array( 'pre_save_helpers', 'post_save_helpers' );
3313
3314
                    foreach ( $helpers as $helper ) {
3315
                        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...
3316
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
3317
                    }
3318
                }
3319
3320
                if ( !empty( $pre_save_helpers ) ) {
3321
                    pods_deprecated( sprintf( __( 'Pre-save helpers are deprecated, use the action pods_pre_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3322
3323
                    foreach ( $pre_save_helpers as $helper ) {
3324
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3325
3326
                        if ( false !== $helper )
3327
                            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...
3328
                    }
3329
                }
3330
            }
3331
        }
3332
3333
		if ( $track_changed_fields ) {
3334
			$changed_fields = $this->get_changed_fields( compact( $pieces ) );
3335
		}
3336
3337
        $table_data = $table_formats = $update_values = $rel_fields = $rel_field_ids = array();
3338
3339
        $object_type = $pod[ 'type' ];
3340
3341
        $object_ID = 'ID';
3342
3343
        if ( 'comment' == $object_type )
3344
            $object_ID = 'comment_ID';
3345
        elseif ( 'taxonomy' == $object_type )
3346
            $object_ID = 'term_id';
3347
3348
        $object_data = $object_meta = $post_term_data = array();
3349
3350
        if ( 'settings' == $object_type )
3351
            $object_data[ 'option_id' ] = $pod[ 'name' ];
3352
        elseif ( !empty( $params->id ) )
3353
            $object_data[ $object_ID ] = $params->id;
3354
3355
        $fields_active = array_unique( $fields_active );
3356
3357
        // Loop through each active field, validating and preparing the table data
3358
        foreach ( $fields_active as $field ) {
3359 View Code Duplication
            if ( isset( $object_fields[ $field ] ) )
3360
                $field_data = $object_fields[ $field ];
3361
            elseif ( isset( $fields[ $field ] ) )
3362
                $field_data = $fields[ $field ];
3363
            else
3364
                continue;
3365
3366
            $value = $field_data[ 'value' ];
3367
            $type = $field_data[ 'type' ];
3368
            $options = pods_var( 'options', $field_data, array() );
3369
3370
            // WPML AJAX compatibility
3371
            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' ) )
3372
                $options[ 'unique' ] = $fields[ $field ][ 'options' ][ 'unique' ] = $options[ 'required' ] = $fields[ $field ][ 'options' ][ 'required' ] = 0;
3373
            else {
3374
                // Validate value
3375
                $validate = $this->handle_field_validation( $value, $field, $object_fields, $fields, $pod, $params );
3376
3377
                if ( false === $validate )
3378
                    $validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field_data[ 'label' ] );
3379
                elseif ( true !== $validate )
3380
                    $validate = (array) $validate;
3381
3382
                if ( !is_bool( $validate ) && !empty( $validate ) )
3383
                    return pods_error( $validate, $this );
3384
            }
3385
3386
            $value = PodsForm::pre_save( $field_data[ 'type' ], $value, $params->id, $field, array_merge( $field_data, $options ), array_merge( $fields, $object_fields ), $pod, $params );
3387
3388
            $field_data[ 'value' ] = $value;
3389
3390
            if ( isset( $object_fields[ $field ] ) ) {
3391
				if ( 'taxonomy' == $object_fields[ $field ][ 'type' ] ) {
3392
					$post_term_data[ $field ] = $value;
3393
				}
3394
				else {
3395
                	$object_data[ $field ] = $value;
3396
				}
3397
			}
3398
            else {
3399
                $simple = ( 'pick' == $type && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
3400
                $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field_data, $field, $fields, $pod, $params );
3401
3402
                // Handle Simple Relationships
3403
                if ( $simple ) {
3404
                    if ( !is_array( $value ) )
3405
                        $value = explode( ',', $value );
3406
3407
                    $pick_limit = (int) pods_var_raw( 'pick_limit', $options, 0 );
3408
3409
                    if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
3410
                        $pick_limit = 1;
3411
3412
                    if ( 'custom-simple' == pods_var( 'pick_object', $field_data ) ) {
3413
                        $custom = pods_var_raw( 'pick_custom', $options, '' );
3414
3415
                        $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data[ 'name' ], $value, array_merge( $field_data, $options ), $pod, $params->id );
3416
3417
                        if ( empty( $value ) || empty( $custom ) )
3418
                            $value = '';
3419
                        elseif ( !empty( $custom ) ) {
3420
                            if ( !is_array( $custom ) ) {
3421
                                $custom = explode( "\n", $custom );
3422
3423
                                $custom_values = array();
3424
3425
                                foreach ( $custom as $c => $cv ) {
3426
                                    if ( 0 < strlen( $cv ) ) {
3427
                                        $custom_label = explode( '|', $cv );
3428
3429
                                        if ( !isset( $custom_label[ 1 ] ) )
3430
                                            $custom_label[ 1 ] = $custom_label[ 0 ];
3431
3432
                                        $custom_label[ 0 ] = trim( (string) $custom_label[ 0 ] );
3433
                                        $custom_label[ 1 ] = trim( (string) $custom_label[ 1 ] );
3434
                                        $custom_values[ $custom_label[ 0 ] ] = $custom_label[ 1 ];
3435
                                    }
3436
                                }
3437
                            }
3438
                            else
3439
                                $custom_values = $custom;
3440
3441
                            $values = array();
3442
3443
                            foreach ( $value as $k => $v ) {
3444
                                $v = pods_unsanitize( $v );
3445
3446
                                if ( isset( $custom_values[ $v ] ) )
3447
                                    $values[ $k ] = $v;
3448
                            }
3449
3450
                            $value = $values;
3451
                        }
3452
                    }
3453
3454
                    if ( 0 < $pick_limit && !empty( $value ) )
3455
                        $value = array_slice( $value, 0, $pick_limit );
3456
3457
                    // Don't save an empty array, just make it an empty string
3458 View Code Duplication
                    if ( empty( $value ) )
3459
                        $value = '';
3460
                    elseif ( is_array( $value ) ) {
3461
                        // If there's just one item, don't save as an array, save the string
3462
                        if ( 1 == $pick_limit || 1 == count( $value ) )
3463
                            $value = implode( '', $value );
3464
                        // If storage is set to table, json encode, otherwise WP will serialize automatically
3465
                        elseif ( 'table' == pods_var( 'storage', $pod ) )
3466
                            $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...
3467
                    }
3468
                }
3469
3470
                // Prepare all table / meta data
3471
                if ( !in_array( $type, $tableless_field_types ) || $simple ) {
3472
                    if ( in_array( $type, $repeatable_field_types ) && 1 == pods_var( $type . '_repeatable', $field_data, 0 ) ) {
3473
                        // Don't save an empty array, just make it an empty string
3474 View Code Duplication
                        if ( empty( $value ) )
3475
                            $value = '';
3476
                        elseif ( is_array( $value ) ) {
3477
                            // If there's just one item, don't save as an array, save the string
3478
                            if ( 1 == count( $value ) )
3479
                                $value = implode( '', $value );
3480
                            // If storage is set to table, json encode, otherwise WP will serialize automatically
3481
                            elseif ( 'table' == pods_var( 'storage', $pod ) )
3482
                                $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...
3483
                        }
3484
                    }
3485
3486
                    $table_data[ $field ] = str_replace( array( '{prefix}', '@wp_' ), array( '{/prefix/}', '{prefix}' ), $value ); // Fix for pods_query
3487
                    $table_formats[] = PodsForm::prepare( $type, $options );
3488
3489
                    $object_meta[ $field ] = $value;
3490
                }
3491
                // Store relational field data to be looped through later
3492
                else {
3493
                    // Convert values from a comma-separated string into an array
3494
                    if ( !is_array( $value ) )
3495
                        $value = explode( ',', $value );
3496
3497
                    $rel_fields[ $type ][ $field ] = $value;
3498
                    $rel_field_ids[] = $field_data[ 'id' ];
3499
                }
3500
            }
3501
        }
3502
3503
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) ) {
3504
            $object_name = $pod[ 'name' ];
3505
3506
            if ( !empty( $pod[ 'object' ] ) )
3507
                $object_name = $pod[ 'object' ];
3508
3509
            $object_name_field = 'post_type';
3510
3511
            if ( 'taxonomy' == $pod['type'] ) {
3512
                $object_name_field = 'taxonomy';
3513
            }
3514
3515
            $object_data[ $object_name_field ] = $object_name;
3516
        }
3517
3518
        if ( ( 'meta' == $pod[ 'storage' ] || 'settings' == $pod[ 'type' ] || ( 'taxonomy' == $pod[ 'type' ] && 'none' == $pod[ 'storage' ] ) ) && !in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3519
            if ( $allow_custom_fields && !empty( $custom_data ) )
3520
                $object_meta = array_merge( $custom_data, $object_meta );
3521
3522
			$fields_to_send = array_flip( array_keys( $object_meta ) );
3523
3524
			foreach ( $fields_to_send as $field => $field_data ) {
3525 View Code Duplication
				if ( isset( $object_fields[ $field ] ) ) {
3526
					$field_data = $object_fields[ $field ];
3527
				}
3528
				elseif ( isset( $fields[ $field ] ) ) {
3529
					$field_data = $fields[ $field ];
3530
				}
3531
				else {
3532
					unset( $fields_to_send[ $field ] );
3533
				}
3534
3535
				$fields_to_send[ $field ] = $field_data;
3536
			}
3537
3538
            $params->id = $this->save_wp_object( $object_type, $object_data, $object_meta, false, true, $fields_to_send );
3539
3540
            if ( !empty( $params->id ) && 'settings' == $object_type )
3541
                $params->id = $pod[ 'id' ];
3542
        }
3543
        else {
3544
            if ( ! in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3545
                $params->id = $this->save_wp_object( $object_type, $object_data, array(), false, true );
3546
            }
3547
3548
            if ( 'table' == $pod[ 'storage' ] ) {
3549
                // Every row should have an id set here, otherwise Pods with nothing
3550
                // but relationship fields won't get properly ID'd
3551
                if ( empty( $params->id ) )
3552
                    $params->id = 0;
3553
3554
                $table_data = array( 'id' => $params->id ) + $table_data;
3555
                array_unshift( $table_formats, '%d' );
3556
3557
                if ( !empty( $table_data ) ) {
3558
                    $sql = pods_data()->insert_on_duplicate( "@wp_pods_{$params->pod}", $table_data, $table_formats );
3559
3560
                    $id = pods_query( $sql, 'Cannot add/save table row' );
3561
3562
                    if ( empty( $params->id ) )
3563
                        $params->id = $id;
3564
                }
3565
            }
3566
        }
3567
3568
        $params->id = (int) $params->id;
3569
3570
		// Save terms for taxonomies associated to a post type
3571
        if ( 0 < $params->id && 'post_type' == $pod[ 'type' ] && !empty( $post_term_data ) ) {
3572
			foreach ( $post_term_data as $post_taxonomy => $post_terms ) {
3573
                $post_terms = (array) $post_terms;
3574
3575
                foreach ( $post_terms as $k => $v ) {
3576
                    if ( ! preg_match( '/[^0-9]/', $v ) ) {
3577
                        $v = (int) $v;
3578
                    }
3579
3580
                    $post_terms[ $k ] = $v;
3581
                }
3582
3583
				wp_set_object_terms( $params->id, $post_terms, $post_taxonomy );
3584
			}
3585
		}
3586
3587
        $no_conflict = pods_no_conflict_check( $pod[ 'type' ] );
3588
3589
        if ( !$no_conflict )
3590
            pods_no_conflict_on( $pod[ 'type' ] );
3591
3592
        // Save relationship / file data
3593
        if ( !empty( $rel_fields ) ) {
3594
            foreach ( $rel_fields as $type => $data ) {
3595
                // Only handle tableless fields
3596
                if ( !in_array( $type, $tableless_field_types ) ) {
3597
                    continue;
3598
				}
3599
3600
                foreach ( $data as $field => $values ) {
3601
                    $pick_val = pods_var( 'pick_val', $fields[ $field ] );
3602
3603
                    if ( 'table' == pods_var( 'pick_object', $fields[ $field ] ) ) {
3604
                        $pick_val = pods_var( 'pick_table', $fields[ $field ][ 'options' ], $pick_val, null, true );
3605
					}
3606
3607 View Code Duplication
                    if ( '__current__' == $pick_val ) {
3608
                        if ( is_object( $pod ) ) {
3609
                            $pick_val = $pod->pod;
3610
						}
3611
                        elseif ( is_array( $pod ) ) {
3612
                            $pick_val = $pod[ 'name' ];
3613
						}
3614
                        elseif ( 0 < strlen( $pod ) ) {
3615
                            $pick_val = $pod;
3616
						}
3617
                    }
3618
3619
                    $fields[ $field ][ 'options' ][ 'table_info' ] = pods_api()->get_table_info( pods_var( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ][ 'options' ] );
3620
3621
                    if ( isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && !empty( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] ) ) {
3622
						$search_data = pods( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] );
3623
3624
						$data_mode = 'pods';
3625
                    }
3626
					else {
3627
						$search_data = pods_data();
3628
						$search_data->table( $fields[ $field ][ 'options' ][ 'table_info' ] );
3629
3630
						$data_mode = 'data';
3631
					}
3632
3633
					$find_rel_params = array(
3634
						'select' => "`t`.`{$search_data->field_id}`",
3635
						'where' => "`t`.`{$search_data->field_slug}` = %s OR `t`.`{$search_data->field_index}` = %s",
3636
						'limit' => 1,
3637
						'pagination' => false,
3638
						'search' => false
3639
					);
3640
3641
					if ( empty( $search_data->field_slug ) && !empty( $search_data->field_index ) ) {
3642
						$find_rel_params[ 'where' ] = "`t`.`{$search_data->field_index}` = %s";
3643
					}
3644
					elseif ( empty( $search_data->field_slug ) && empty( $search_data->field_index ) ) {
3645
						$find_rel_params = false;
3646
					}
3647
3648
                    $related_limit = (int) pods_var_raw( $type . '_limit', $fields[ $field ][ 'options' ], 0 );
3649
3650 View Code Duplication
                    if ( 'single' == pods_var_raw( $type . '_format_type', $fields[ $field ][ 'options' ] ) ) {
3651
                        $related_limit = 1;
3652
					}
3653
3654
                    // Enforce integers / unique values for IDs
3655
                    $value_ids = array();
3656
3657
					$is_file_field = in_array( $type, PodsForm::file_field_types() );
3658
					$is_taggable = ( in_array( $type, PodsForm::tableless_field_types() ) && 1 == pods_v( $type . '_taggable', $fields[ $field ][ 'options' ] ) );
3659
3660
					// @todo Handle simple relationships eventually
3661
                    foreach ( $values as $v ) {
3662
                        if ( !empty( $v ) ) {
3663
							if ( !is_array( $v ) ) {
3664
								if ( !preg_match( '/[^0-9]/', $v ) ) {
3665
									$v = (int) $v;
3666
								}
3667
								// File handling
3668
								elseif ( $is_file_field ) {
3669
									// Get ID from GUID
3670
									$v = pods_image_id_from_field( $v );
3671
3672
									// If file not found, add it
3673
									if ( empty( $v ) ) {
3674
										$v = pods_attachment_import( $v );
3675
									}
3676
								}
3677
								// Reference by slug
3678
								else {
3679
									$v_data = false;
3680
3681
									if ( false !== $find_rel_params ) {
3682
										$rel_params = $find_rel_params;
3683
										$rel_params[ 'where' ] = $wpdb->prepare( $rel_params[ 'where' ], array( $v, $v ) );
3684
3685
										$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...
3686
3687
										$v_data = $search_data->fetch( $v );
3688
									}
3689
3690
									if ( !empty( $v_data ) && isset( $v_data[ $search_data->field_id ] ) ) {
3691
										$v = (int) $v_data[ $search_data->field_id ];
3692
									}
3693
									// Allow tagging for Pods objects
3694
									elseif ( $is_taggable && 'pods' == $data_mode ) {
3695
										$tag_data = array(
3696
											$search_data->field_index => $v
3697
										);
3698
3699
										if ( 'post_type' == $search_data->pod_data[ 'type' ] ) {
3700
											$tag_data[ 'post_status' ] = 'publish';
3701
										}
3702
3703
										/**
3704
										 * Filter for changing tag before adding new item.
3705
										 *
3706
										 * @param array $tag_data Fields for creating new item.
3707
										 * @param int $v Field ID of tag.
3708
										 * @param obj $search_data Search object for tag.
3709
										 * @param string $field Table info for field.
3710
										 * @param array	$pieces Field array.
3711
										 *
3712
										 * @since 2.3.19
3713
										 */
3714
										$tag_data = apply_filters( 'pods_api_save_pod_item_taggable_data', $tag_data, $v, $search_data, $field, compact( $pieces ) );
3715
3716
										// Save $v to a new item on related object
3717
										$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...
3718
3719
										// @todo Support non-Pods for tagging
3720
									}
3721
								}
3722
							}
3723
							elseif ( $is_file_field && isset( $v[ 'id' ] ) ) {
3724
								$v = (int) $v[ 'id' ];
3725
							}
3726
							else {
3727
								continue;
3728
							}
3729
3730
							if ( !empty( $v ) && !in_array( $v, $value_ids ) ) {
3731
								$value_ids[] = $v;
3732
							}
3733
                        }
3734
                    }
3735
3736
                    $value_ids = array_unique( array_filter( $value_ids ) );
3737
3738
                    // Limit values
3739
                    if ( 0 < $related_limit && !empty( $value_ids ) )
3740
                        $value_ids = array_slice( $value_ids, 0, $related_limit );
3741
3742
                    // Get current values
3743
                    if ( 'pick' == $type && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ] ) )
3744
                        $related_ids = PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ];
3745
                    else
3746
                        $related_ids = $this->lookup_related_items( $fields[ $field ][ 'id' ], $pod[ 'id' ], $params->id, $fields[ $field ], $pod );
3747
3748
                    // Get ids to remove
3749
                    $remove_ids = array_diff( $related_ids, $value_ids );
3750
3751
                    // Delete relationships
3752
                    if ( !empty( $remove_ids ) )
3753
                        $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] );
3754
3755
                    // Save relationships
3756
                    if ( !empty( $value_ids ) )
3757
                        $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] );
3758
3759
                    // Run save function for field type (where needed)
3760
                    PodsForm::save( $type, $values, $params->id, $field, array_merge( $fields[ $field ], $fields[ $field ][ 'options' ] ), array_merge( $fields, $object_fields ), $pod, $params );
3761
                }
3762
3763
                // Unset data no longer needed
3764
                if ( 'pick' == $type ) {
3765
                    foreach ( $data as $field => $values ) {
3766
                        if ( isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) ) {
3767
                            unset( PodsField_Pick::$related_data[ PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'related_field' ][ 'id' ] ] );
3768
                            unset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] );
3769
                        }
3770
                    }
3771
                }
3772
            }
3773
        }
3774
3775
        if ( !$no_conflict )
3776
            pods_no_conflict_off( $pod[ 'type' ] );
3777
3778
        if ( false === $bypass_helpers ) {
3779
            $pieces = compact( $pieces );
3780
3781
            // Plugin hooks
3782
            $this->do_hook( 'post_save_pod_item', $pieces, $is_new_item, $params->id );
3783
            $this->do_hook( "post_save_pod_item_{$params->pod}", $pieces, $is_new_item, $params->id );
3784
3785
            if ( $is_new_item ) {
3786
                $this->do_hook( 'post_create_pod_item', $pieces, $params->id );
3787
                $this->do_hook( "post_create_pod_item_{$params->pod}", $pieces, $params->id );
3788
            }
3789
            else {
3790
                $this->do_hook( 'post_edit_pod_item', $pieces, $params->id );
3791
                $this->do_hook( "post_edit_pod_item_{$params->pod}", $pieces, $params->id );
3792
            }
3793
3794
            // Call any post-save helpers (if not bypassed)
3795
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3796 View Code Duplication
                if ( !empty( $post_save_helpers ) ) {
3797
                    pods_deprecated( sprintf( __( 'Post-save helpers are deprecated, use the action pods_post_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3798
3799
                    foreach ( $post_save_helpers as $helper ) {
3800
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3801
3802
                        if ( false !== $helper && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
3803
                            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...
3804
                    }
3805
                }
3806
            }
3807
        }
3808
3809
        // Clear cache
3810
        pods_cache_clear( $params->id, 'pods_items_' . $pod[ 'name' ] );
3811
3812
		if ( $params->clear_slug_cache && !empty( $pod[ 'field_slug' ] ) ) {
3813
			$slug = pods( $pod[ 'name' ], $params->id )->field( $pod[ 'field_slug' ] );
3814
3815
			if ( 0 < strlen( $slug ) ) {
3816
        		pods_cache_clear( $slug, 'pods_items_' . $pod[ 'name' ] );
3817
			}
3818
		}
3819
3820
        // Clear WP meta cache
3821
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3822
            $meta_type = $pod[ 'type' ];
3823
3824
            if ( 'post_type' == $meta_type )
3825
                $meta_type = 'post';
3826
3827
            wp_cache_delete( $params->id, $meta_type . '_meta' );
3828
            wp_cache_delete( $params->id, 'pods_' . $meta_type . '_meta' );
3829
        }
3830
3831
        // Success! Return the id
3832
        return $params->id;
3833
3834
    }
3835
3836
    /**
3837
     * @see PodsAPI::save_pod_item
3838
     * Add multiple pod items
3839
     *
3840
     * $params['pod'] string The Pod name (pod or pod_id is required)
3841
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
3842
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
3843
     *
3844
     * $data['id'] int The item ID (optional)
3845
     * $data['data'] array An associative array of field names + values
3846
     *
3847
     * @param array|object $params An associative array of parameters, data excluded
3848
     * @param array $data An associative array of pod ids and field names + values (arrays of field data)
3849
     *
3850
     * @return int The item ID
3851
     * @since 2.0
3852
     */
3853
    public function save_pod_items ( $params, $data ) {
3854
        $params = (object) $params;
3855
3856
        $ids = array();
3857
3858
        foreach ( $data as $fields ) {
3859
            $params->data = $fields;
3860
3861
            if ( isset( $fields[ 'id' ] ) && isset( $fields[ 'data' ] ) ) {
3862
                $params->id = $fields[ 'id' ];
3863
                $params->data = $fields[ 'data' ];
3864
            }
3865
3866
            $ids[] = $this->save_pod_item( $params );
3867
        }
3868
3869
        return $ids;
3870
    }
3871
3872
	/**
3873
	 * Get the fields that have changed during a save
3874
	 *
3875
	 * @param array $pieces Pieces array from save_pod_item
3876
	 *
3877
	 * @return array Array of fields and values that have changed
3878
	 */
3879
	public function get_changed_fields( $pieces ) {
3880
3881
		$fields = $pieces[ 'fields' ];
3882
		$fields_active = $pieces[ 'fields_active' ];
3883
3884
		$fields_changed = array();
3885
3886
		if ( 0 < $pieces[ 'params' ]->id ) {
3887
			$pod = pods( $pieces[ 'params' ]->pod, $pieces[ 'params' ]->id );
3888
3889
			foreach ( $fields_active as $field ) {
3890
				if ( isset( $fields[ $field ] ) && $pod->raw( $field ) != $fields[ $field ][ 'value' ] ) {
3891
					$fields_changed[ $field ] = $fields[ $field ][ 'value' ];
3892
				}
3893
			}
3894
		}
3895
3896
		return $fields_changed;
3897
3898
	}
3899
3900
    /**
3901
     * Save relationships
3902
     *
3903
     * @param int $id ID of item
3904
     * @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...
3905
     * @param array $pod Pod data
3906
     * @param array $field Field data
3907
     */
3908
    public function save_relationships ( $id, $related_ids, $pod, $field ) {
3909
        // Get current values
3910
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ] ) )
3911
            $current_ids = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ];
3912
        else
3913
            $current_ids = $this->lookup_related_items( $field[ 'id' ], $pod[ 'id' ], $id, $field, $pod );
3914
3915
        if ( !is_array( $related_ids ) )
3916
            $related_ids = implode( ',', $related_ids );
3917
3918
        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...
3919
            $related_ids[ $k ] = (int) $related_id;
3920
        }
3921
3922
        $related_ids = array_unique( array_filter( $related_ids ) );
3923
3924
        $related_limit = (int) pods_var_raw( $field[ 'type' ] . '_limit', $field[ 'options' ], 0 );
3925
3926 View Code Duplication
        if ( 'single' == pods_var_raw( $field[ 'type' ] . '_format_type', $field[ 'options' ] ) )
3927
            $related_limit = 1;
3928
3929
        // Limit values
3930
        if ( 0 < $related_limit && !empty( $related_ids ) )
3931
            $related_ids = array_slice( $related_ids, 0, $related_limit );
3932
3933
        // Post Types, Media, Users, and Comments (meta-based)
3934 View Code Duplication
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3935
            $object_type = $pod[ 'type' ];
3936
3937
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
3938
                $object_type = 'post';
3939
            elseif ( 'taxonomy' == $object_type )
3940
                $object_type = 'term';
3941
3942
            delete_metadata( $object_type, $id, $field[ 'name' ] );
3943
3944
            if ( !empty( $related_ids ) ) {
3945
                update_metadata( $object_type, $id, '_pods_' . $field[ 'name' ], $related_ids );
3946
3947
                foreach ( $related_ids as $related_id ) {
3948
                    add_metadata( $object_type, $id, $field[ 'name' ], $related_id );
3949
                }
3950
            }
3951
            else
3952
                delete_metadata( $object_type, $id, '_pods_' . $field[ 'name' ] );
3953
        }
3954
        // Custom Settings Pages (options-based)
3955
        elseif ( 'settings' == $pod[ 'type' ] ) {
3956
            if ( !empty( $related_ids ) )
3957
                update_option( $pod[ 'name' ] . '_' . $field[ 'name' ], $related_ids );
3958
            else
3959
                delete_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
3960
        }
3961
3962
        $related_pod_id = $related_field_id = 0;
3963
3964
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && !empty( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ] ) ) {
3965
            $related_pod_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_pod' ][ 'id' ];
3966
            $related_field_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ][ 'id' ];
3967
        }
3968
3969
        // Relationships table
3970
        if ( !pods_tableless() ) {
3971
            $related_weight = 0;
3972
3973
            foreach ( $related_ids as $related_id ) {
3974
                if ( in_array( $related_id, $current_ids ) ) {
3975
                    pods_query( "
3976
                        UPDATE `@wp_podsrel`
3977
                        SET
3978
                            `pod_id` = %d,
3979
                            `field_id` = %d,
3980
                            `item_id` = %d,
3981
                            `related_pod_id` = %d,
3982
                            `related_field_id` = %d,
3983
                            `related_item_id` = %d,
3984
                            `weight` = %d
3985
                        WHERE
3986
                            `pod_id` = %d
3987
                            AND `field_id` = %d
3988
                            AND `item_id` = %d
3989
                            AND `related_item_id` = %d
3990
                    ", array(
3991
                        $pod[ 'id' ],
3992
                        $field[ 'id' ],
3993
                        $id,
3994
                        $related_pod_id,
3995
                        $related_field_id,
3996
                        $related_id,
3997
                        $related_weight,
3998
3999
                        $pod[ 'id' ],
4000
                        $field[ 'id' ],
4001
                        $id,
4002
                        $related_id,
4003
                    ) );
4004
                }
4005
                else {
4006
                    pods_query( "
4007
                        INSERT INTO `@wp_podsrel`
4008
                            (
4009
                                `pod_id`,
4010
                                `field_id`,
4011
                                `item_id`,
4012
                                `related_pod_id`,
4013
                                `related_field_id`,
4014
                                `related_item_id`,
4015
                                `weight`
4016
                            )
4017
                        VALUES ( %d, %d, %d, %d, %d, %d, %d )
4018
                    ", array(
4019
                        $pod[ 'id' ],
4020
                        $field[ 'id' ],
4021
                        $id,
4022
                        $related_pod_id,
4023
                        $related_field_id,
4024
                        $related_id,
4025
                        $related_weight
4026
                    ) );
4027
                }
4028
4029
                $related_weight++;
4030
            }
4031
        }
4032
    }
4033
4034
    /**
4035
     * Duplicate a Pod
4036
     *
4037
     * $params['id'] int The Pod ID
4038
     * $params['name'] string The Pod name
4039
     * $params['new_name'] string The new Pod name
4040
     *
4041
     * @param array $params An associative array of parameters
4042
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4043
     *
4044
     * @return int New Pod ID
4045
     * @since 2.3
4046
     */
4047
    public function duplicate_pod ( $params, $strict = false ) {
4048 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4049
            if ( is_numeric( $params ) )
4050
                $params = array( 'id' => $params );
4051
            else
4052
                $params = array( 'name' => $params );
4053
4054
            $params = (object) pods_sanitize( $params );
4055
        }
4056
        else
4057
            $params = (object) pods_sanitize( $params );
4058
4059
        $params->table_info = false;
4060
4061
        $pod = $this->load_pod( $params, $strict );
4062
4063
        if ( empty( $pod ) ) {
4064
            if ( false !== $strict )
4065
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4066
4067
            return false;
4068
        }
4069
        elseif ( in_array( $pod[ 'type' ], array( 'media', 'user', 'comment' ) ) ) {
4070
            if ( false !== $strict )
4071
                return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this );
4072
4073
            return false;
4074
        }
4075
        elseif ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod[ 'object' ] ) ) {
4076
			$pod[ 'object' ] = '';
4077
        }
4078
4079
        unset( $pod[ 'id' ] );
4080
4081
        if ( isset( $params->new_name ) )
4082
            $pod[ 'name' ] = $params->new_name;
4083
4084
        $try = 1;
4085
4086
        $check_name = $pod[ 'name' ];
4087
        $new_label = $pod[ 'label' ];
4088
4089 View Code Duplication
        while ( $this->load_pod( array( 'name' => $check_name, 'table_info' => false ), false ) ) {
4090
            $try++;
4091
4092
            $check_name = $pod[ 'name' ] . $try;
4093
            $new_label = $pod[ 'label' ] . $try;
4094
        }
4095
4096
        $pod[ 'name' ] = $check_name;
4097
        $pod[ 'label' ] = $new_label;
4098
4099
        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
4100
            unset( $pod[ 'fields' ][ $field ][ 'id' ] );
4101
        }
4102
4103
        return $this->save_pod( $pod );
4104
    }
4105
4106
    /**
4107
     * Duplicate a Field
4108
     *
4109
     * $params['pod_id'] int The Pod ID
4110
     * $params['pod'] string The Pod name
4111
     * $params['id'] int The Field ID
4112
     * $params['name'] string The Field name
4113
     * $params['new_name'] string The new Field name
4114
     *
4115
     * @param array $params An associative array of parameters
4116
     * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error
4117
     *
4118
     * @return int New Field ID
4119
     * @since 2.3.10
4120
     */
4121
	public function duplicate_field( $params, $strict = false ) {
4122
4123
		if ( !is_object( $params ) && !is_array( $params ) ) {
4124
			if ( is_numeric( $params ) ) {
4125
				$params = array( 'id' => $params );
4126
			}
4127
			else {
4128
				$params = array( 'name' => $params );
4129
			}
4130
		}
4131
4132
		$params = (object) pods_sanitize( $params );
4133
4134
		$params->table_info = false;
4135
4136
		$field = $this->load_field( $params, $strict );
4137
4138
		if ( empty( $field ) ) {
4139
			if ( false !== $strict ) {
4140
				return pods_error( __( 'Field not found', 'pods' ), $this );
4141
			}
4142
4143
			return false;
4144
		}
4145
4146
		unset( $field[ 'id' ] );
4147
4148
		if ( isset( $params->new_name ) ) {
4149
			$field[ 'name' ] = $params->new_name;
4150
		}
4151
4152
		$try = 1;
4153
4154
		$check_name = $field[ 'name' ];
4155
		$new_label = $field[ 'label' ];
4156
4157 View Code Duplication
		while ( $this->load_field( array( 'pod_id' => $field[ 'pod_id' ], 'name' => $check_name, 'table_info' => false ), false ) ) {
4158
			$try++;
4159
4160
			$check_name = $field[ 'name' ] . $try;
4161
			$new_label = $field[ 'label' ] . $try;
4162
		}
4163
4164
		$field[ 'name' ] = $check_name;
4165
		$field[ 'label' ] = $new_label;
4166
4167
		return $this->save_field( $field );
4168
4169
	}
4170
4171
    /**
4172
     * @see PodsAPI::save_pod_item
4173
     *
4174
     * Duplicate a pod item
4175
     *
4176
     * $params['pod'] string The Pod name
4177
     * $params['id'] int The item's ID from the wp_pods_* table
4178
     *
4179
     * @param array $params An associative array of parameters
4180
     *
4181
     * @return int The table row ID
4182
     * @since 1.12
4183
     */
4184
    public function duplicate_pod_item ( $params ) {
4185
        $params = (object) pods_sanitize( $params );
4186
4187
        $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ) );
4188
4189
        if ( false === $pod )
4190
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4191
4192
        $pod = pods( $params->pod, $params->id );
4193
4194
        $params->pod = $pod->pod;
4195
        $params->pod_id = $pod->pod_id;
4196
4197
        $fields = (array) pods_var_raw( 'fields', $pod->pod_data, array(), null, true );
4198
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4199
4200
        if ( !empty( $object_fields ) )
4201
            $fields = array_merge( $object_fields, $fields );
4202
4203
        $save_params = array(
4204
            'pod' => $params->pod,
4205
            'data' => array()
4206
        );
4207
4208
        foreach ( $fields as $field ) {
4209
            $value = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'ids' ) );
4210
4211
            if ( !empty( $value ) || ( !is_array( $value ) && 0 < strlen( $value ) ) )
4212
                $save_params[ 'data' ][ $field[ 'name' ] ] = $value;
4213
        }
4214
4215
        $save_params = $this->do_hook( 'duplicate_pod_item', $save_params, $pod->pod, $pod->id(), $params );
4216
4217
        $id = $this->save_pod_item( $save_params );
4218
4219
        return $id;
4220
    }
4221
4222
    /**
4223
     * @see pods()
4224
     *
4225
     * Export a pod item
4226
     *
4227
     * $params['pod'] string The Pod name
4228
     * $params['id'] int The item's ID from the wp_pods_* table
4229
     * $params['fields'] array The fields to export
4230
     * $params['depth'] int How many levels deep to export data
4231
     *
4232
     * @param array $params An associative array of parameters
4233
     * @param object $pod (optional) Pods object
4234
     *
4235
     * @return int The table row ID
4236
     * @since 1.12
4237
     */
4238
    public function export_pod_item ( $params, $pod = null ) {
4239
        if ( !is_object( $pod ) || 'Pods' != get_class( $pod ) ) {
4240
            if ( empty( $params ) )
4241
                return false;
4242
4243
            $params = (object) pods_sanitize( $params );
4244
4245
            $pod = pods( $params->pod, $params->id, false );
4246
4247
            if ( empty( $pod ) )
4248
                return false;
4249
        }
4250
4251
        $fields = (array) pods_var_raw( 'fields', $params, array(), null, true );
4252
        $depth = (int) pods_var_raw( 'depth', $params, 2, null, true );
4253
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4254
        $flatten = (boolean) pods_var( 'flatten', $params, false, null, true );
4255
4256
        if ( empty( $fields ) ) {
4257
            $fields = $pod->fields;
4258
            $fields = array_merge( $fields, $object_fields );
4259
        }
4260
4261
        $data = $this->export_pod_item_level( $pod, $fields, $depth, $flatten );
4262
4263
        $data = $this->do_hook( 'export_pod_item', $data, $pod->pod, $pod->id(), $pod, $fields, $depth, $flatten );
4264
4265
        return $data;
4266
    }
4267
4268
    /**
4269
     * Export a pod item by depth level
4270
     *
4271
     * @param Pods $pod Pods object
4272
     * @param array $fields Fields to export
4273
     * @param int $depth Depth limit
4274
     * @param boolean $flatten Whether to flatten arrays for display
4275
     * @param int $current_depth Current depth level
4276
     *
4277
     * @return array Data array
4278
     *
4279
     * @since 2.3
4280
     */
4281
    private function export_pod_item_level ( $pod, $fields, $depth, $flatten = false, $current_depth = 1 ) {
4282
        $tableless_field_types = PodsForm::tableless_field_types();
4283
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4284
4285
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4286
4287
        $export_fields = array();
4288
4289
        foreach ( $fields as $k => $field ) {
4290
            if ( !is_array( $field ) ) {
4291
                $field = array(
4292
                    'id' => 0,
4293
                    'name' => $field
4294
                );
4295
            }
4296
4297
            if ( isset( $pod->fields[ $field[ 'name' ] ] ) ) {
4298
                $field = $pod->fields[ $field[ 'name' ] ];
4299
                $field[ 'lookup_name' ] = $field[ 'name' ];
4300
4301
                if ( in_array( $field[ 'type' ], $tableless_field_types ) && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4302
                    if ( 'pick' == $field[ 'type' ] ) {
4303
                        if ( empty( $field[ 'table_info' ] ) )
4304
                            $field[ 'table_info' ] = $this->get_table_info( pods_var_raw( 'pick_object', $field ), pods_var_raw( 'pick_val', $field ), null, null, $field );
4305
4306
                        if ( !empty( $field[ 'table_info' ] ) )
4307
                            $field[ 'lookup_name' ] .= '.' . $field[ 'table_info' ][ 'field_id' ];
4308
                    }
4309
                    elseif ( in_array( $field[ 'type' ], PodsForm::file_field_types() ) )
4310
                        $field[ 'lookup_name' ] .= '.guid';
4311
                }
4312
4313
                $export_fields[ $field[ 'name' ] ] = $field;
4314
            }
4315
            elseif ( isset( $object_fields[ $field[ 'name' ] ] ) ) {
4316
                $field = $object_fields[ $field[ 'name' ] ];
4317
                $field[ 'lookup_name' ] = $field[ 'name' ];
4318
4319
                $export_fields[ $field[ 'name' ] ] = $field;
4320
            }
4321
            elseif ( $field[ 'name' ] == $pod->pod_data[ 'field_id' ] ) {
4322
                $field[ 'type' ] = 'number';
4323
                $field[ 'lookup_name' ] = $field[ 'name' ];
4324
4325
                $export_fields[ $field[ 'name' ] ] = $field;
4326
            }
4327
        }
4328
4329
        $data = array();
4330
4331
        foreach ( $export_fields as $field ) {
4332
            // Return IDs (or guid for files) if only one level deep
4333
            if ( 1 == $depth )
4334
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'lookup_name' ], 'output' => 'arrays' ) );
4335
            // Recurse depth levels for pick fields if $depth allows
4336
            elseif ( ( -1 == $depth || $current_depth < $depth ) && 'pick' == $field[ 'type' ] && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4337
                $related_data = array();
4338
4339
                $related_ids = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'ids' ) );
4340
4341
                if ( !empty( $related_ids ) ) {
4342
                    $related_ids = (array) $related_ids;
4343
4344
                    $pick_object = pods_var_raw( 'pick_object', $field );
4345
4346
                    $related_pod = pods( pods_var_raw( 'pick_val', $field ), null, false );
4347
4348
                    // If this isn't a Pod, return data exactly as Pods does normally
4349
                    if ( empty( $related_pod ) || ( 'pod' != $pick_object && $pick_object != $related_pod->pod_data[ 'type' ] ) || $related_pod->pod == $pod->pod )
4350
                        $related_data = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4351
                    else {
4352
                        $related_object_fields = (array) pods_var_raw( 'object_fields', $related_pod->pod_data, array(), null, true );
4353
4354
                        $related_fields = array_merge( $related_pod->fields, $related_object_fields );
4355
4356
                        foreach ( $related_ids as $related_id ) {
4357
                            if ( $related_pod->fetch( $related_id ) ) {
4358
                                $related_item = $this->export_pod_item_level( $related_pod, $related_fields, $depth, $flatten, ( $current_depth + 1 ) );
4359
4360
                                $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 ) );
4361
                            }
4362
                        }
4363
4364
                        if ( $flatten && !empty( $related_data ) )
4365
                            $related_data = pods_serial_comma( array_values( $related_data ), array( 'and' => '', 'field_index' => $related_pod->pod_data[ 'field_index' ] ) );
4366
                    }
4367
                }
4368
4369
                $data[ $field[ 'name' ] ] = $related_data;
4370
            }
4371
            // Return data exactly as Pods does normally
4372
            else
4373
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4374
4375
            if ( $flatten && is_array( $data[ $field[ 'name' ] ] ) )
4376
                $data[ $field[ 'name' ] ] = pods_serial_comma( $data[ $field[ 'name' ] ], array( 'field' => $field[ 'name' ], 'fields' => $export_fields, 'and' => '' ) );
4377
        }
4378
4379
	$data[ 'id' ] = (int) $pod->id();
4380
        return $data;
4381
    }
4382
4383
    /**
4384
     * Reorder a Pod
4385
     *
4386
     * $params['pod'] string The Pod name
4387
     * $params['field'] string The field name of the field to reorder
4388
     * $params['order'] array The key => value array of items to reorder (key should be an integer)
4389
     *
4390
     * @param array $params An associative array of parameters
4391
     *
4392
     * @return bool
4393
     *
4394
     * @since 1.9.0
4395
     */
4396
    public function reorder_pod_item ( $params ) {
4397
        $params = (object) pods_sanitize( $params );
4398
4399
        // @deprecated 2.0
4400
        if ( isset( $params->datatype ) ) {
4401
            pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4402
4403
            $params->pod = $params->datatype;
4404
4405
            unset( $params->datatype );
4406
        }
4407
4408
        if ( null === pods_var_raw( 'pod', $params, null, null, true ) )
4409
            return pods_error( __( '$params->pod is required', 'pods' ), $this );
4410
4411
        if ( !is_array( $params->order ) )
4412
            $params->order = explode( ',', $params->order );
4413
4414
        $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
4415
4416
        $params->name = $pod[ 'name' ];
4417
4418
        if ( false === $pod )
4419
            return pods_error( __( 'Pod is required', 'pods' ), $this );
4420
4421
        foreach ( $params->order as $order => $id ) {
4422
            if ( isset( $pod[ 'fields' ][ $params->field ] ) || isset( $pod[ 'object_fields' ][ $params->field ] ) ) {
4423
                if ( 'table' == $pod[ 'storage' ] && ( !pods_tableless() ) ) {
4424
                    if ( isset( $pod[ 'fields' ][ $params->field ] ) )
4425
                        pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" );
4426
                    else
4427
                        pods_query( "UPDATE `{$pod['table']}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `{$pod['field_id']}` = " . pods_absint( $id ) . " LIMIT 1" );
4428
                }
4429
                else
4430
                    $this->save_pod_item( array( 'pod' => $params->pod, 'pod_id' => $params->pod_id, 'id' => $id, 'data' => array( $params->field => pods_absint( $order ) ) ) );
4431
            }
4432
        }
4433
4434
        return true;
4435
    }
4436
4437
    /**
4438
     *
4439
     * Delete all content for a Pod
4440
     *
4441
     * $params['id'] int The Pod ID
4442
     * $params['name'] string The Pod name
4443
     *
4444
     * @param array $params An associative array of parameters
4445
     * @param array $pod Pod data
4446
     *
4447
     * @return bool
4448
     *
4449
     * @uses pods_query
4450
     * @uses pods_cache_clear
4451
     *
4452
     * @since 1.9.0
4453
     */
4454
    public function reset_pod ( $params, $pod = false ) {
4455
        $params = (object) pods_sanitize( $params );
4456
4457
        $params->table_info = true;
4458
4459
        if ( empty( $pod ) )
4460
            $pod = $this->load_pod( $params );
4461
4462
        if ( false === $pod )
4463
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4464
4465
        $params->id = $pod[ 'id' ];
4466
        $params->name = $pod[ 'name' ];
4467
4468 View Code Duplication
        if ( !pods_tableless() ) {
4469
            if ( 'table' == $pod[ 'storage' ] ) {
4470
                try {
4471
                    pods_query( "TRUNCATE `@wp_pods_{$params->name}`", false );
4472
                }
4473
                catch ( Exception $e ) {
4474
                    // Allow pod to be reset if the table doesn't exist
4475
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4476
                        return pods_error( $e->getMessage(), $this );
4477
                }
4478
            }
4479
4480
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4481
        }
4482
4483
        // @todo Delete relationships from tableless relationships
4484
4485
        // Delete all posts/revisions from this post type
4486
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media' ) ) ) {
4487
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4488
4489
            $sql = "
4490
                DELETE `t`, `r`, `m`
4491
                FROM `{$pod['table']}` AS `t`
4492
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4493
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4494
                LEFT JOIN `{$pod['table']}` AS `r`
4495
                    ON `r`.`post_parent` = `t`.`{$pod['field_id']}` AND `r`.`post_status` = 'inherit'
4496
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4497
            ";
4498
4499
            pods_query( $sql, false );
4500
        }
4501
        // Delete all terms from this taxonomy
4502
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
4503
            if ( function_exists( 'get_term_meta' ) ) {
4504
                $sql = "
4505
                    DELETE `t`, `m`, `tt`, `tr`
4506
                    FROM `{$pod['table']}` AS `t`
4507
                    LEFT JOIN `{$pod['meta_table']}` AS `m`
4508
                        ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4509
                    " . $pod['join']['tt'] . "
4510
                    " . $pod['join']['tr'] . "
4511
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4512
                ";
4513
            } else {
4514
                $sql = "
4515
                    DELETE `t`, `tt`, `tr`
4516
                    FROM `{$pod['table']}` AS `t`
4517
                    " . $pod['join']['tt'] . "
4518
                    " . $pod['join']['tr'] . "
4519
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4520
                ";
4521
            }
4522
4523
            pods_query( $sql, false );
4524
        }
4525
        // Delete all users except the current one
4526
        elseif ( 'user' == $pod[ 'type' ] ) {
4527
            $sql = "
4528
                DELETE `t`, `m`
4529
                FROM `{$pod['table']}` AS `t`
4530
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4531
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4532
                WHERE `t`.`{$pod['field_id']}` != " . (int) get_current_user_id() . "
4533
            ";
4534
4535
            pods_query( $sql, false );
4536
        }
4537
        // Delete all comments
4538
        elseif ( 'comment' == $pod[ 'type' ] ) {
4539
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4540
4541
            $sql = "
4542
                DELETE `t`, `m`
4543
                FROM `{$pod['table']}` AS `t`
4544
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4545
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4546
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4547
            ";
4548
4549
            pods_query( $sql, false );
4550
        }
4551
4552
        pods_cache_clear( true ); // only way to reliably clear out cached data across an entire group
4553
4554
        return true;
4555
    }
4556
4557
    /**
4558
     * Delete a Pod and all its content
4559
     *
4560
     * $params['id'] int The Pod ID
4561
     * $params['name'] string The Pod name
4562
     *
4563
     * @param array $params An associative array of parameters
4564
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4565
     * @param bool $delete_all (optional) Whether to delete all content from a WP object
4566
     *
4567
     * @uses PodsAPI::load_pod
4568
     * @uses wp_delete_post
4569
     * @uses pods_query
4570
     *
4571
     * @return bool
4572
     * @since 1.7.9
4573
     */
4574
    public function delete_pod ( $params, $strict = false, $delete_all = false ) {
4575
        /**
4576
         * @var $wpdb wpdb
4577
         */
4578
        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...
4579
4580 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4581
            if ( is_numeric( $params ) )
4582
                $params = array( 'id' => $params );
4583
            else
4584
                $params = array( 'name' => $params );
4585
4586
            $params = (object) pods_sanitize( $params );
4587
        }
4588
        else
4589
            $params = (object) pods_sanitize( $params );
4590
4591
        $params->table_info = false;
4592
4593
        $pod = $this->load_pod( $params, $strict );
4594
4595
        if ( empty( $pod ) ) {
4596
            if ( false !== $strict )
4597
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4598
4599
            return false;
4600
        }
4601
4602
        $params->id = (int) $pod[ 'id' ];
4603
        $params->name = $pod[ 'name' ];
4604
4605
        foreach ( $pod[ 'fields' ] as $field ) {
4606
            $field[ 'pod' ] = $pod;
4607
4608
            $this->delete_field( $field, false );
4609
        }
4610
4611
        // Only delete the post once the fields are taken care of, it's not required anymore
4612
        $success = wp_delete_post( $params->id );
4613
4614
        if ( !$success )
4615
            return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this );
4616
4617
        // Reset content
4618
        if ( $delete_all )
4619
            $this->reset_pod( $params, $pod );
4620
4621 View Code Duplication
        if ( !pods_tableless() ) {
4622
            if ( 'table' == $pod[ 'storage' ] ) {
4623
                try {
4624
                    pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false );
4625
                }
4626
                catch ( Exception $e ) {
4627
                    // Allow pod to be deleted if the table doesn't exist
4628
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4629
                        return pods_error( $e->getMessage(), $this );
4630
                }
4631
            }
4632
4633
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4634
        }
4635
4636
        // @todo Delete relationships from tableless relationships
4637
4638
        // Delete any relationship references
4639
        $sql = "
4640
            DELETE `pm`
4641
            FROM `{$wpdb->postmeta}` AS `pm`
4642
            LEFT JOIN `{$wpdb->posts}` AS `p`
4643
                ON `p`.`post_type` = '_pods_field'
4644
                    AND `p`.`ID` = `pm`.`post_id`
4645
            LEFT JOIN `{$wpdb->postmeta}` AS `pm2`
4646
                ON `pm2`.`meta_key` = 'pick_object'
4647
                    AND `pm2`.`meta_value` = 'pod'
4648
                    AND `pm2`.`post_id` = `pm`.`post_id`
4649
            WHERE
4650
                `p`.`ID` IS NOT NULL
4651
                AND `pm2`.`meta_id` IS NOT NULL
4652
                AND `pm`.`meta_key` = 'pick_val'
4653
                AND `pm`.`meta_value` = '{$params->name}'
4654
        ";
4655
4656
        pods_query( $sql );
4657
4658
        $this->cache_flush_pods( $pod );
4659
4660
        return true;
4661
    }
4662
4663
    /**
4664
     * Drop a field within a Pod
4665
     *
4666
     * $params['id'] int The field ID
4667
     * $params['name'] int The field name
4668
     * $params['pod'] string The Pod name
4669
     * $params['pod_id'] string The Pod name
4670
     *
4671
     * @param array $params An associative array of parameters
4672
     * @param bool $table_operation Whether or not to handle table operations
4673
     *
4674
     * @uses PodsAPI::load_field
4675
     * @uses wp_delete_post
4676
     * @uses pods_query
4677
     *
4678
     * @return bool
4679
     * @since 1.7.9
4680
     */
4681
    public function delete_field ( $params, $table_operation = true ) {
4682
        /**
4683
         * @var $wpdb wpdb
4684
         */
4685
        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...
4686
4687
        $tableless_field_types = PodsForm::tableless_field_types();
4688
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4689
4690
        $params = (object) pods_sanitize( $params );
4691
4692
        if ( !isset( $params->pod ) )
4693
            $params->pod = '';
4694
4695
        if ( !isset( $params->pod_id ) )
4696
            $params->pod_id = 0;
4697
4698
        $pod = $params->pod;
4699
4700
        $save_pod = false;
4701
4702
        if ( !is_array( $pod ) )
4703
            $pod = $this->load_pod( array( 'name' => $pod, 'id' => $params->pod_id, 'table_info' => false ) );
4704
        else
4705
            $save_pod = true;
4706
4707
        if ( empty( $pod ) )
4708
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4709
4710
        $params->pod_id = $pod[ 'id' ];
4711
        $params->pod = $pod[ 'name' ];
4712
4713
        if ( !isset( $params->name ) )
4714
            $params->name = '';
4715
4716
        if ( !isset( $params->id ) )
4717
            $params->id = 0;
4718
4719
        $field = $this->load_field( array( 'name' => $params->name, 'id' => $params->id, 'pod' => $params->pod, 'pod_id' => $params->pod_id ) );
4720
4721
        if ( false === $field )
4722
            return pods_error( __( 'Field not found', 'pods' ), $this );
4723
4724
        $params->id = $field[ 'id' ];
4725
        $params->name = $field[ 'name' ];
4726
4727
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
4728
        $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params );
4729
4730
        if ( $table_operation && 'table' == $pod[ 'storage' ] && ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) )
4731
            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false );
4732
4733
        $success = wp_delete_post( $params->id );
4734
4735
        if ( !$success )
4736
            return pods_error( __( 'Field unable to be deleted', 'pods' ), $this );
4737
4738
        $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm
4739
            LEFT JOIN {$wpdb->posts} AS p
4740
                ON p.post_type = '_pods_field' AND p.ID = pm.post_id
4741
            WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) );
4742
4743
        if ( ( !pods_tableless() ) && $table_operation ) {
4744
            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 );
4745
        }
4746
4747
        // @todo Delete tableless relationship meta
4748
4749
        if ( true === $save_pod )
4750
            $this->cache_flush_pods( $pod );
4751
4752
        return true;
4753
    }
4754
4755
    /**
4756
     * Drop a Pod Object
4757
     *
4758
     * $params['id'] int The object ID
4759
     * $params['name'] string The object name
4760
     * $params['type'] string The object type
4761
     *
4762
     * @param array|object $params An associative array of parameters
4763
     *
4764
     * @uses wp_delete_post
4765
     *
4766
     * @return bool
4767
     * @since 2.0
4768
     */
4769
    public function delete_object ( $params ) {
4770
        $params = (object) $params;
4771
        $object = $this->load_object( $params );
4772
4773 View Code Duplication
        if ( empty( $object ) )
4774
            return pods_error( sprintf( __( "%s Object not found", 'pods' ), ucwords( $params->type ) ), $this );
4775
4776
        $success = wp_delete_post( $params->id );
4777
4778 View Code Duplication
        if ( !$success )
4779
            return pods_error( sprintf( __( "%s Object not deleted", 'pods' ), ucwords( $params->type ) ), $this );
4780
4781
        pods_transient_clear( 'pods_objects_' . $params->type );
4782
4783
        return true;
4784
    }
4785
4786
    /**
4787
     * @see PodsAPI::delete_object
4788
     *
4789
     * Drop a Pod Template
4790
     *
4791
     * $params['id'] int The template ID
4792
     * $params['name'] string The template name
4793
     *
4794
     * @param array $params An associative array of parameters
4795
     *
4796
     * @return bool
4797
     * @since 1.7.9
4798
     */
4799
    public function delete_template ( $params ) {
4800
        $params = (object) $params;
4801
        $params->type = 'template';
4802
        return $this->delete_object( $params );
4803
    }
4804
4805
    /**
4806
     * @see PodsAPI::delete_object
4807
     *
4808
     * Drop a Pod Page
4809
     *
4810
     * $params['id'] int The page ID
4811
     * $params['uri'] string The page URI
4812
     *
4813
     * @param array $params An associative array of parameters
4814
     *
4815
     * @return bool
4816
     * @since 1.7.9
4817
     */
4818
    public function delete_page ( $params ) {
4819
        $params = (object) $params;
4820
        if ( isset( $params->uri ) ) {
4821
            $params->name = $params->uri;
4822
            unset( $params->uri );
4823
        }
4824
        if ( isset( $params->name ) )
4825
            $params->name = trim( $params->name, '/' );
4826
        $params->type = 'page';
4827
        return $this->delete_object( $params );
4828
    }
4829
4830
    /**
4831
     * @see PodsAPI::delete_object
4832
     *
4833
     * Drop a Pod Helper
4834
     *
4835
     * $params['id'] int The helper ID
4836
     * $params['name'] string The helper name
4837
     *
4838
     * @param array $params An associative array of parameters
4839
     *
4840
     * @return bool
4841
     * @since 1.7.9
4842
     */
4843
    public function delete_helper ( $params ) {
4844
        $params = (object) $params;
4845
        $params->type = 'helper';
4846
        return $this->delete_object( $params );
4847
    }
4848
4849
    /**
4850
     * Drop a single pod item
4851
     *
4852
     * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter)
4853
     * $params['pod'] string (optional) The Pod name (used with id parameter)
4854
     * $params['pod_id'] int (optional) The Pod ID (used with id parameter)
4855
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
4856
     *
4857
     * @param array $params An associative array of parameters
4858
     * @param bool $wp Whether to run WP object delete action
4859
     *
4860
     * @return bool
4861
     * @since 1.7.9
4862
     */
4863
    public function delete_pod_item ( $params, $wp = true ) {
4864
        $params = (object) pods_sanitize( $params );
4865
4866
        // @deprecated 2.0
4867
        if ( isset( $params->datatype_id ) || isset( $params->datatype ) || isset( $params->tbl_row_id ) ) {
4868
            if ( isset( $params->tbl_row_id ) ) {
4869
                pods_deprecated( __( '$params->id instead of $params->tbl_row_id', 'pods' ), '2.0' );
4870
                $params->id = $params->tbl_row_id;
4871
                unset( $params->tbl_row_id );
4872
            }
4873
4874 View Code Duplication
            if ( isset( $params->pod_id ) ) {
4875
                pods_deprecated( __( '$params->id instead of $params->pod_id', 'pods' ), '2.0' );
4876
                $params->id = $params->pod_id;
4877
                unset( $params->pod_id );
4878
            }
4879
4880 View Code Duplication
            if ( isset( $params->dataype_id ) ) {
4881
                pods_deprecated( __( '$params->pod_id instead of $params->datatype_id', 'pods' ), '2.0' );
4882
                $params->pod_id = $params->dataype_id;
4883
                unset( $params->dataype_id );
4884
            }
4885
4886
            if ( isset( $params->datatype ) ) {
4887
                pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4888
                $params->pod = $params->datatype;
4889
                unset( $params->datatype );
4890
            }
4891
        }
4892
4893
        if ( !isset( $params->id ) )
4894
            return pods_error( __( 'Pod Item not found', 'pods' ), $this );
4895
4896
        $params->id = pods_absint( $params->id );
4897
4898
        if ( !isset( $params->pod ) )
4899
            $params->pod = '';
4900
4901
        if ( !isset( $params->pod_id ) )
4902
            $params->pod_id = 0;
4903
4904
        $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ) );
4905
4906
        if ( false === $pod )
4907
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4908
4909
        $params->pod_id = $pod[ 'id' ];
4910
        $params->pod = $pod[ 'name' ];
4911
4912
        // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls
4913
        $bypass_helpers = false;
4914
4915
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
4916
            $bypass_helpers = true;
4917
4918
        $pre_delete_helpers = $post_delete_helpers = array();
4919
4920
        if ( false === $bypass_helpers ) {
4921
            // Plugin hook
4922
            $this->do_hook( 'pre_delete_pod_item', $params, $pod );
4923
            $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod );
4924
4925
            // Call any pre-save helpers (if not bypassed)
4926 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
4927
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
4928
                    $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' );
4929
4930
                    foreach ( $helpers as $helper ) {
4931
                        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...
4932
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
4933
                    }
4934
                }
4935
4936
                if ( !empty( $pre_delete_helpers ) ) {
4937
                    pods_deprecated( sprintf( __( 'Pre-delete helpers are deprecated, use the action pods_pre_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
4938
4939
                    foreach ( $pre_delete_helpers as $helper ) {
4940
                        $helper = $this->load_helper( array( 'name' => $helper ) );
4941
4942
                        if ( false !== $helper )
4943
                            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...
4944
                    }
4945
                }
4946
            }
4947
        }
4948
4949
        // Delete object from relationship fields
4950
        $this->delete_object_from_relationships( $params->id, $pod );
4951
4952
        if ( 'table' == $pod[ 'storage' ] )
4953
            pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" );
4954
4955
        if ( $wp ) {
4956
            if ( 'taxonomy' == $pod['type'] ) {
4957
                $taxonomy = $pod['name'];
4958
4959
                if ( ! empty( $pod['object'] ) ) {
4960
                    $taxonomy = $pod['object'];
4961
                }
4962
4963
                wp_delete_term( $params->id, $taxonomy );
4964
            } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) {
4965
                $this->delete_wp_object( $pod['type'], $params->id );
4966
            }
4967
        }
4968
4969
        if ( false === $bypass_helpers ) {
4970
            // Plugin hook
4971
            $this->do_hook( 'post_delete_pod_item', $params, $pod );
4972
            $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod );
4973
4974
            // Call any post-save helpers (if not bypassed)
4975 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
4976
                if ( !empty( $post_delete_helpers ) ) {
4977
                    pods_deprecated( sprintf( __( 'Post-delete helpers are deprecated, use the action pods_post_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
4978
4979
                    foreach ( $post_delete_helpers as $helper ) {
4980
                        $helper = $this->load_helper( array( 'name' => $helper ) );
4981
4982
                        if ( false !== $helper )
4983
                            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...
4984
                    }
4985
                }
4986
            }
4987
        }
4988
4989
        pods_cache_clear( $params->id, 'pods_items_' . $params->pod );
4990
4991
        return true;
4992
    }
4993
4994
    /**
4995
     * Delete an object from tableless fields
4996
     *
4997
     * @param int $id
4998
     * @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...
4999
     * @param string $name
5000
     *
5001
     * @return bool
5002
     *
5003
     * @since 2.3
5004
     */
5005
    public function delete_object_from_relationships ( $id, $object, $name = null ) {
5006
        /**
5007
         * @var $pods_init \PodsInit
5008
         */
5009
        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...
5010
5011
        $pod = false;
5012
5013
        // Run any bidirectional delete operations
5014
        if ( is_array( $object ) )
5015
            $pod = $object;
5016
        elseif ( is_object( $pods_init ) )
5017
            $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...
5018
5019
        if ( !empty( $pod ) ) {
5020
            $object = $pod[ 'type' ];
5021
            $name = $pod[ 'name' ];
5022
5023
            foreach ( $pod[ 'fields' ] as $field ) {
5024
                PodsForm::delete( $field[ 'type' ], $id, $field[ 'name' ], array_merge( $field, $field[ 'options' ] ), $pod );
5025
            }
5026
        }
5027
5028
        // Lookup related fields (non-bidirectional)
5029
        $params = array(
5030
            'where' => array(
5031
                array(
5032
                    'key' => 'type',
5033
                    'value' => 'pick'
5034
                ),
5035
                array(
5036
                    'key' => 'pick_object',
5037
                    'value' => $object
5038
                )
5039
            )
5040
        );
5041
5042
        if ( !empty( $name ) && $name != $object ) {
5043
            $params[ 'where' ][] = array(
5044
                'key' => 'pick_val',
5045
                'value' => $name
5046
            );
5047
        }
5048
5049
        $fields = $this->load_fields( $params, false );
5050
5051
        if ( !empty( $pod ) && 'media' == $pod[ 'type' ] ) {
5052
            $params[ 'where' ] = array(
5053
                array(
5054
                    'key' => 'type',
5055
                    'value' => 'file'
5056
                )
5057
            );
5058
5059
            $fields = array_merge( $fields, $this->load_fields( $params, false ) );
5060
        }
5061
5062
        if ( is_array( $fields ) && !empty( $fields ) ) {
5063
            foreach ( $fields as $related_field ) {
5064
                $related_pod = $this->load_pod( array( 'id' => $related_field[ 'pod_id' ], 'fields' => false ), false );
5065
5066
                if ( empty( $related_pod ) )
5067
                    continue;
5068
5069
                $related_from = $this->lookup_related_items_from( $related_field[ 'id' ], $related_pod[ 'id' ], $id, $related_field, $related_pod );
5070
5071
                $this->delete_relationships( $related_from, $id, $related_pod, $related_field );
5072
            }
5073
        }
5074
5075
        if ( !empty( $pod ) && !pods_tableless() ) {
5076
            pods_query( "
5077
                DELETE FROM `@wp_podsrel`
5078
                WHERE
5079
                (
5080
                    `pod_id` = %d
5081
                    AND `item_id` = %d
5082
                )
5083
                OR (
5084
                    `related_pod_id` = %d
5085
                    AND `related_item_id` = %d
5086
                )
5087
            ", array(
5088
                $pod[ 'id' ],
5089
                $id,
5090
5091
                $pod[ 'id' ],
5092
                $id
5093
            ) );
5094
        }
5095
5096
        return true;
5097
    }
5098
5099
    /**
5100
     * Delete relationships
5101
     *
5102
     * @param int|array $related_id IDs for items to save
5103
     * @param int|array $id ID or IDs to remove
5104
     * @param array $related_pod Pod data
5105
     * @param array $related_field Field data
5106
     *
5107
     * @return void
5108
     *
5109
     * @since 2.3
5110
     */
5111
    public function delete_relationships ( $related_id, $id, $related_pod, $related_field ) {
5112
        if ( is_array( $related_id ) ) {
5113
            foreach ( $related_id as $rid ) {
5114
                $this->delete_relationships( $rid, $id, $related_pod, $related_field );
5115
            }
5116
5117
            return;
5118
        }
5119
5120
        if ( is_array( $id ) ) {
5121
            foreach ( $id as $rid ) {
5122
                $this->delete_relationships( $related_id, $rid, $related_pod, $related_field );
5123
            }
5124
5125
            return;
5126
        }
5127
5128
        $id = (int) $id;
5129
5130
        if ( empty( $id ) )
5131
            return;
5132
5133
        $related_ids = $this->lookup_related_items( $related_field[ 'id' ], $related_pod[ 'id' ], $related_id, $related_field, $related_pod );
5134
5135
        if ( empty( $related_ids ) )
5136
            return;
5137
        elseif ( !in_array( $id, $related_ids ) )
5138
            return;
5139
5140
	    if ( isset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] ) ) {
5141
		    // Delete relationship from cache
5142
		    unset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] );
5143
	    }
5144
        unset( $related_ids[ array_search( $id, $related_ids ) ] );
5145
5146
        $no_conflict = pods_no_conflict_check( $related_pod[ 'type' ] );
5147
5148
        if ( !$no_conflict )
5149
            pods_no_conflict_on( $related_pod[ 'type' ] );
5150
5151
        // Post Types, Media, Users, and Comments (meta-based)
5152 View Code Duplication
        if ( in_array( $related_pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
5153
            $object_type = $related_pod[ 'type' ];
5154
5155
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
5156
                $object_type = 'post';
5157
            elseif ( 'taxonomy' == $object_type )
5158
                $object_type = 'term';
5159
5160
            delete_metadata( $object_type, $related_id, $related_field[ 'name' ] );
5161
5162
            if ( !empty( $related_ids ) ) {
5163
                update_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ], $related_ids );
5164
5165
                foreach ( $related_ids as $rel_id ) {
5166
                    add_metadata( $object_type, $related_id, $related_field[ 'name' ], $rel_id );
5167
                }
5168
            }
5169
            else
5170
                delete_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ] );
5171
        }
5172
        // Custom Settings Pages (options-based)
5173
        elseif ( 'settings' == $related_pod[ 'type' ] ) {
5174
            if ( !empty( $related_ids ) )
5175
                update_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ], $related_ids );
5176
            else
5177
                delete_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ] );
5178
        }
5179
5180
        // Relationships table
5181
        if ( !pods_tableless() ) {
5182
            pods_query( "
5183
                DELETE FROM `@wp_podsrel`
5184
                WHERE
5185
                (
5186
                    `pod_id` = %d
5187
                    AND `field_id` = %d
5188
                    AND `item_id` = %d
5189
                    AND `related_item_id` = %d
5190
                )
5191
                OR (
5192
                    `related_pod_id` = %d
5193
                    AND `related_field_id` = %d
5194
                    AND `related_item_id` = %d
5195
                    AND `item_id` = %d
5196
                )
5197
            ", array(
5198
                $related_pod[ 'id' ],
5199
                $related_field[ 'id' ],
5200
                $related_id,
5201
                $id,
5202
5203
                $related_pod[ 'id' ],
5204
                $related_field[ 'id' ],
5205
                $related_id,
5206
                $id
5207
            ) );
5208
        }
5209
5210
        if ( !$no_conflict )
5211
            pods_no_conflict_off( $related_pod[ 'type' ] );
5212
    }
5213
5214
    /**
5215
     * Check if a Pod exists
5216
     *
5217
     * $params['id'] int Pod ID
5218
     * $params['name'] string Pod name
5219
     *
5220
     * @param array $params An associative array of parameters
5221
     *
5222
     * @return bool True if exists
5223
     *
5224
     * @since 1.12
5225
     */
5226
    public function pod_exists ( $params, $type = null ) {
5227
        if ( is_string( $params ) )
5228
            $params = array( 'name' => $params );
5229
5230
        $params = (object) pods_sanitize( $params );
5231
5232
        if ( !empty( $params->id ) || !empty( $params->name ) ) {
5233 View Code Duplication
            if ( !isset( $params->name ) )
5234
                $pod = get_post( $dummy = (int) $params->id );
5235
            else {
5236
                $pod = get_posts( array(
5237
                    'name' => $params->name,
5238
                    'post_type' => '_pods_pod',
5239
                    'posts_per_page' => 1
5240
                ) );
5241
            }
5242
5243
            if ( !empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) )
5244
                return true;
5245
        }
5246
5247
        return false;
5248
    }
5249
5250
    /**
5251
     * Load a Pod and all of its fields
5252
     *
5253
     * $params['id'] int The Pod ID
5254
     * $params['name'] string The Pod name
5255
     * $params['fields'] bool Whether to load fields (default is true)
5256
     *
5257
     * @param array|object $params An associative array of parameters or pod name as a string
5258
     * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work
5259
     *
5260
     * @return array|bool|mixed|void
5261
     * @since 1.7.9
5262
     */
5263
    public function load_pod ( $params, $strict = true ) {
5264
5265
        /**
5266
         * @var $sitepress SitePress
5267
		 * @var $wpdb wpdb
5268
         */
5269
        global $sitepress, $icl_adjust_id_url_filter_off, $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...
5270
5271
        $current_language = false;
5272
        $load_fields = true;
5273
5274
        // WPML support
5275 View Code Duplication
        if ( is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
5276
            $current_language = pods_sanitize( ICL_LANGUAGE_CODE );
5277
        // Polylang support
5278
        elseif ( function_exists( 'pll_current_language' ) )
5279
            $current_language = pll_current_language( 'slug' );
5280
5281
        if ( !is_array( $params ) && !is_object( $params ) )
5282
            $params = array( 'name' => $params, 'table_info' => false, 'fields' => true );
5283
5284
        if ( is_object( $params ) && isset( $params->fields ) && !$params->fields )
5285
            $load_fields = false;
5286
        elseif ( is_array( $params ) && isset( $params[ 'fields' ] ) && !$params[ 'fields' ] )
5287
            $load_fields = false;
5288
5289
	    $table_info = false;
5290
5291
        if ( is_object( $params ) && ! empty( $params->table_info ) )
5292
            $table_info = true;
5293
        elseif ( is_array( $params ) && ! empty( $params[ 'table_info' ] ) )
5294
            $table_info = true;
5295
5296
        $transient = 'pods_' . $wpdb->prefix . '_pod';
5297
5298
        if ( !empty( $current_language ) )
5299
            $transient .= '_' . $current_language;
5300
5301
        if ( !$load_fields )
5302
            $transient .= '_nofields';
5303
5304
        if ( $table_info )
5305
            $transient .= '_tableinfo';
5306
5307
        if ( is_object( $params ) && isset( $params->post_name ) ) {
5308
            $pod = false;
5309
5310
            if ( pods_api_cache() )
5311
                $pod = pods_transient_get( $transient . '_' . $params->post_name );
5312
5313 View Code Duplication
            if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5314
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
5315
                    $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5316
5317
                return $pod;
5318
            }
5319
5320
            $_pod = get_object_vars( $params );
5321
        }
5322
        else {
5323
            $params = (object) pods_sanitize( $params );
5324
5325 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) ) {
5326
                if ( $strict )
5327
                    return pods_error( 'Either Pod ID or Name are required', $this );
5328
5329
                return false;
5330
            }
5331
5332
            if ( isset( $params->name ) ) {
5333
                $pod = false;
5334
5335
				if ( '_pods_pod' == $params->name ) {
5336
					$pod = array(
5337
						'id' => 0,
5338
						'name' => $params->name,
5339
						'label' => __( 'Pods', 'pods' ),
5340
						'type' => 'post_type',
5341
						'storage' => 'meta',
5342
						'options' => array(
5343
							'label_singular' => __( 'Pod', 'pods' )
5344
						),
5345
						'fields' => array()
5346
					);
5347
				}
5348
				elseif ( '_pods_field' == $params->name ) {
5349
					$pod = array(
5350
						'id' => 0,
5351
						'name' => $params->name,
5352
						'label' => __( 'Pod Fields', 'pods' ),
5353
						'type' => 'post_type',
5354
						'storage' => 'meta',
5355
						'options' => array(
5356
							'label_singular' => __( 'Pod Field', 'pods' )
5357
						),
5358
						'fields' => array()
5359
					);
5360
				}
5361
                elseif ( pods_api_cache() )
5362
                    $pod = pods_transient_get( $transient . '_' . $params->name );
5363
5364 View Code Duplication
                if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5365
                    if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
5366
                        $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5367
5368
                    return $pod;
5369
                }
5370
            }
5371
5372 View Code Duplication
            if ( !isset( $params->name ) )
5373
                $pod = get_post( $dummy = (int) $params->id );
5374
            else {
5375
                $pod = get_posts( array(
5376
                    'name' => $params->name,
5377
                    'post_type' => '_pods_pod',
5378
                    'posts_per_page' => 1
5379
                ) );
5380
            }
5381
5382
            if ( empty( $pod ) ) {
5383
                if ( $strict )
5384
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
5385
5386
                return false;
5387
            }
5388
5389
            if ( is_array( $pod ) )
5390
                $pod = $pod[ 0 ];
5391
5392
            $_pod = get_object_vars( $pod );
5393
        }
5394
5395
        $pod = false;
5396
5397
        if ( pods_api_cache() )
5398
            $pod = pods_transient_get( $transient . '_' . $_pod[ 'post_name' ] );
5399
5400 View Code Duplication
        if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5401
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
5402
                $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5403
5404
            return $pod;
5405
        }
5406
5407
        $pod = array(
5408
            'id' => $_pod[ 'ID' ],
5409
            'name' => $_pod[ 'post_name' ],
5410
            'label' => $_pod[ 'post_title' ],
5411
            'description' => $_pod[ 'post_content' ]
5412
        );
5413
5414
        if ( strlen( $pod[ 'label' ] ) < 1 )
5415
            $pod[ 'label' ] = $pod[ 'name' ];
5416
5417
        // @todo update with a method to put all options in
5418
        $defaults = array(
5419
            'show_in_menu' => 1,
5420
            'type' => 'post_type',
5421
            'storage' => 'meta',
5422
            'object' => '',
5423
            'alias' => ''
5424
        );
5425
5426
        $pod[ 'options' ] = get_post_meta( $pod[ 'id' ] );
5427
5428 View Code Duplication
        foreach ( $pod[ 'options' ] as $option => $value ) {
5429
            if ( is_array( $value ) ) {
5430
                foreach ( $value as $k => $v ) {
5431
                    if ( !is_array( $v ) )
5432
                        $value[ $k ] = maybe_unserialize( $v );
5433
                }
5434
5435
                if ( 1 == count( $value ) )
5436
                    $value = current( $value );
5437
            }
5438
            else
5439
                $value = maybe_unserialize( $value );
5440
5441
            $pod[ 'options' ][ $option ] = $value;
5442
        }
5443
5444
        $pod[ 'options' ] = array_merge( $defaults, $pod[ 'options' ] );
5445
5446
        $pod[ 'type' ] = $pod[ 'options' ][ 'type' ];
5447
        $pod[ 'storage' ] = $pod[ 'options' ][ 'storage' ];
5448
        $pod[ 'object' ] = $pod[ 'options' ][ 'object' ];
5449
        $pod[ 'alias' ] = $pod[ 'options' ][ 'alias' ];
5450
5451
        unset( $pod[ 'options' ][ 'type' ] );
5452
        unset( $pod[ 'options' ][ 'storage' ] );
5453
        unset( $pod[ 'options' ][ 'object' ] );
5454
        unset( $pod[ 'options' ][ 'alias' ] );
5455
5456
        if ( $table_info )
5457
            $pod = array_merge( $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ), $pod );
5458
5459
        // Override old 'none' storage type
5460 View Code Duplication
        if ( 'taxonomy' == $pod['type'] && 'none' == $pod['storage'] && function_exists( 'get_term_meta' ) ) {
5461
            $pod[ 'storage' ] = 'meta';
5462
        }
5463
5464
        if ( isset( $pod[ 'pod' ] ) )
5465
            unset( $pod[ 'pod' ] );
5466
5467
        $pod[ 'fields' ] = array();
5468
5469
        $pod[ 'object_fields' ] = array();
5470
5471
        if ( 'pod' != $pod[ 'type' ] )
5472
            $pod[ 'object_fields' ] = $this->get_wp_object_fields( $pod[ 'type' ], $pod );
5473
5474
        $fields = get_posts( array(
5475
            'post_type' => '_pods_field',
5476
            'posts_per_page' => -1,
5477
            'nopaging' => true,
5478
            'post_parent' => $pod[ 'id' ],
5479
            'orderby' => 'menu_order',
5480
            'order' => 'ASC'
5481
        ) );
5482
5483
        if ( !empty( $fields ) ) {
5484
            foreach ( $fields as $field ) {
5485
                $field->pod = $pod[ 'name' ];
5486
                $field->table_info = $table_info;
5487
5488
                if ( $load_fields ) {
5489
                    $field = $this->load_field( $field );
5490
5491
                    $field = PodsForm::field_setup( $field, null, $field[ 'type' ] );
5492
                }
5493
                else {
5494
                    $field = array(
5495
                        'id' => $field->ID,
5496
                        'name' => $field->post_name,
5497
                        'label' => $field->post_title,
5498
                        'type' => get_post_meta( $field->ID, 'type', true )
5499
                    );
5500
                }
5501
5502
                $pod[ 'fields' ][ $field[ 'name' ] ] = $field;
5503
            }
5504
        }
5505
5506 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
5507
            pods_transient_set( $transient . '_' . $pod[ 'name' ], $pod );
5508
5509
        return $pod;
5510
    }
5511
5512
    /**
5513
     * Load a list of Pods based on filters specified.
5514
     *
5515
     * $params['type'] string/array Pod Type(s) to filter by
5516
     * $params['object'] string/array Pod Object(s) to filter by
5517
     * $params['options'] array Pod Option(s) key=>value array to filter by
5518
     * $params['orderby'] string ORDER BY clause of query
5519
     * $params['limit'] string Number of Pods to return
5520
     * $params['where'] string WHERE clause of query
5521
     * $params['ids'] string|array IDs of Objects
5522
     * $params['count'] boolean Return only a count of Pods
5523
     * $params['names'] boolean Return only an array of name => label
5524
     * $params['ids'] boolean Return only an array of ID => label
5525
     * $params['fields'] boolean Return pod fields with Pods (default is true)
5526
     * $params['key_names'] boolean Return pods keyed by name
5527
     *
5528
     * @param array $params An associative array of parameters
5529
     *
5530
     * @return array|mixed
5531
     *
5532
     * @uses PodsAPI::load_pod
5533
     *
5534
     * @since 2.0
5535
     */
5536
    public function load_pods ( $params = null ) {
5537
5538
        /**
5539
         * @var $sitepress SitePress
5540
         */
5541
        global $sitepress, $icl_adjust_id_url_filter_off;
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...
5542
5543
        $current_language = false;
5544
5545
        // WPML support
5546 View Code Duplication
        if ( is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
5547
            $current_language = pods_sanitize( ICL_LANGUAGE_CODE );
5548
        // Polylang support
5549
        elseif ( function_exists( 'pll_current_language' ) )
5550
            $current_language = pll_current_language( 'slug' );
5551
5552
        $params = (object) pods_sanitize( $params );
5553
5554
        $order = 'ASC';
5555
        $orderby = 'menu_order title';
5556
        $limit = -1;
5557
        $ids = false;
5558
5559
        $meta_query = array();
5560
        $cache_key = '';
5561
5562
        if ( isset( $params->type ) && !empty( $params->type ) ) {
5563
            if ( !is_array( $params->type ) )
5564
                $params->type = array( trim( $params->type ) );
5565
5566
            sort( $params->type );
5567
5568
            $meta_query[] = array(
5569
                'key' => 'type',
5570
                'value' => $params->type,
5571
                'compare' => 'IN'
5572
            );
5573
5574
            if ( 0 < count( $params->type ) )
5575
                $cache_key .= '_type_' . trim( implode( '_', $params->type ) );
5576
        }
5577
5578
        if ( isset( $params->object ) && !empty( $params->object ) ) {
5579
            if ( !is_array( $params->object ) )
5580
                $params->object = array( $params->object );
5581
5582
            $params->object = pods_trim( $params->object );
5583
5584
            sort( $params->object );
5585
5586
            $meta_query[] = array(
5587
                'key' => 'object',
5588
                'value' => $params->object,
5589
                'compare' => 'IN'
5590
            );
5591
5592
            if ( 1 == count( $params->object ) )
5593
                $cache_key .= '_object_' . trim( implode( '', $params->object ) );
5594
        }
5595
5596 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
5597
            foreach ( $params->options as $option => $value ) {
5598
                if ( !is_array( $value ) )
5599
                    $value = array( $value );
5600
5601
                $value = pods_trim( $value );
5602
5603
                sort( $value );
5604
5605
                $meta_query[] = array(
5606
                    'key' => $option,
5607
                    'value' => pods_sanitize( $value ),
5608
                    'compare' => 'IN'
5609
                );
5610
            }
5611
5612
            $cache_key = '';
5613
        }
5614
5615
        if ( isset( $params->where ) && is_array( $params->where ) )
5616
            $meta_query = array_merge( $meta_query, (array) $params->where );
5617
5618 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
5619
            $order = strtoupper( $params->order );
5620
5621
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
5622
            $orderby = strtoupper( $params->orderby );
5623
5624
        if ( isset( $params->limit ) && !empty( $params->limit ) )
5625
            $limit = pods_absint( $params->limit );
5626
5627
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
5628
            $ids = $params->ids;
5629
5630
            if ( !is_array( $ids ) )
5631
                $ids = explode( ',', $ids );
5632
        }
5633
5634
        if ( empty( $ids ) )
5635
            $ids = false;
5636
5637
        $pre_key = '';
5638
5639
        if ( !empty( $current_language ) )
5640
            $pre_key .= '_' . $current_language;
5641
5642
        if ( isset( $params->count ) && $params->count )
5643
            $pre_key .= '_count';
5644
5645
        if ( isset( $params->ids ) && $params->ids && !empty( $ids ) )
5646
            $pre_key .= '_ids_' . implode( '_', $ids );
5647
5648
        if ( isset( $params->names ) && $params->names )
5649
            $pre_key .= '_names';
5650
        elseif ( isset( $params->names_ids ) && $params->names_ids )
5651
            $pre_key .= '_names_ids';
5652
5653
        if ( isset( $params->key_names ) && $params->key_names )
5654
            $pre_key .= '_namekeys';
5655
5656
        if ( isset( $params->fields ) && !$params->fields )
5657
            $pre_key .= '_nofields';
5658
5659
        if ( isset( $params->table_info ) && $params->table_info )
5660
            $pre_key .= '_tableinfo';
5661
5662
5663
        $pre_key .= '_get';
5664
5665
        if ( empty( $cache_key ) )
5666
            $cache_key = 'pods' . $pre_key . '_all';
5667
        else
5668
            $cache_key = 'pods' . $pre_key . $cache_key;
5669
5670
        if ( 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 ) ) {
5671
            $the_pods = pods_transient_get( $cache_key );
5672
5673
            if ( false === $the_pods )
5674
                $the_pods = pods_cache_get( $cache_key, 'pods' );
5675
5676
            if ( !is_array( $the_pods ) && 'none' == $the_pods )
5677
                return array();
5678
            elseif ( false !== $the_pods )
5679
                return $the_pods;
5680
        }
5681
5682
        $the_pods = array();
5683
5684
		$args = array(
5685
			'post_type' => '_pods_pod',
5686
			'nopaging' => true,
5687
			'posts_per_page' => $limit,
5688
			'order' => $order,
5689
			'orderby' => $orderby,
5690
			'meta_query' => $meta_query,
5691
		);
5692
5693
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
5694
		if ( false != $ids ) {
5695
			$args[ 'post__in' ] = $ids;
5696
		}
5697
5698
		$_pods = get_posts( $args );
5699
5700
        $export_ignore = array(
5701
            'object_type',
5702
            'object_name',
5703
            'table',
5704
            'meta_table',
5705
            'pod_table',
5706
            'field_id',
5707
            'field_index',
5708
            'field_slug',
5709
            'field_type',
5710
            'field_parent',
5711
            'field_parent_select',
5712
            'meta_field_id',
5713
            'meta_field_index',
5714
            'meta_field_value',
5715
            'pod_field_id',
5716
            'pod_field_index',
5717
            'object_fields',
5718
            'join',
5719
            'where',
5720
            'where_default',
5721
            'orderby',
5722
            'pod',
5723
            'recurse',
5724
            'table_info',
5725
            'attributes',
5726
            'group',
5727
            'grouped',
5728
            'developer_mode',
5729
            'dependency',
5730
            'depends-on',
5731
            'excludes-on'
5732
        );
5733
5734
        $total_fields = 0;
5735
5736
        if ( isset( $params->count ) && $params->count )
5737
            $the_pods = count( $_pods );
5738
        else {
5739
            foreach ( $_pods as $pod ) {
5740
                if ( isset( $params->names ) && $params->names )
5741
                    $the_pods[ $pod->post_name ] = $pod->post_title;
5742
                elseif ( isset( $params->names_ids ) && $params->names_ids )
5743
                    $the_pods[ $pod->ID ] = $pod->post_name;
5744
                else {
5745
                    if ( isset( $params->fields ) && !$params->fields )
5746
                        $pod->fields = false;
5747
5748
                    $pod = $this->load_pod( $pod );
5749
5750
                    // Remove extra data not needed
5751
                    if ( pods_var( 'export', $params, false ) && ( !isset( $params->fields ) || $params->fields ) ) {
5752
                        foreach ( $export_ignore as $ignore ) {
5753
                            if ( isset( $pod[ $ignore ] ) )
5754
                                unset( $pod[ $ignore ] );
5755
                        }
5756
5757
                        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
5758
                            if ( isset( $pod[ 'fields' ][ $field ][ 'table_info' ] ) )
5759
                                unset( $pod[ 'fields' ][ $field ][ 'table_info' ] );
5760
                        }
5761
                    }
5762
5763
                    $total_fields += count( $pod[ 'fields' ] );
5764
5765
                    if ( isset( $params->key_names ) && $params->key_names )
5766
                        $the_pods[ $pod[ 'name' ] ] = $pod;
5767
                    else
5768
                        $the_pods[ $pod[ 'id' ] ] = $pod;
5769
                }
5770
            }
5771
        }
5772
5773
        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 ) ) {
5774
            // Too many Pods can cause issues with the DB when caching is not enabled
5775
            if ( 15 < count( $the_pods ) || 75 < count( $total_fields ) ) {
5776
                pods_transient_clear( $cache_key );
5777
5778 View Code Duplication
                if ( pods_api_cache() ) {
5779
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
5780
                        pods_cache_set( $cache_key, 'none', 'pods' );
5781
                    else
5782
                        pods_cache_set( $cache_key, $the_pods, 'pods' );
5783
                }
5784
            }
5785
            else {
5786
                pods_cache_clear( $cache_key, 'pods' );
5787
5788 View Code Duplication
                if ( pods_api_cache() ) {
5789
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
5790
                        pods_transient_set( $cache_key, 'none' );
5791
                    else
5792
                        pods_transient_set( $cache_key, $the_pods );
5793
                }
5794
            }
5795
        }
5796
5797
        return $the_pods;
5798
    }
5799
5800
    /**
5801
     * Check if a Pod's field exists
5802
     *
5803
     * $params['pod_id'] int The Pod ID
5804
     * $params['id'] int The field ID
5805
     * $params['name'] string The field name
5806
     *
5807
     * @param array $params An associative array of parameters
5808
     *
5809
     * @return bool
5810
     *
5811
     * @since 1.12
5812
     */
5813
    public function field_exists ( $params ) {
5814
        $params = (object) pods_sanitize( $params );
5815
5816
        if ( ( !empty( $params->id ) || !empty( $params->name ) ) && isset( $params->pod_id ) && !empty( $params->pod_id ) ) {
5817 View Code Duplication
            if ( !isset( $params->name ) )
5818
                $field = get_post( $dummy = (int) $params->id );
5819
            else {
5820
                $field = get_posts( array(
5821
                    'name' => $params->name,
5822
                    'post_type' => '_pods_field',
5823
                    'posts_per_page' => 1,
5824
                    'post_parent' => $params->pod_id
5825
                ) );
5826
            }
5827
5828
            if ( !empty( $field ) )
5829
                return true;
5830
        }
5831
5832
        return false;
5833
    }
5834
5835
    /**
5836
     * Load a field
5837
     *
5838
     * $params['pod_id'] int The Pod ID
5839
     * $params['pod'] string The Pod name
5840
     * $params['id'] int The field ID
5841
     * $params['name'] string The field name
5842
     * $params['table_info'] boolean Whether to lookup a pick field's table info
5843
     *
5844
     * @param array $params An associative array of parameters
5845
     * @param boolean $strict Whether to require a field exist or not when loading the info
5846
     *
5847
     * @return array|bool Array with field data, false if field not found
5848
     * @since 1.7.9
5849
     */
5850
    public function load_field ( $params, $strict = false ) {
5851
        $params = (object) $params;
5852
5853
        if ( !isset( $params->table_info ) )
5854
            $params->table_info = false;
5855
5856
        $pod = array();
5857
        $field = array();
5858
5859
        if ( isset( $params->post_title ) )
5860
            $_field = $params;
5861
        elseif ( isset( $params->id ) && !empty( $params->id ) )
5862
            $_field = get_post( $dumb = (int) $params->id );
5863
        else {
5864
            if ( !isset( $params->pod ) )
5865
                $params->pod = '';
5866
5867
            if ( !isset( $params->pod_id ) )
5868
                $params->pod_id = 0;
5869
5870
            if ( isset( $params->pod_data ) )
5871
                $pod = $params->pod_data;
5872 View Code Duplication
            else {
5873
                $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ), false );
5874
5875
                if ( false === $pod ) {
5876
                    if ( $strict )
5877
                        return pods_error( __( 'Pod not found', 'pods' ), $this );
5878
5879
                    return false;
5880
                }
5881
            }
5882
5883
            $params->pod_id = $pod[ 'id' ];
5884
            $params->pod = $pod[ 'name' ];
5885
5886 View Code Duplication
            if ( empty( $params->name ) && empty( $params->pod ) && empty( $params->pod_id ) )
5887
                return pods_error( __( 'Either Field Name or Field ID / Pod ID are required', 'pods' ), $this );
5888
5889
            $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
5890
5891
            if ( isset( $pod[ 'fields' ][ $params->name ] ) && isset( $pod[ 'fields' ][ $params->name ][ 'id' ] ) )
5892
                return $pod[ 'fields' ][ $params->name ];
5893
5894
            $field = false;
5895
5896
            if ( pods_api_cache() )
5897
                $field = pods_transient_get( 'pods_field_' . $params->pod . '_' . $params->name );
5898
5899
            if ( empty( $field ) ) {
5900
                $field = get_posts( array(
5901
                    'name' => $params->name,
5902
                    'post_type' => '_pods_field',
5903
                    'posts_per_page' => 1,
5904
                    'post_parent' => $params->pod_id
5905
                ) );
5906
5907
                if ( empty( $field ) ) {
5908
                    if ( $strict )
5909
                        return pods_error( __( 'Field not found', 'pods' ), $this );
5910
5911
                    return false;
5912
                }
5913
5914
                $_field = $field[ 0 ];
5915
5916
                $field = array();
5917
            }
5918
        }
5919
5920
        if ( empty( $_field ) ) {
5921
            if ( $strict )
5922
                return pods_error( __( 'Field not found', 'pods' ), $this );
5923
5924
            return false;
5925
        }
5926
5927
        $_field = get_object_vars( $_field );
5928
5929
        if ( !isset( $pod[ 'name' ] ) && !isset( $_field[ 'pod' ] ) ) {
5930
            if ( 0 < $_field[ 'post_parent' ] )
5931
                $pod = $this->load_pod( array( 'id' => $_field[ 'post_parent' ], 'table_info' => false ), false );
5932
5933
            if ( empty( $pod ) ) {
5934
                if ( $strict )
5935
                    return pods_error( __( 'Pod for field not found', 'pods' ), $this );
5936
5937
                return false;
5938
            }
5939
        }
5940
5941
        if ( empty( $field ) ) {
5942 View Code Duplication
            if ( pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
5943
                $field = pods_transient_get( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $_field[ 'post_name' ] );
5944
5945
            if ( empty( $field ) ) {
5946
                $defaults = array(
5947
                    'type' => 'text'
5948
                );
5949
5950
                $field = array(
5951
                    'id' => $_field[ 'ID' ],
5952
                    'name' => $_field[ 'post_name' ],
5953
                    'label' => $_field[ 'post_title' ],
5954
                    'description' => $_field[ 'post_content' ],
5955
                    'weight' => $_field[ 'menu_order' ],
5956
                    'pod_id' => $_field[ 'post_parent' ],
5957
                    'pick_object' => '',
5958
                    'pick_val' => '',
5959
                    'sister_id' => '',
5960
                    'table_info' => array()
5961
                );
5962
5963
                if ( isset( $pod[ 'name' ] ) )
5964
                    $field[ 'pod' ] = $pod[ 'name' ];
5965
                elseif ( isset( $_field[ 'pod' ] ) )
5966
                    $field[ 'pod' ] = $_field[ 'pod' ];
5967
5968
                $field[ 'options' ] = get_post_meta( $field[ 'id' ] );
5969
5970
                $options_ignore = array(
5971
                    'method',
5972
                    'table_info',
5973
                    'attributes',
5974
                    'group',
5975
                    'grouped',
5976
                    'developer_mode',
5977
                    'dependency',
5978
                    'depends-on',
5979
                    'excludes-on'
5980
                );
5981
5982
                foreach ( $options_ignore as $ignore ) {
5983
                    if ( isset( $field[ 'options' ][ $ignore ] ) )
5984
                        unset( $field[ 'options' ][ $ignore ] );
5985
                }
5986
5987 View Code Duplication
                foreach ( $field[ 'options' ] as $option => $value ) {
5988
                    if ( is_array( $value ) ) {
5989
                        foreach ( $value as $k => $v ) {
5990
                            if ( !is_array( $v ) )
5991
                                $value[ $k ] = maybe_unserialize( $v );
5992
                        }
5993
5994
                        if ( 1 == count( $value ) )
5995
                            $value = current( $value );
5996
                    }
5997
                    else
5998
                        $value = maybe_unserialize( $value );
5999
6000
                    $field[ 'options' ][ $option ] = $value;
6001
                }
6002
6003
                $field[ 'options' ] = array_merge( $defaults, $field[ 'options' ] );
6004
6005
                $field[ 'type' ] = $field[ 'options' ][ 'type' ];
6006
6007
                unset( $field[ 'options' ][ 'type' ] );
6008
6009 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_object' ] ) ) {
6010
                    $field[ 'pick_object' ] = $field[ 'options' ][ 'pick_object' ];
6011
6012
                    unset( $field[ 'options' ][ 'pick_object' ] );
6013
                }
6014
6015 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_val' ] ) ) {
6016
                    $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_val' ];
6017
6018
                    unset( $field[ 'options' ][ 'pick_val' ] );
6019
                }
6020
6021 View Code Duplication
                if ( isset( $field[ 'options' ][ 'sister_id' ] ) ) {
6022
                    $field[ 'sister_id' ] = $field[ 'options' ][ 'sister_id' ];
6023
6024
                    unset( $field[ 'options' ][ 'sister_id' ] );
6025
                }
6026
6027
                if ( isset( $field[ 'options' ][ 'sister_field_id' ] ) )
6028
                    unset( $field[ 'options' ][ 'sister_field_id' ] );
6029
6030 View Code Duplication
                if ( pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6031
                    pods_transient_set( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $field[ 'name' ], $field );
6032
            }
6033
        }
6034
6035
        $field[ 'table_info' ] = array();
6036
6037
        if ( 'pick' == $field[ 'type' ] && $params->table_info )
6038
            $field[ 'table_info' ] = $this->get_table_info( $field[ 'pick_object' ], $field[ 'pick_val' ], null, null, $field );
6039
6040
        return $field;
6041
    }
6042
6043
    /**
6044
     * Load fields by Pod, ID, Name, and/or Type
6045
     *
6046
     * $params['pod_id'] int The Pod ID
6047
     * $params['pod'] string The Pod name
6048
     * $params['id'] array The field IDs
6049
     * $params['name'] array The field names
6050
     * $params['type'] array The field types
6051
     * $params['options'] array Field Option(s) key=>value array to filter by
6052
     * $params['where'] string WHERE clause of query
6053
     *
6054
     * @param array $params An associative array of parameters
6055
     * @param bool $strict  Whether to require a field exist or not when loading the info
6056
     *
6057
     * @return array Array of field data.
6058
     *
6059
     * @since 1.7.9
6060
     */
6061
    public function load_fields ( $params, $strict = false ) {
6062
		// @todo Get away from using md5/serialize, I'm sure we can cache specific parts
6063
	    $cache_key = md5( serialize( $params  ) );
6064
	    if ( isset( $this->fields_cache[ $cache_key ] ) ) {
6065
		    return $this->fields_cache[ $cache_key ];
6066
	    }
6067
6068
        $params = (object) pods_sanitize( $params );
6069
6070
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6071
            $params->pod = '';
6072
6073
        if ( !isset( $params->pod_id ) || empty( $params->pod_id ) )
6074
            $params->pod_id = 0;
6075
6076 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
6077
            $params->name = array();
6078
        else
6079
            $params->name = (array) $params->name;
6080
6081
        if ( !isset( $params->id ) || empty( $params->id ) )
6082
            $params->id = array();
6083
        else {
6084
            $params->id = (array) $params->id;
6085
6086
            foreach ( $params->id as &$id ) {
6087
                $id = pods_absint( $id );
6088
            }
6089
        }
6090
6091 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6092
            $params->type = array();
6093
        else
6094
            $params->type = (array) $params->type;
6095
6096
        $fields = array();
6097
6098
        if ( !empty( $params->pod ) || !empty( $params->pod_id ) ) {
6099
            $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => true ), false );
6100
6101
            if ( false === $pod ) {
6102
                if ( $strict )
6103
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
6104
6105
                return $fields;
6106
            }
6107
6108
			$pod[ 'fields' ] = array_merge( pods_var_raw( 'object_fields', $pod, array() ), $pod[ 'fields' ] );
6109
6110
            foreach ( $pod[ 'fields' ] as $field ) {
6111
                if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6112
                    $fields[ $field[ 'name' ] ] = $field;
6113
				elseif ( in_array( $fields[ 'name' ], $params->name ) || in_array( $fields[ 'id' ], $params->id ) || in_array( $fields[ 'type' ], $params->type ) )
6114
                    $fields[ $field[ 'name' ] ] = $field;
6115
            }
6116
        }
6117
        elseif ( ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) || ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) ) ) {
6118
            $order = 'ASC';
6119
            $orderby = 'menu_order title';
6120
            $limit = -1;
6121
            $ids = false;
6122
6123
            $meta_query = array();
6124
6125 View Code Duplication
            if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6126
                foreach ( $params->options as $option => $value ) {
6127
                    if ( !is_array( $value ) )
6128
                        $value = array( $value );
6129
6130
                    $value = pods_trim( $value );
6131
6132
                    sort( $value );
6133
6134
                    $meta_query[] = array(
6135
                        'key' => $option,
6136
                        'value' => pods_sanitize( $value ),
6137
                        'compare' => 'IN'
6138
                    );
6139
                }
6140
            }
6141
6142
            if ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) )
6143
                $meta_query = array_merge( $meta_query, (array) $params->where );
6144
6145
			$args = array(
6146
				'post_type' => '_pods_field',
6147
				'nopaging' => true,
6148
				'posts_per_page' => $limit,
6149
				'order' => $order,
6150
				'orderby' => $orderby,
6151
				'meta_query' => $meta_query,
6152
			);
6153
6154
			// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6155
			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...
6156
				$args[ 'post__in' ] = $ids;
6157
			}
6158
6159
            $fields = array();
6160
6161
            $_fields = get_posts( $args );
6162
6163
            foreach ( $_fields as $field ) {
6164
                $field = $this->load_field( $field, false );
6165
6166
                if ( !empty( $field ) )
6167
                    $fields[ $field[ 'id' ] ] = $field;
6168
            }
6169
        }
6170
        else {
6171 View Code Duplication
            if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6172
                return pods_error( __( 'Either Field Name / Field ID / Field Type, or Pod Name / Pod ID are required', 'pods' ), $this );
6173
6174
            $lookup = array();
6175
6176 View Code Duplication
            if ( !empty( $params->name ) ) {
6177
                $fields = implode( "', '", $params->name );
6178
6179
                $lookup[] = "`post_name` IN ( '{$fields}' )";
6180
            }
6181
6182 View Code Duplication
            if ( !empty( $params->id ) ) {
6183
                $fields = implode( ", ", $params->id );
6184
6185
                $lookup[] = "`ID` IN ( {$fields} )";
6186
            }
6187
6188
            $lookup = implode( ' AND ', $lookup );
6189
6190
            $result = pods_query( "SELECT `ID`, `post_name`, `post_parent` FROM `@wp_posts` WHERE `post_type` = '_pods_field' AND ( {$lookup} )" );
6191
6192
            $fields = array();
6193
6194
            if ( !empty( $result ) ) {
6195
                foreach ( $result as $field ) {
6196
					$field = $this->load_field( array(
6197
                        'id' => $field->ID,
6198
                        'name' => $field->post_name,
6199
                        'pod_id' => $field->post_parent
6200
                    ), false );
6201
6202
                    if ( !empty( $field ) && ( empty( $params->type ) || in_array( $field[ 'type' ], $params->type ) ) )
6203
                        $fields[ $field[ 'id' ] ] = $field;
6204
                }
6205
            }
6206
        }
6207
	    if ( isset( $cache_key ) ) {
6208
		    $this->fields_cache[ $cache_key ] = $fields;
6209
	    }
6210
        return $fields;
6211
    }
6212
6213
    /**
6214
     * Load a Pods Object
6215
     *
6216
     * $params['id'] int The Object ID
6217
     * $params['name'] string The Object name
6218
     * $params['type'] string The Object type
6219
     *
6220
     * @param array|object $params An associative array of parameters
6221
     * @param bool $strict
6222
     *
6223
     * @return array|bool
6224
     * @since 2.0
6225
     */
6226
    public function load_object ( $params, $strict = false ) {
6227
        if ( is_object( $params ) && isset( $params->post_title ) )
6228
            $_object = get_object_vars( $params );
6229
        else {
6230
            $params = (object) pods_sanitize( $params );
6231
6232 View Code Duplication
            if ( !isset( $params->type ) || empty( $params->type ) )
6233
                return pods_error( __( 'Object type is required', 'pods' ), $this );
6234
6235 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) )
6236
                return pods_error( __( 'Either Object ID or Name are required', 'pods' ), $this );
6237
6238
            /**
6239
             * @var $wpdb wpdb
6240
             */
6241
            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...
6242
6243
            if ( isset( $params->name ) )
6244
                $_object = pods_by_title( $params->name, ARRAY_A, '_pods_' . $params->type, 'publish' );
6245
            else {
6246
                $object = $params->id;
6247
6248
                $_object = get_post( $object, ARRAY_A );
6249
            }
6250
6251
            if ( empty( $_object ) ) {
6252
                if ( $strict )
6253
                    return pods_error( __( 'Object not found', 'pods' ), $this );
6254
6255
                return false;
6256
            }
6257
        }
6258
6259
        $object = array(
6260
            'id' => $_object[ 'ID' ],
6261
            'name' => $_object[ 'post_title' ],
6262
            'code' => $_object[ 'post_content' ],
6263
            'type' => str_replace( '_pods_', '', $_object[ 'post_type' ] ),
6264
            'slug' => $_object[ 'post_name' ]
6265
        );
6266
6267
        $object[ 'options' ] = get_post_meta( $object[ 'id' ] );
6268
6269
        foreach ( $object[ 'options' ] as $option => &$value ) {
6270
            if ( is_array( $value ) && 1 == count( $value ) )
6271
                $value = current( $value );
6272
        }
6273
6274
        return $object;
6275
    }
6276
6277
    /**
6278
     * Load Multiple Pods Objects
6279
     *
6280
     * $params['type'] string The Object type
6281
     * $params['options'] array Pod Option(s) key=>value array to filter by
6282
     * $params['orderby'] string ORDER BY clause of query
6283
     * $params['limit'] string Number of objects to return
6284
     * $params['where'] string WHERE clause of query
6285
     * $params['ids'] string|array IDs of Objects
6286
     *
6287
     * @param array|object $params An associative array of parameters
6288
     *
6289
     * @return array
6290
     * @since 2.0
6291
     */
6292
    public function load_objects ( $params ) {
6293
        $params = (object) pods_sanitize( $params );
6294
6295 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6296
            return pods_error( __( 'Pods Object type is required', 'pods' ), $this );
6297
6298
        $order = 'ASC';
6299
        $orderby = 'menu_order';
6300
        $limit = -1;
6301
        $ids = false;
6302
6303
        $meta_query = array();
6304
        $cache_key = '';
6305
6306 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6307
            foreach ( $params->options as $option => $value ) {
6308
                if ( !is_array( $value ) )
6309
                    $value = array( $value );
6310
6311
                $value = pods_trim( $value );
6312
6313
                sort( $value );
6314
6315
                $meta_query[] = array(
6316
                    'key' => $option,
6317
                    'value' => pods_sanitize( $value ),
6318
                    'compare' => 'IN'
6319
                );
6320
            }
6321
        }
6322
6323
        if ( isset( $params->where ) && is_array( $params->where ) )
6324
            $meta_query = array_merge( $meta_query, (array) $params->where );
6325
6326 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
6327
            $order = strtoupper( $params->order );
6328
6329
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
6330
            $orderby = strtoupper( $params->orderby );
6331
6332
        if ( isset( $params->limit ) && !empty( $params->limit ) )
6333
            $limit = pods_absint( $params->limit );
6334
6335
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
6336
            $ids = $params->ids;
6337
6338
            if ( !is_array( $ids ) )
6339
                $ids = explode( ',', $ids );
6340
        }
6341
6342
        if ( empty( $ids ) )
6343
            $ids = false;
6344
6345
        if ( pods_api_cache() && empty( $meta_query ) && empty( $limit ) && ( empty( $orderby ) || 'menu_order' == $orderby ) && empty( $ids ) ) {
6346
            $cache_key = 'pods_objects_' . $params->type;
6347
6348
            $the_objects = pods_transient_get( $cache_key );
6349
6350
            if ( false !== $the_objects )
6351
                return $the_objects;
6352
        }
6353
6354
        $the_objects = array();
6355
6356
		$args = array(
6357
			'post_type' => '_pods_' . $params->type,
6358
			'nopaging' => true,
6359
			'posts_per_page' => $limit,
6360
			'order' => $order,
6361
			'orderby' => $orderby,
6362
			'meta_query' => $meta_query,
6363
		);
6364
6365
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6366
		if ( false != $ids ) {
6367
			$args[ 'post__in' ] = $ids;
6368
		}
6369
6370
		$objects = get_posts( $args );
6371
6372
        foreach ( $objects as $object ) {
6373
            $object = $this->load_object( $object );
6374
6375
            $the_objects[ $object[ 'name' ] ] = $object;
6376
        }
6377
6378
        if ( pods_api_cache() && !empty( $cache_key ) )
6379
            pods_transient_set( $cache_key, $the_objects );
6380
6381
        return $the_objects;
6382
    }
6383
6384
    /**
6385
     * @see PodsAPI::load_object
6386
     *
6387
     * Load a Pod Template
6388
     *
6389
     * $params['id'] int The template ID
6390
     * $params['name'] string The template name
6391
     *
6392
     * @param array $params An associative array of parameters
6393
     *
6394
     * @return array|bool
6395
     * @since 1.7.9
6396
     */
6397
    public function load_template ( $params ) {
6398
        if ( !class_exists( 'Pods_Templates' ) )
6399
            return false;
6400
6401
        $params = (object) $params;
6402
        $params->type = 'template';
6403
        return $this->load_object( $params );
6404
    }
6405
6406
    /**
6407
     * @see PodsAPI::load_objects
6408
     *
6409
     * Load Multiple Pod Templates
6410
     *
6411
     * $params['where'] string The WHERE clause of query
6412
     * $params['options'] array Pod Option(s) key=>value array to filter by
6413
     * $params['orderby'] string ORDER BY clause of query
6414
     * $params['limit'] string Number of templates to return
6415
     *
6416
     * @param array $params (optional) An associative array of parameters
6417
     *
6418
     * @return array
6419
     *
6420
     * @since 2.0
6421
     */
6422
    public function load_templates ( $params = null ) {
6423
        if ( !class_exists( 'Pods_Templates' ) )
6424
            return array();
6425
6426
        $params = (object) $params;
6427
        $params->type = 'template';
6428
        return $this->load_objects( $params );
6429
    }
6430
6431
    /**
6432
     * @see PodsAPI::load_object
6433
     *
6434
     * Load a Pod Page
6435
     *
6436
     * $params['id'] int The page ID
6437
     * $params['name'] string The page URI
6438
     *
6439
     * @param array $params An associative array of parameters
6440
     *
6441
     * @return array|bool
6442
     *
6443
     * @since 1.7.9
6444
     */
6445
    public function load_page ( $params ) {
6446
        if ( !class_exists( 'Pods_Pages' ) )
6447
            return false;
6448
6449
        $params = (object) $params;
6450 View Code Duplication
        if ( !isset( $params->name ) && isset( $params->uri ) ) {
6451
            $params->name = $params->uri;
6452
            unset( $params->uri );
6453
        }
6454
        $params->type = 'page';
6455
        return $this->load_object( $params );
6456
    }
6457
6458
    /**
6459
     * @see PodsAPI::load_objects
6460
     *
6461
     * Load Multiple Pod Pages
6462
     *
6463
     * $params['where'] string The WHERE clause of query
6464
     * $params['options'] array Pod Option(s) key=>value array to filter by
6465
     * $params['orderby'] string ORDER BY clause of query
6466
     * $params['limit'] string Number of pages to return
6467
     *
6468
     * @param array $params (optional) An associative array of parameters
6469
     *
6470
     * @return array
6471
     *
6472
     * @since 2.0
6473
     */
6474
    public function load_pages ( $params = null ) {
6475
        if ( !class_exists( 'Pods_Pages' ) )
6476
            return array();
6477
6478
        $params = (object) $params;
6479
        $params->type = 'page';
6480
        return $this->load_objects( $params );
6481
    }
6482
6483
    /**
6484
     * @see PodsAPI::load_object
6485
     *
6486
     * Load a Pod Helper
6487
     *
6488
     * $params['id'] int The helper ID
6489
     * $params['name'] string The helper name
6490
     *
6491
     * @param array $params An associative array of parameters
6492
     *
6493
     * @return array|bool
6494
     *
6495
     * @since 1.7.9
6496
     */
6497 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...
6498
        if ( !class_exists( 'Pods_Helpers' ) )
6499
            return false;
6500
6501
        $params = (object) $params;
6502
        $params->type = 'helper';
6503
        return $this->load_object( $params );
6504
    }
6505
6506
    /**
6507
     * @see PodsAPI::load_objects
6508
     *
6509
     * Load Multiple Pod Helpers
6510
     *
6511
     * $params['where'] string The WHERE clause of query
6512
     * $params['options'] array Pod Option(s) key=>value array to filter by
6513
     * $params['orderby'] string ORDER BY clause of query
6514
     * $params['limit'] string Number of pages to return
6515
     *
6516
     * @param array $params (optional) An associative array of parameters
6517
     *
6518
     * @return array
6519
     *
6520
     * @since 2.0
6521
     */
6522 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...
6523
        if ( !class_exists( 'Pods_Helpers' ) )
6524
            return array();
6525
6526
        $params = (object) $params;
6527
        $params->type = 'helper';
6528
        return $this->load_objects( $params );
6529
    }
6530
6531
    /**
6532
     * Load the pod item object
6533
     *
6534
     * $params['pod'] string The datatype name
6535
     * $params['id'] int (optional) The item's ID
6536
     *
6537
     * @param array $params An associative array of parameters
6538
     *
6539
     * @return bool|\Pods
6540
     *
6541
     * @uses pods()
6542
     *
6543
     * @since 2.0
6544
     */
6545
    public function load_pod_item ( $params ) {
6546
        $params = (object) pods_sanitize( $params );
6547
6548 View Code Duplication
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6549
            return pods_error( __( 'Pod name required', 'pods' ), $this );
6550 View Code Duplication
        if ( !isset( $params->id ) || empty( $params->id ) )
6551
            return pods_error( __( 'Item ID required', 'pods' ), $this );
6552
6553
        $pod = false;
6554
6555
        if ( pods_api_cache() )
6556
            $pod = pods_cache_get( $params->id, 'pods_item_object_' . $params->pod );
6557
6558
        if ( false !== $pod )
6559
            return $pod;
6560
6561
        $pod = pods( $params->pod, $params->id );
6562
6563
        if ( pods_api_cache() )
6564
            pods_cache_set( $params->id, $pod, 'pods_item_object_' . $params->pod );
6565
6566
        return $pod;
6567
    }
6568
6569
    /**
6570
     * Load potential sister fields for a specific field
6571
     *
6572
     * $params['pod'] int The Pod name
6573
     * $params['related_pod'] string The related Pod name
6574
     *
6575
     * @param array $params An associative array of parameters
6576
     * @param array $pod (optional) Array of Pod data to use (to avoid lookup)
6577
     *
6578
     * @return array|bool
6579
     *
6580
     * @since 1.7.9
6581
     *
6582
     * @uses PodsAPI::load_pod
6583
     */
6584
    public function load_sister_fields ( $params, $pod = null ) {
6585
        $params = (object) pods_sanitize( $params );
6586
6587 View Code Duplication
        if ( empty( $pod ) ) {
6588
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ), false );
6589
6590
            if ( false === $pod )
6591
                return pods_error( __( 'Pod not found', 'pods' ), $this );
6592
        }
6593
6594
        $params->pod_id = $pod[ 'id' ];
6595
        $params->pod = $pod[ 'name' ];
6596
6597
        $type = false;
6598
6599
        if ( 0 === strpos( $params->related_pod, 'pod-' ) ) {
6600
            $params->related_pod = pods_str_replace( 'pod-', '', $params->related_pod, 1 );
6601
            $type = 'pod';
6602
        }
6603 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'post_type-' ) ) {
6604
            $params->related_pod = pods_str_replace( 'post_type-', '', $params->related_pod, 1 );
6605
            $type = 'post_type';
6606
        }
6607 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'taxonomy-' ) ) {
6608
            $params->related_pod = pods_str_replace( 'taxonomy-', '', $params->related_pod, 1 );
6609
            $type = 'taxonomy';
6610
        }
6611
6612
        $related_pod = $this->load_pod( array( 'name' => $params->related_pod, 'table_info' => false ), false );
6613
6614
        if ( false === $related_pod || ( false !== $type && 'pod' != $type && $type != $related_pod[ 'type' ] ) )
6615
            return pods_error( __( 'Related Pod not found', 'pods' ), $this );
6616
6617
        $params->related_pod_id = $related_pod[ 'id' ];
6618
        $params->related_pod = $related_pod[ 'name' ];
6619
6620
        $sister_fields = array();
6621
6622
        foreach ( $related_pod[ 'fields' ] as $field ) {
6623
            if ( 'pick' == $field[ 'type' ] && in_array( $field[ 'pick_object' ], array( $pod[ 'type' ], 'pod' ) ) && ( $params->pod == $field[ 'pick_object' ] || $params->pod == $field[ 'pick_val' ] ) )
6624
                $sister_fields[ $field[ 'id' ] ] = esc_html( $field[ 'label' ] . ' (' . $field[ 'name' ] . ')' );
6625
        }
6626
6627
        return $sister_fields;
6628
    }
6629
6630
    /**
6631
     * Takes a sql field such as tinyint and returns the pods field type, such as num.
6632
     *
6633
     * @param string $sql_field The SQL field to look for
6634
     *
6635
     * @return string The field type
6636
     *
6637
     * @since 2.0
6638
     */
6639
    public static function detect_pod_field_from_sql_data_type ( $sql_field ) {
6640
        $sql_field = strtolower( $sql_field );
6641
6642
        $field_to_field_map = array(
6643
            'tinyint' => 'number',
6644
            'smallint' => 'number',
6645
            'mediumint' => 'number',
6646
            'int' => 'number',
6647
            'bigint' => 'number',
6648
            'float' => 'number',
6649
            'double' => 'number',
6650
            'decimal' => 'number',
6651
            'date' => 'date',
6652
            'datetime' => 'datetime',
6653
            'timestamp' => 'datetime',
6654
            'time' => 'time',
6655
            'year' => 'date',
6656
            'varchar' => 'text',
6657
            'text' => 'paragraph',
6658
            'mediumtext' => 'paragraph',
6659
            'longtext' => 'paragraph'
6660
        );
6661
6662
        return ( array_key_exists( $sql_field, $field_to_field_map ) ) ? $field_to_field_map[ $sql_field ] : 'paragraph';
6663
    }
6664
6665
    /**
6666
     * Gets all field types
6667
     *
6668
     * @return array Array of field types
6669
     *
6670
     * @uses PodsForm::field_loader
6671
     *
6672
     * @since 2.0
6673
     * @deprecated
6674
     */
6675
    public function get_field_types () {
6676
        return PodsForm::field_types();
6677
    }
6678
6679
    /**
6680
     * Gets the schema definition of a field.
6681
     *
6682
     * @param string $type Field type to look for
6683
     * @param array $options (optional) Options of the field to pass to the schema function.
6684
     *
6685
     * @return array|bool|mixed|null
6686
     *
6687
     * @since 2.0
6688
     */
6689
    private function get_field_definition ( $type, $options = null ) {
6690
        $definition = PodsForm::field_method( $type, 'schema', $options );
6691
6692
        return $this->do_hook( 'field_definition', $definition, $type, $options );
6693
    }
6694
6695
    /**
6696
     * @see PodsForm:validate
6697
     *
6698
     * Validates the value of a field.
6699
     *
6700
     * @param mixed $value The value to validate
6701
     * @param string $field Field to use for validation
6702
     * @param array $object_fields Fields of the object we're validating
6703
     * @param array $fields Array of all fields data
6704
     * @param array|Pods $pod Array of pod data (or Pods object)
6705
     * @param array|object $params Extra parameters to pass to the validation function of the field.
6706
     *
6707
     * @return array|bool
6708
     *
6709
     * @uses PodsForm::validate
6710
     *
6711
     * @since 2.0
6712
     */
6713
    public function handle_field_validation ( &$value, $field, $object_fields, $fields, $pod, $params ) {
6714
        $tableless_field_types = PodsForm::tableless_field_types();
6715
6716
        $fields = array_merge( $fields, $object_fields );
6717
6718
        $options = $fields[ $field ];
6719
6720
        $id = ( is_object( $params ) ? $params->id : ( is_object( $pod ) ? $pod->id() : 0 ) );
6721
6722
        if ( is_object( $pod ) )
6723
            $pod = $pod->pod_data;
6724
6725
        $type = $options[ 'type' ];
6726
        $label = $options[ 'label' ];
6727
        $label = empty( $label ) ? $field : $label;
6728
6729
        // Verify required fields
6730
        if ( 1 == pods_var( 'required', $options[ 'options' ], 0 ) && 'slug' != $type ) {
6731
            if ( '' == $value || null === $value || array() === $value )
6732
                return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this );
6733
6734
            if ( 'multi' == pods_var( 'pick_format_type', $options[ 'options' ] ) && 'autocomplete' != pods_var( 'pick_format_multi', $options[ 'options' ] ) ) {
6735
                $has_value = false;
6736
6737
                $check_value = (array) $value;
6738
6739
                foreach ( $check_value as $val ) {
6740
                    if ( '' != $val && null !== $val && 0 !== $val && '0' !== $val ) {
6741
                        $has_value = true;
6742
6743
                        continue;
6744
                    }
6745
                }
6746
6747
                if ( !$has_value )
6748
                    return pods_error( sprintf( __( '%s is required', 'pods' ), $label ), $this );
6749
            }
6750
6751
        }
6752
6753
        // @todo move this to after pre-save preparations
6754
        // Verify unique fields
6755
        if ( 1 == pods_var( 'unique', $options[ 'options' ], 0 ) && '' !== $value && null !== $value && array() !== $value ) {
6756
            if ( empty( $pod ) )
6757
                return false;
6758
6759
            if ( !in_array( $type, $tableless_field_types ) ) {
6760
                $exclude = '';
6761
6762
                if ( !empty( $id ) )
6763
                    $exclude = "AND `id` != {$id}";
6764
6765
                $check = false;
6766
6767
                $check_value = pods_sanitize( $value );
6768
6769
                // @todo handle meta-based fields
6770
                // Trigger an error if not unique
6771
                if ( 'table' == $pod[ 'storage' ] )
6772
                    $check = pods_query( "SELECT `id` FROM `@wp_pods_" . $pod[ 'name' ] . "` WHERE `{$field}` = '{$check_value}' {$exclude} LIMIT 1", $this );
6773
6774
                if ( !empty( $check ) )
6775
                    return pods_error( sprintf( __( '%s needs to be unique', 'pods' ), $label ), $this );
6776
            }
6777
            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...
6778
                // @todo handle tableless check
6779
            }
6780
        }
6781
6782
        $validate = PodsForm::validate( $options[ 'type' ], $value, $field, array_merge( $options, pods_var( 'options', $options, array() ) ), $fields, $pod, $id, $params );
6783
6784
        $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params );
6785
6786
        return $validate;
6787
    }
6788
6789
    /**
6790
     * Find items related to a parent field
6791
     *
6792
     * @param int $field_id The Field ID
6793
     * @param int $pod_id The Pod ID
6794
     * @param mixed $ids A comma-separated string (or array) of item IDs
6795
     * @param array $field Field data array
6796
     * @param array $pod Pod data array
6797
     *
6798
     * @return array
6799
     *
6800
     * @since 2.0
6801
     *
6802
     * @uses pods_query()
6803
     */
6804
    public function lookup_related_items ( $field_id, $pod_id, $ids, $field = null, $pod = null ) {
6805
        $related_ids = array();
6806
6807
        if ( !is_array( $ids ) )
6808
            $ids = explode( ',', $ids );
6809
6810
        foreach ( $ids as $k => $id ) {
6811
            $ids[ $k ] = (int) $id;
6812
        }
6813
6814
        $ids = array_unique( array_filter( $ids ) );
6815
6816
	    $idstring = implode( ',', $ids );
6817
	    if ( 0 != $pod_id && 0 != $field_id && isset( self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] ) ) {
6818
		    // Check cache first, no point in running the same query multiple times
6819
		    return self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ];
6820
	    }
6821
6822
        $tableless_field_types = PodsForm::tableless_field_types();
6823
6824
		$field_type = pods_v( 'type', $field );
6825
6826
        if ( empty( $ids ) || !in_array( $field_type, $tableless_field_types ) )
6827
            return array();
6828
6829
        $related_pick_limit = 0;
6830
6831
		if ( empty( $field ) ) {
6832
			$field = $this->load_field( array( 'id' => $field_id ) );
6833
		}
6834
6835
        if ( !empty( $field ) ) {
6836
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
6837
6838
            $related_pick_limit = (int) pods_v( $field_type . '_limit', $options, 0 );
6839
6840
            if ( 'single' == pods_var_raw( $field_type . '_format_type', $options ) )
6841
                $related_pick_limit = 1;
6842
6843
            // Temporary hack until there's some better handling here
6844
            $related_pick_limit = $related_pick_limit * count( $ids );
6845
        }
6846
6847
		if ( 'taxonomy' == $field_type ) {
6848
			$related = wp_get_object_terms( $ids, pods_v( 'name', $field ), array( 'fields' => 'ids' ) );
6849
6850
			if ( !is_wp_error( $related ) ) {
6851
				$related_ids = $related;
6852
			}
6853
		}
6854
		elseif ( !pods_tableless() ) {
6855
            $ids = implode( ', ', $ids );
6856
6857
            $field_id = (int) $field_id;
6858
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
6859
6860
            $related_where = "
6861
                `field_id` = {$field_id}
6862
                AND `item_id` IN ( {$ids} )
6863
            ";
6864
6865
            $sql = "
6866
                SELECT item_id, related_item_id, related_field_id
6867
                FROM `@wp_podsrel`
6868
                WHERE
6869
                    {$related_where}
6870
                ORDER BY `weight`
6871
            ";
6872
6873
            $relationships = pods_query( $sql );
6874
6875
            if ( !empty( $relationships ) ) {
6876
                foreach ( $relationships as $relation ) {
6877
                    if ( !in_array( $relation->related_item_id, $related_ids ) )
6878
                        $related_ids[] = (int) $relation->related_item_id;
6879
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->item_id, $related_ids ) )
6880
                        $related_ids[] = (int) $relation->item_id;
6881
                }
6882
            }
6883
        }
6884 View Code Duplication
        else {
6885
            if ( !is_array( $pod ) )
6886
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
6887
6888
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
6889
                $meta_type = $pod[ 'type' ];
6890
6891
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
6892
                    $meta_type = 'post';
6893
                elseif ( 'taxonomy' == $meta_type )
6894
                    $meta_type = 'term';
6895
6896
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
6897
6898
                if ( !$no_conflict )
6899
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
6900
6901
                foreach ( $ids as $id ) {
6902
                    if ( 'settings' == $meta_type ) {
6903
                        $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
6904
6905
                        if ( empty( $related_id ) )
6906
                            $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
6907
6908
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
6909
                            foreach ( $related_id as $related ) {
6910
                                if ( is_array( $related ) && !empty( $related ) ) {
6911
                                    if ( isset( $related[ 'id' ] ) )
6912
                                        $related_ids[] = (int) $related[ 'id' ];
6913
                                    else {
6914
                                        foreach ( $related as $r ) {
6915
                                            $related_ids[] = (int) $r;
6916
                                        }
6917
                                    }
6918
                                }
6919
                                else
6920
                                    $related_ids[] = (int) $related;
6921
                            }
6922
                        }
6923
                    }
6924
                    else {
6925
                        $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
6926
6927
                        if ( empty( $related_id ) )
6928
                            $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
6929
6930
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
6931
                            foreach ( $related_id as $related ) {
6932
                                if ( is_array( $related ) && !empty( $related ) ) {
6933
                                    if ( isset( $related[ 'id' ] ) )
6934
                                        $related_ids[] = (int) $related[ 'id' ];
6935
                                    else {
6936
                                        foreach ( $related as $r ) {
6937
                                            if ( isset( $related[ 'id' ] ) )
6938
                                                $related_ids[] = (int) $r[ 'id' ];
6939
                                            else
6940
                                                $related_ids[] = (int) $r;
6941
                                        }
6942
                                    }
6943
                                }
6944
                                else
6945
                                    $related_ids[] = (int) $related;
6946
                            }
6947
                        }
6948
                    }
6949
                }
6950
6951
                if ( !$no_conflict )
6952
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
6953
            }
6954
        }
6955
6956
        if ( is_array( $related_ids ) ) {
6957
            $related_ids = array_unique( array_filter( $related_ids ) );
6958
6959
            if ( 0 < $related_pick_limit && !empty( $related_ids ) )
6960
                $related_ids = array_slice( $related_ids, 0, $related_pick_limit );
6961
        }
6962
	    if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) {
6963
                    // Only cache if $pod_id and $field_id were passed
6964
		    self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] = $related_ids;
6965
	    }
6966
6967
        return $related_ids;
6968
    }
6969
6970
    /**
6971
     * Find related items related to an item
6972
     *
6973
     * @param int $field_id The Field ID
6974
     * @param int $pod_id The Pod ID
6975
     * @param int $id Item ID to get related IDs from
6976
     * @param array $field Field data array
6977
     * @param array $pod Pod data array
6978
     *
6979
     * @return array|bool
6980
     *
6981
     * @since 2.3
6982
     *
6983
     * @uses pods_query()
6984
     */
6985
    public function lookup_related_items_from ( $field_id, $pod_id, $id, $field = null, $pod = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $pod_id is not used and could be removed.

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

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

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

Loading history...
6986
        $related_ids = false;
6987
6988
        $id = (int) $id;
6989
6990
        $tableless_field_types = PodsForm::tableless_field_types();
6991
6992
        if ( empty( $id ) || !in_array( pods_v( 'type', $field ), $tableless_field_types ) )
6993
            return false;
6994
6995
        $related_pick_limit = 0;
6996
6997
        if ( !empty( $field ) ) {
6998
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
6999
7000
            $related_pick_limit = (int) pods_v( 'pick_limit', $options, 0 );
7001
7002
            if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
7003
                $related_pick_limit = 1;
7004
        }
7005
7006
        if ( !pods_tableless() ) {
7007
            $field_id = (int) $field_id;
7008
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7009
7010
            $related_where = "
7011
                `field_id` = {$field_id}
7012
                AND `related_item_id` = {$id}
7013
            ";
7014
7015
            $sql = "
7016
                SELECT *
7017
                FROM `@wp_podsrel`
7018
                WHERE
7019
                    {$related_where}
7020
                ORDER BY `weight`
7021
            ";
7022
7023
            $relationships = pods_query( $sql );
7024
7025
            if ( !empty( $relationships ) ) {
7026
                $related_ids = array();
7027
7028
                foreach ( $relationships as $relation ) {
7029
                    if ( $field_id == $relation->field_id && !in_array( $relation->item_id, $related_ids ) )
7030
                        $related_ids[] = (int) $relation->item_id;
7031
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->related_item_id, $related_ids ) )
7032
                        $related_ids[] = (int) $relation->related_item_id;
7033
                }
7034
            }
7035
        }
7036 View Code Duplication
        else {
7037
            // @todo handle meta-based lookups
7038
            return false;
7039
7040
            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...
Bug introduced by
The variable $pod seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
7041
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7042
7043
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
0 ignored issues
show
Bug introduced by
The variable $pod seems only to be defined at a later point. As such the call to empty() seems to always evaluate to true.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
7044
                $related_ids = array();
7045
7046
                $meta_type = $pod[ 'type' ];
7047
7048
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
0 ignored issues
show
Bug introduced by
The variable $meta_type seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
7049
                    $meta_type = 'post';
7050
                elseif ( 'taxonomy' == $meta_type )
0 ignored issues
show
Bug introduced by
The variable $meta_type seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
7051
                    $meta_type = 'term';
7052
7053
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7054
7055
                if ( !$no_conflict )
0 ignored issues
show
Bug introduced by
The variable $no_conflict seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
7056
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7057
7058
                if ( 'settings' == $meta_type ) {
0 ignored issues
show
Bug introduced by
The variable $meta_type seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
7059
                    $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7060
7061
                    if ( empty( $related_id ) )
0 ignored issues
show
Bug introduced by
The variable $related_id seems only to be defined at a later point. As such the call to empty() seems to always evaluate to true.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
7062
                        $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7063
7064
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7065
                        foreach ( $related_id as $related ) {
7066
                            if ( is_array( $related ) && !empty( $related ) ) {
7067
                                if ( isset( $related[ 'id' ] ) )
7068
                                    $related_ids[] = (int) $related[ 'id' ];
7069
                                else {
7070
                                    foreach ( $related as $r ) {
7071
                                        $related_ids[] = (int) $r;
7072
                                    }
7073
                                }
7074
                            }
7075
                            else
7076
                                $related_ids[] = (int) $related;
7077
                        }
7078
                    }
7079
                }
7080
                else {
7081
                    $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7082
7083
                    if ( empty( $related_id ) )
0 ignored issues
show
Bug introduced by
The variable $related_id seems only to be defined at a later point. As such the call to empty() seems to always evaluate to true.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
7084
                        $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7085
7086
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7087
                        foreach ( $related_id as $related ) {
7088
                            if ( is_array( $related ) && !empty( $related ) ) {
7089
                                if ( isset( $related[ 'id' ] ) )
7090
                                    $related_ids[] = (int) $related[ 'id' ];
7091
                                else {
7092
                                    foreach ( $related as $r ) {
7093
                                        if ( isset( $related[ 'id' ] ) )
7094
                                            $related_ids[] = (int) $r[ 'id' ];
7095
                                        else
7096
                                            $related_ids[] = (int) $r;
7097
                                    }
7098
                                }
7099
                            }
7100
                            else
7101
                                $related_ids[] = (int) $related;
7102
                        }
7103
                    }
7104
                }
7105
7106
                if ( !$no_conflict )
0 ignored issues
show
Bug introduced by
The variable $no_conflict seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
7107
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7108
            }
7109
        }
7110
7111
        if ( is_array( $related_ids ) )
7112
            $related_ids = array_unique( array_filter( $related_ids ) );
7113
7114
        return $related_ids;
7115
    }
7116
7117
	/**
7118
	 *
7119
	 * Load the information about an objects MySQL table
7120
	 *
7121
	 * @param $object_type
7122
	 * @param string $object The object to look for
7123
	 * @param null $name (optional) Name of the pod to load
7124
	 * @param array $pod (optional) Array with pod information
7125
	 *
7126
	 * @return array
7127
	 *
7128
	 * @since 2.5
7129
	 */
7130
	public function get_table_info_load ( $object_type, $object, $name = null, $pod = null ) {
7131
7132
		$info = array();
7133
7134
		if ( 'pod' == $object_type && null === $pod ) {
7135 View Code Duplication
			if ( empty( $name ) ) {
7136
				$prefix = 'pod-';
7137
7138
				// Make sure we actually have the prefix before trying anything with the name
7139
				if ( 0 === strpos( $object_type, $prefix ) )
7140
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7141
			}
7142
7143
			if ( empty( $name ) && !empty( $object ) )
7144
				$name = $object;
7145
7146
			$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7147
7148
			if ( !empty( $pod ) ) {
7149
				$object_type = $pod[ 'type' ];
7150
				$name = $pod[ 'name' ];
7151
				$object = $pod[ 'object' ];
7152
7153
				$info[ 'pod' ] = $pod;
7154
			}
7155
		}
7156
		elseif ( null === $pod ) {
7157
			if ( empty( $name ) ) {
7158
				$prefix = $object_type . '-';
7159
7160
				// Make sure we actually have the prefix before trying anything with the name
7161
				if ( 0 === strpos( $object_type, $prefix ) )
7162
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7163
			}
7164
7165
			if ( empty( $name ) && !empty( $object ) )
7166
				$name = $object;
7167
7168
			if ( !empty( $name ) ) {
7169
				$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7170
7171
				if ( !empty( $pod ) && ( null === $object_type || $object_type == $pod[ 'type' ] ) ) {
7172
					$object_type = $pod[ 'type' ];
7173
					$name = $pod[ 'name' ];
7174
					$object = $pod[ 'object' ];
7175
7176
					$info[ 'pod' ] = $pod;
7177
				}
7178
			}
7179
		}
7180
		elseif ( !empty( $pod ) )
7181
			$info[ 'pod' ] = $pod;
7182
7183
		if ( 0 === strpos( $object_type, 'pod' ) ) {
7184 View Code Duplication
			if ( empty( $name ) ) {
7185
				$prefix = 'pod-';
7186
7187
				// Make sure we actually have the prefix before trying anything with the name
7188
				if ( 0 === strpos( $object_type, $prefix ) )
7189
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7190
			}
7191
7192
			$info[ 'type' ] = 'pod';
7193
			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...
7194
7195
			$info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object );
7196
7197
			if ( is_array( $info[ 'pod' ] ) && 'pod' == pods_v( 'type', $info[ 'pod' ] ) ) {
7198
				$info[ 'pod_field_index' ] = $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_v( 'pod_index', $info[ 'pod' ][ 'options' ], 'id', true );
7199
7200
				$slug_field = get_posts( array(
7201
					'post_type' => '_pods_field',
7202
					'posts_per_page' => 1,
7203
					'nopaging' => true,
7204
					'post_parent' => $info[ 'pod' ][ 'id' ],
7205
					'orderby' => 'menu_order',
7206
					'order' => 'ASC',
7207
					'meta_query' => array(
7208
						array(
7209
							'key' => 'type',
7210
							'value' => 'slug',
7211
						)
7212
					)
7213
				) );
7214
7215
				if ( !empty( $slug_field ) ) {
7216
					$slug_field = $slug_field[ 0 ];
7217
7218
					$info[ 'field_slug' ] = $info[ 'pod_field_slug' ] = $slug_field->post_name;
7219
				}
7220
7221
				if ( 1 == pods_v( 'hierarchical', $info[ 'pod' ][ 'options' ], 0 ) ) {
7222
					$parent_field = pods_v( 'pod_parent', $info[ 'pod' ][ 'options' ], 'id', true );
7223
7224
					if ( !empty( $parent_field ) && isset( $info[ 'pod' ][ 'fields' ][ $parent_field ] ) ) {
7225
						$info[ 'object_hierarchical' ] = true;
7226
7227
						$info[ 'pod_field_parent' ] = $info[ 'field_parent' ] = $parent_field . '_select';
7228
						$info[ 'field_parent_select' ] = '`' . $parent_field . '`.`id` AS `' . $info[ 'field_parent' ] . '`';
7229
					}
7230
				}
7231
			}
7232
		}
7233
		return $info;
7234
	}
7235
7236
    /**
7237
     * Get information about an objects MySQL table
7238
     *
7239
     * @param string $object_type
7240
     * @param string $object The object to look for
7241
     * @param null $name (optional) Name of the pod to load
7242
     * @param array $pod (optional) Array with pod information
7243
     * @param array $field (optional) Array with field information
7244
     *
7245
     * @return array|bool
7246
     *
7247
     * @since 2.0
7248
     */
7249
    public function get_table_info ( $object_type, $object, $name = null, $pod = null, $field = null ) {
7250
        /**
7251
         * @var $wpdb wpdb
7252
         * @var $sitepress SitePress
7253
         * @var $icl_adjust_id_url_filter_off boolean
7254
         */
7255
        global $wpdb, $sitepress, $icl_adjust_id_url_filter_off, $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...
7256
7257
		// @todo Handle $object arrays for Post Types, Taxonomies, Comments (table pulled from first object in array)
7258
7259
        $info = array(
7260
            //'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...
7261
            'object_type' => $object_type,
7262
            'type' => null,
7263
            'object_name' => $object,
7264
            'object_hierarchical' => false,
7265
7266
            'table' => $object,
7267
            'meta_table' => $object,
7268
            'pod_table' => $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object ),
7269
7270
            'field_id' => 'id',
7271
            'field_index' => 'name',
7272
            'field_slug' => null,
7273
            'field_type' => null,
7274
            'field_parent' => null,
7275
            'field_parent_select' => null,
7276
7277
            'meta_field_id' => 'id',
7278
            'meta_field_index' => 'name',
7279
            'meta_field_value' => 'name',
7280
7281
            'pod_field_id' => 'id',
7282
            'pod_field_index' => 'name',
7283
            'pod_field_slug' => null,
7284
            'pod_field_parent' => null,
7285
7286
            'join' => array(),
7287
7288
            'where' => null,
7289
            'where_default' => null,
7290
7291
            'orderby' => null,
7292
7293
            'pod' => null,
7294
            'recurse' => false
7295
        );
7296
7297
        if ( empty( $object_type ) ) {
7298
            $object_type = 'post_type';
7299
            $object = 'post';
7300
        }
7301
	    elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ) ) ) {
7302
		    $object = $object_type;
7303
	    }
7304
7305
        $pod_name = $pod;
7306
7307 View Code Duplication
        if ( is_array( $pod_name ) )
7308
            $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...
7309
	    else {
7310
		    $pod_name = $object;
7311
	    }
7312
7313
        $field_name = $field;
7314
7315 View Code Duplication
        if ( is_array( $field_name ) )
7316
            $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...
7317
7318
        $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7319
7320
        $current_language = false;
7321
        $current_language_t_id = $current_language_tt_id = 0;
7322
7323
        // WPML support
7324
        if ( is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
7325
            $current_language = pods_sanitize( ICL_LANGUAGE_CODE );
7326
        // Polylang support
7327
        elseif ( is_object( $polylang ) && function_exists( 'pll_current_language' ) ) {
7328
            $current_language = pods_sanitize( pll_current_language( 'slug' ) );
7329
7330
            if ( !empty( $current_language ) ) {
7331
		if ( isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' )) {
7332
			$current_language_t_id = (int) $polylang->model->get_language( $current_language )->term_id;
7333
			$current_language_tt_id = (int) $polylang->model->get_language( $current_language )->term_taxonomy_id;
7334
		} else {
7335
			$current_language_t_id = (int) $polylang->get_language( $current_language )->term_id;
7336
			$current_language_tt_id = (int) $polylang->get_language( $current_language )->term_taxonomy_id;
7337
		}
7338
            }
7339
        }
7340
7341
        if ( !empty( $current_language ) )
7342
            $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7343
7344
        $_info = false;
7345
7346
	    if ( isset( self::$table_info_cache[ $transient ] ) ) {
7347
		    // Prefer info from the object internal cache
7348
		    $_info = self::$table_info_cache[ $transient ];
7349
	    } elseif ( pods_api_cache() ) {
7350
		    $_info = pods_transient_get( $transient );
7351
		    if ( false === $_info && ! did_action( 'init' ) ) {
7352
			    $_info = pods_transient_get( $transient . '_pre_init' );
7353
		    }
7354
	    }
7355
7356
	    if ( false !== $_info ) {
7357
		    // Data was cached, use that
7358
		    $info = $_info;
7359
	    } else {
7360
	        // Data not cached, load it up
7361
		    $_info = $this->get_table_info_load( $object_type, $object, $name, $pod );
7362
		    if ( isset( $_info[ 'type' ] ) ) {
7363
			    // Allow function to override $object_type
7364
			    $object_type = $_info[ 'type' ];
7365
		    }
7366
		    $info = array_merge( $info, $_info );
7367
	    }
7368
7369
	    if ( 0 === strpos( $object_type, 'post_type' ) || 'media' == $object_type || in_array( pods_var_raw( 'type', $info[ 'pod' ] ), array( 'post_type', 'media' ) ) ) {
7370
		    $info[ 'table' ] = $wpdb->posts;
7371
		    $info[ 'meta_table' ] = $wpdb->postmeta;
7372
7373
		    $info[ 'field_id' ] = 'ID';
7374
		    $info[ 'field_index' ] = 'post_title';
7375
		    $info[ 'field_slug' ] = 'post_name';
7376
		    $info[ 'field_type' ] = 'post_type';
7377
		    $info[ 'field_parent' ] = 'post_parent';
7378
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7379
7380
		    $info[ 'meta_field_id' ] = 'post_id';
7381
		    $info[ 'meta_field_index' ] = 'meta_key';
7382
		    $info[ 'meta_field_value' ] = 'meta_value';
7383
7384
		    if ( 'media' == $object_type )
7385
			    $object = 'attachment';
7386
7387
		    if ( empty( $name ) ) {
7388
			    $prefix = 'post_type-';
7389
7390
			    // Make sure we actually have the prefix before trying anything with the name
7391
			    if ( 0 === strpos( $object_type, $prefix ) )
7392
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7393
		    }
7394
7395
		    if ( 'media' != $object_type )
7396
			    $object_type = 'post_type';
7397
7398
		    $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7399
7400
		    if ( 'attachment' == $post_type || 'media' == $object_type )
7401
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_media';
7402
		    else
7403
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $post_type, true, false );
7404
7405
		    $post_type_object = get_post_type_object( $post_type );
7406
7407
		    if ( is_object( $post_type_object ) && $post_type_object->hierarchical )
7408
			    $info[ 'object_hierarchical' ] = true;
7409
7410
		    /**
7411
		     * Default Post Status to query for.
7412
		     *
7413
		     * Use to change "default" post status from publish to any other status or statuses.
7414
		     *
7415
		     * @param  array $post_status List of post statuses. Default is 'publish'
7416
		     * @param  string $post_type Post type of current object
7417
		     * @param  array $info Array of information about the object.
7418
		     * @param  string $object	Type of object
7419
		     * @param  string $name Name of pod to load
7420
		     * @param  array $pod Array with Pod information. Result of PodsAPI::load_pod()
7421
		     * @param  array $field		Array with field information
7422
		     *
7423
		     * @since unknown
7424
		     */
7425
		    $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', array( 'publish' ), $post_type, $info, $object_type, $object, $name, $pod, $field );
7426
7427
		    $info[ 'where' ] = array(
7428
			    //'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
72% 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...
7429
			    'post_type' => '`t`.`' . $info[ 'field_type' ] . '` = "' . $post_type . '"'
7430
		    );
7431
7432
		    if ( 'post_type' == $object_type )
7433
			    $info[ 'where_default' ] = '`t`.`post_status` IN ( "' . implode( '", "', $post_status ) . '" )';
7434
7435
		    $info[ 'orderby' ] = '`t`.`menu_order`, `t`.`' . $info[ 'field_index' ] . '`, `t`.`post_date`';
7436
7437
		    // WPML support
7438 View Code Duplication
		    if ( is_object( $sitepress ) && $sitepress->is_translated_post_type( $post_type ) && !$icl_adjust_id_url_filter_off ) {
7439
			    $info[ 'join' ][ 'wpml_translations' ] = "
7440
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7441
                            ON `wpml_translations`.`element_id` = `t`.`ID`
7442
                                AND `wpml_translations`.`element_type` = 'post_{$post_type}'
7443
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7444
                    ";
7445
7446
			    $info[ 'join' ][ 'wpml_languages' ] = "
7447
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7448
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7449
                    ";
7450
7451
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7452
		    }
7453
		    // Polylang support
7454
		    elseif( is_object( $polylang ) && !empty( $current_language ) && function_exists( 'pll_is_translated_post_type' ) && pll_is_translated_post_type( $post_type ) ) {
7455
			    $info[ 'join' ][ 'polylang_languages' ] = "
7456
                        LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7457
                            ON `polylang_languages`.`object_id` = `t`.`ID`
7458
                                AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id}
7459
                    ";
7460
7461
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7462
		    }
7463
7464
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7465
	    }
7466
	    elseif ( 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, array( 'nav_menu', 'post_format' ) ) || 'taxonomy' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7467
		    $info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->terms;
7468
7469
		    $info[ 'join' ][ 'tt' ] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`";
7470
		    $info[ 'join' ][ 'tr' ] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`";
7471
		    $info[ 'field_id' ] = $info[ 'meta_field_id' ] = 'term_id';
7472
		    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = 'name';
7473
		    $info[ 'field_slug' ] = 'slug';
7474
		    $info[ 'field_type' ] = 'taxonomy';
7475
		    $info[ 'field_parent' ] = 'parent';
7476
		    $info[ 'field_parent_select' ] = '`tt`.`' . $info[ 'field_parent' ] . '`';
7477
7478
            if ( ! empty( $wpdb->termmeta ) ) {
7479
                $info[ 'meta_table' ] = $wpdb->termmeta;
7480
7481
                $info[ 'meta_field_id' ] = 'term_id';
7482
                $info[ 'meta_field_index' ] = 'meta_key';
7483
                $info[ 'meta_field_value' ] = 'meta_value';
7484
            }
7485
7486
		    if ( 'nav_menu' == $object_type )
7487
			    $object = 'nav_menu';
7488
		    elseif ( 'post_format' == $object_type )
7489
			    $object = 'post_format';
7490
7491
		    if ( empty( $name ) ) {
7492
			    $prefix = 'taxonomy-';
7493
7494
			    // Make sure we actually have the prefix before trying anything with the name
7495
			    if ( 0 === strpos( $object_type, $prefix ) )
7496
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7497
		    }
7498
7499
		    if ( !in_array( $object_type, array( 'nav_menu', 'post_format' ) ) )
7500
			    $object_type = 'taxonomy';
7501
7502
		    $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7503
7504
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $taxonomy, true, false );
7505
7506
		    $taxonomy_object = get_taxonomy( $taxonomy );
7507
7508
		    if ( is_object( $taxonomy_object ) && $taxonomy_object->hierarchical )
7509
			    $info[ 'object_hierarchical' ] = true;
7510
7511
		    $info[ 'where' ] = array(
7512
			    'tt.taxonomy' => '`tt`.`' . $info[ 'field_type' ] . '` = "' . $taxonomy . '"'
7513
		    );
7514
7515
		    // WPML Support
7516 View Code Duplication
		    if ( is_object( $sitepress ) && $sitepress->is_translated_taxonomy( $taxonomy ) && !$icl_adjust_id_url_filter_off ) {
7517
			    $info[ 'join' ][ 'wpml_translations' ] = "
7518
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7519
                            ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id`
7520
                                AND `wpml_translations`.`element_type` = 'tax_{$taxonomy}'
7521
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7522
                    ";
7523
7524
			    $info[ 'join' ][ 'wpml_languages' ] = "
7525
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7526
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7527
                    ";
7528
7529
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7530
		    }
7531
		    // Polylang support
7532
		    elseif ( is_object( $polylang ) && !empty( $current_language ) && function_exists( 'pll_is_translated_taxonomy' ) && pll_is_translated_taxonomy( $taxonomy ) ) {
7533
			    $info[ 'join' ][ 'polylang_languages' ] = "
7534
                        LEFT JOIN `{$wpdb->termmeta}` AS `polylang_languages`
7535
                            ON `polylang_languages`.`term_id` = `t`.`term_id`
7536
                                AND `polylang_languages`.`meta_value` = {$current_language_t_id}
7537
                    ";
7538
7539
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`term_id` IS NOT NULL";
7540
		    }
7541
7542
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7543
	    }
7544
	    elseif ( 'user' == $object_type || 'user' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7545
		    $info[ 'table' ] = $wpdb->users;
7546
		    $info[ 'meta_table' ] = $wpdb->usermeta;
7547
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_user';
7548
7549
		    $info[ 'field_id' ] = 'ID';
7550
		    $info[ 'field_index' ] = 'display_name';
7551
		    $info[ 'field_slug' ] = 'user_nicename';
7552
7553
		    $info[ 'meta_field_id' ] = 'user_id';
7554
		    $info[ 'meta_field_index' ] = 'meta_key';
7555
		    $info[ 'meta_field_value' ] = 'meta_value';
7556
7557
		    $info[ 'where' ] = array(
7558
			    'user_status' => '`t`.`user_status` = 0'
7559
		    );
7560
7561
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7562
	    }
7563
	    elseif ( 'comment' == $object_type || 'comment' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7564
		    //$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...
7565
7566
		    $info[ 'table' ] = $wpdb->comments;
7567
		    $info[ 'meta_table' ] = $wpdb->commentmeta;
7568
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_comment';
7569
7570
		    $info[ 'field_id' ] = 'comment_ID';
7571
		    $info[ 'field_index' ] = 'comment_date';
7572
		    $info[ 'field_type' ] = 'comment_type';
7573
		    $info[ 'field_parent' ] = 'comment_parent';
7574
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7575
7576
		    $info[ 'meta_field_id' ] = 'comment_id';
7577
		    $info[ 'meta_field_index' ] = 'meta_key';
7578
		    $info[ 'meta_field_value' ] = 'meta_value';
7579
7580
		    $object = 'comment';
7581
7582
		    $comment_type = ( empty( $object ) ? $name : $object );
7583
7584
		    $comment_type_clause = '`t`.`' . $info[ 'field_type' ] . '` = "' . $comment_type . '"';
7585
7586
		    if ( 'comment' == $comment_type ) {
7587
			    $comment_type_clause = '( ' . $comment_type_clause . ' OR `t`.`' . $info[ 'field_type' ] . '` = "" )';
7588
		    }
7589
7590
		    $info[ 'where' ] = array(
7591
			    'comment_approved' => '`t`.`comment_approved` = 1',
7592
			    'comment_type' => $comment_type_clause
7593
		    );
7594
7595
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` DESC, `t`.`' . $info[ 'field_id' ] . '`';
7596
	    }
7597 View Code Duplication
	    elseif ( in_array( $object_type, array( 'option', 'settings' ) ) || 'settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7598
		    $info[ 'table' ] = $wpdb->options;
7599
		    $info[ 'meta_table' ] = $wpdb->options;
7600
7601
		    $info[ 'field_id' ] = 'option_id';
7602
		    $info[ 'field_index' ] = 'option_name';
7603
7604
		    $info[ 'meta_field_id' ] = 'option_id';
7605
		    $info[ 'meta_field_index' ] = 'option_name';
7606
		    $info[ 'meta_field_value' ] = 'option_value';
7607
7608
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7609
	    }
7610 View Code Duplication
	    elseif ( is_multisite() && ( in_array( $object_type, array( 'site_option', 'site_settings' ) ) || 'site_settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) ) {
7611
		    $info[ 'table' ] = $wpdb->sitemeta;
7612
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7613
7614
		    $info[ 'field_id' ] = 'site_id';
7615
		    $info[ 'field_index' ] = 'meta_key';
7616
7617
		    $info[ 'meta_field_id' ] = 'site_id';
7618
		    $info[ 'meta_field_index' ] = 'meta_key';
7619
		    $info[ 'meta_field_value' ] = 'meta_value';
7620
7621
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7622
	    }
7623
	    elseif ( is_multisite() && 'network' == $object_type ) { // Network = Site
7624
		    $info[ 'table' ] = $wpdb->site;
7625
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7626
7627
		    $info[ 'field_id' ] = 'id';
7628
		    $info[ 'field_index' ] = 'domain';
7629
7630
		    $info[ 'meta_field_id' ] = 'site_id';
7631
		    $info[ 'meta_field_index' ] = 'meta_key';
7632
		    $info[ 'meta_field_value' ] = 'meta_value';
7633
7634
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7635
	    }
7636
	    elseif ( is_multisite() && 'site' == $object_type ) { // Site = Blog
7637
		    $info[ 'table' ] = $wpdb->blogs;
7638
7639
		    $info[ 'field_id' ] = 'blog_id';
7640
		    $info[ 'field_index' ] = 'domain';
7641
		    $info[ 'field_type' ] = 'site_id';
7642
7643
		    $info[ 'where' ] = array(
7644
			    'archived' => '`t`.`archived` = 0',
7645
			    'spam' => '`t`.`spam` = 0',
7646
			    'deleted' => '`t`.`deleted` = 0',
7647
			    'site_id' => '`t`.`' . $info[ 'field_type' ] . '` = ' . (int) get_current_site()->id
7648
		    );
7649
7650
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7651
	    }
7652
	    elseif ( 'table' == $object_type || 'table' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7653
		    $info[ 'table' ] = ( empty( $object ) ? $name : $object );
7654
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . $info[ 'table' ];
7655
7656
		    if ( !empty( $field ) && is_array( $field ) ) {
7657
			    $info[ 'table' ] = pods_var_raw( 'pick_table', pods_var_raw( 'options', $field, $field ) );
7658
			    $info[ 'field_id' ] = pods_var_raw( 'pick_table_id', pods_var_raw( 'options', $field, $field ) );
7659
			    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_var_raw( 'pick_table_index', pods_var_raw( 'options', $field, $field ) );
7660
		    }
7661
	    }
7662
7663
	    $info[ 'table' ] = pods_clean_name( $info[ 'table' ], false, false );
7664
	    $info[ 'meta_table' ] = pods_clean_name( $info[ 'meta_table' ], false, false );
7665
	    $info[ 'pod_table' ] = pods_clean_name( $info[ 'pod_table' ], false, false );
7666
7667
	    $info[ 'field_id' ] = pods_clean_name( $info[ 'field_id' ], false, false );
7668
	    $info[ 'field_index' ] = pods_clean_name( $info[ 'field_index' ], false, false );
7669
	    $info[ 'field_slug' ] = pods_clean_name( $info[ 'field_slug' ], false, false );
7670
7671
	    $info[ 'meta_field_id' ] = pods_clean_name( $info[ 'meta_field_id' ], false, false );
7672
	    $info[ 'meta_field_index' ] = pods_clean_name( $info[ 'meta_field_index' ], false, false );
7673
	    $info[ 'meta_field_value' ] = pods_clean_name( $info[ 'meta_field_value' ], false, false );
7674
7675 View Code Duplication
	    if ( empty( $info[ 'orderby' ] ) )
7676
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '`, `t`.`' . $info[ 'field_id' ] . '`';
7677
7678
	    if ( 'table' == pods_var_raw( 'storage', $info[ 'pod' ] ) && !in_array( $object_type, array( 'pod', 'table' ) ) ) {
7679
		    $info[ 'join' ][ 'd' ] = 'LEFT JOIN `' . $info[ 'pod_table' ] . '` AS `d` ON `d`.`id` = `t`.`' . $info[ 'field_id' ] . '`';
7680
		    //$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...
7681
	    }
7682
7683
	    if ( !empty( $info[ 'pod' ] ) && is_array( $info[ 'pod' ] ) )
7684
		    $info[ 'recurse' ] = true;
7685
7686
	    $info[ 'type' ] = $object_type;
7687
	    $info[ 'object_name' ] = $object;
7688
7689
	    if ( pods_api_cache() ) {
7690
		    if ( ! did_action( 'init' ) ) {
7691
			    $transient .= '_pre_init';
7692
		    }
7693
		    pods_transient_set( $transient, $info );
7694
	    }
7695
7696
7697
	    self::$table_info_cache[ $transient ] = apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
7698
7699
        return self::$table_info_cache[ $transient ];
7700
    }
7701
7702
    /**
7703
     * Export a package
7704
     *
7705
     * $params['pod'] string Pod Type IDs to export
7706
     * $params['template'] string Template IDs to export
7707
     * $params['podpage'] string Pod Page IDs to export
7708
     * $params['helper'] string Helper IDs to export
7709
     *
7710
     * @param array $params An associative array of parameters
7711
     *
7712
     * @return array|bool
7713
     *
7714
     * @since 1.9.0
7715
     * @deprecated 2.0
7716
     */
7717
    public function export_package ( $params ) {
7718
        if ( class_exists( 'Pods_Migrate_Packages' ) )
7719
            return Pods_Migrate_Packages::export( $params );
7720
7721
        return false;
7722
    }
7723
7724
    /**
7725
     * Replace an existing package
7726
     *
7727
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
7728
     *
7729
     * @return bool
7730
     *
7731
     * @since 1.9.8
7732
     * @deprecated 2.0
7733
     */
7734
    public function replace_package ( $data = false ) {
7735
        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...
7736
    }
7737
7738
    /**
7739
     * Import a package
7740
     *
7741
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
7742
     * @param bool $replace (optional) Replace existing items when found
7743
     *
7744
     * @return bool
7745
     *
7746
     * @since 1.9.0
7747
     * @deprecated 2.0
7748
     */
7749
    public function import_package ( $data = false, $replace = false ) {
7750
        if ( class_exists( 'Pods_Migrate_Packages' ) )
7751
            return Pods_Migrate_Packages::import( $data, $replace );
7752
7753
        return false;
7754
    }
7755
7756
    /**
7757
     * Validate a package
7758
     *
7759
     * @param array|string $data (optional) An associative array containing a package, or the json encoded package
7760
     * @param bool $output (optional)
7761
     *
7762
     * @return array|bool
7763
     *
7764
     * @since 1.9.0
7765
     * @deprecated 2.0
7766
     */
7767
    public function validate_package ( $data = false, $output = false ) {
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

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

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

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

Loading history...
7768
        return true;
7769
    }
7770
7771
    /**
7772
     * Import data from an array or a CSV file.
7773
     *
7774
     * @param mixed $import_data PHP associative array or CSV input
7775
     * @param bool $numeric_mode Use IDs instead of the name field when matching
7776
     * @param string $format Format of import data, options are php or csv
7777
     *
7778
     * @return array IDs of imported items
7779
     *
7780
     * @since 1.7.1
7781
     * @todo This needs some love and use of table_info etc for relationships
7782
     */
7783
    public function import ( $import_data, $numeric_mode = false, $format = null ) {
7784
        /**
7785
         * @var $wpdb wpdb
7786
         */
7787
        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...
7788
7789
        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...
7790
            $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...
7791
7792
        if ( 'csv' == $format && !is_array( $import_data ) ) {
7793
            $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...
7794
7795
            $import_data = $data[ 'items' ];
7796
        }
7797
7798
        pods_query( "SET NAMES utf8" );
7799
        pods_query( "SET CHARACTER SET utf8" );
7800
7801
        // Loop through the array of items
7802
        $ids = array();
7803
7804
        // Test to see if it's an array of arrays
7805
        if ( !is_array( @current( $import_data ) ) )
7806
            $import_data = array( $import_data );
7807
7808
        $pod = $this->load_pod( array( 'name' => $this->pod ) );
7809
7810
        if ( false === $pod )
7811
            return pods_error( __( 'Pod not found', 'pods' ), $this );
7812
7813
        $fields = array_merge( $pod[ 'fields' ], $pod[ 'object_fields' ] );
7814
7815
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
7816
7817
        foreach ( $import_data as $key => $data_row ) {
7818
            $data = array();
7819
7820
            // Loop through each field (use $fields so only valid fields get parsed)
7821
            foreach ( $fields as $field_name => $field_data ) {
7822
                if ( !isset( $data_row[ $field_name ] ) && !isset( $data_row[ $field_data[ 'label' ] ] ) )
7823
                    continue;
7824
7825
                $field_id = $field_data[ 'id' ];
7826
                $type = $field_data[ 'type' ];
7827
                $pick_object = isset( $field_data[ 'pick_object' ] ) ? $field_data[ 'pick_object' ] : '';
7828
                $pick_val = isset( $field_data[ 'pick_val' ] ) ?  $field_data[ 'pick_val' ] : '';
7829
7830
                if ( isset( $data_row[ $field_name] ) )
7831
                    $field_value = $data_row[ $field_name ];
7832
                else
7833
                    $field_value = $data_row[ $field_data[ 'label' ] ];
7834
7835
                if ( null !== $field_value && false !== $field_value && '' !== $field_value ) {
7836
                    if ( 'pick' == $type || in_array( $type, PodsForm::file_field_types() ) ) {
7837
                        $field_values = is_array( $field_value ) ? $field_value : array( $field_value );
7838
                        $pick_values = array();
7839
7840
                        foreach ( $field_values as $pick_value ) {
7841
                            if ( in_array( $type, PodsForm::file_field_types() ) || 'media' == $pick_object ) {
7842
                                $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'";
7843
7844 View Code Duplication
                                if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7845
                                    $where = "`ID` = " . pods_absint( $pick_value );
7846
7847
                                $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = 'attachment' AND {$where} ORDER BY `ID`", $this );
7848
7849
                                if ( !empty( $result ) )
7850
                                    $pick_values[] = $result[ 0 ]->id;
7851
                            }
7852
                            // @todo This could and should be abstracted better and simplified
7853
                            elseif ( 'pick' == $type ) {
7854
                                $related_pod = false;
7855
7856
                                if ( 'pod' == $pick_object )
7857
                                    $related_pod = $this->load_pod( array( 'name' => $pick_val, 'table_info' => true ), false );
7858
7859
                                if ( empty( $related_pod ) ) {
7860
                                    $related_pod = array(
7861
                                        'id' => 0,
7862
                                        'type' => $pick_object
7863
                                    );
7864
                                }
7865
7866
                                if ( in_array( 'taxonomy', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
7867
                                    $where = "`t`.`name` = '" . pods_sanitize( $pick_value ) . "'";
7868
7869 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7870
                                        $where = "`tt`.`term_id` = " . pods_absint( $pick_value );
7871
7872
                                    $result = pods_query( "SELECT `t`.`term_id` AS `id` FROM `{$wpdb->term_taxonomy}` AS `tt` LEFT JOIN `{$wpdb->terms}` AS `t` ON `t`.`term_id` = `tt`.`term_id` WHERE `taxonomy` = '{$pick_val}' AND {$where} ORDER BY `t`.`term_id`", $this );
7873
7874
                                    if ( !empty( $result ) )
7875
                                        $pick_values[] = $result[ 0 ]->id;
7876
                                }
7877
                                elseif ( in_array( 'post_type', array( $pick_object, $related_pod[ 'type' ] ) ) || in_array( 'media', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
7878
                                    $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'";
7879
7880 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7881
                                        $where = "`ID` = " . pods_absint( $pick_value );
7882
7883
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = '{$pick_val}' AND {$where} ORDER BY `ID`", $this );
7884
7885
                                    if ( !empty( $result ) )
7886
                                        $pick_values[] = $result[ 0 ]->id;
7887
                                }
7888
                                elseif ( in_array( 'user', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
7889
                                    $where = "`user_login` = '" . pods_sanitize( $pick_value ) . "'";
7890
7891 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7892
                                        $where = "`ID` = " . pods_absint( $pick_value );
7893
7894
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->users}` WHERE {$where} ORDER BY `ID`", $this );
7895
7896
                                    if ( !empty( $result ) )
7897
                                        $pick_values[] = $result[ 0 ]->id;
7898
                                }
7899
                                elseif ( in_array( 'comment', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
7900
                                    $where = "`comment_ID` = " . pods_absint( $pick_value );
7901
7902
                                    $result = pods_query( "SELECT `comment_ID` AS `id` FROM `{$wpdb->comments}` WHERE {$where} ORDER BY `ID`", $this );
7903
7904
                                    if ( !empty( $result ) )
7905
                                        $pick_values[] = $result[ 0 ]->id;
7906
                                }
7907
                                elseif ( in_array( $pick_object, $simple_tableless_objects ) )
7908
                                    $pick_values[] = $pick_value;
7909
                                elseif ( !empty( $related_pod[ 'id' ] ) ) {
7910
                                    $where = "`" . $related_pod[ 'field_index' ] . "` = '" . pods_sanitize( $pick_value ) . "'";
7911
7912
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7913
                                        $where = "`" . $related_pod[ 'field_id' ] . "` = " . pods_absint( $pick_value );
7914
7915
                                    $result = pods_query( "SELECT `" . $related_pod[ 'field_id' ] . "` AS `id` FROM `" . $related_pod[ 'table' ] . "` WHERE {$where} ORDER BY `" . $related_pod[ 'field_id' ] . "`", $this );
7916
7917
                                    if ( !empty( $result ) )
7918
                                        $pick_values[] = $result[ 0 ]->id;
7919
                                }
7920
                            }
7921
                        }
7922
7923
                        $field_value = implode( ',', $pick_values );
7924
                    }
7925
7926
                    $data[ $field_name ] = $field_value;
7927
                }
7928
            }
7929
7930
            if ( !empty( $data ) ) {
7931
                $params = array(
7932
                    'pod' => $this->pod,
7933
                    'data' => $data
7934
                );
7935
7936
                $ids[] = $this->save_pod_item( $params );
7937
            }
7938
        }
7939
7940
        return $ids;
7941
    }
7942
7943
    /**
7944
     * Export data from a Pod
7945
     *
7946
     * @param string|object $pod The pod name or Pods object
7947
     * @param array $params An associative array of parameters
7948
     *
7949
     * @return array Data arrays of all exported pod items
7950
     * @since 1.7.1
7951
     */
7952
    public function export ( $pod = null, $params = null ) {
7953
7954
        if ( empty( $pod ) ) {
7955
            $pod = $this->pod;
7956
        }
7957
7958
        $find = array(
7959
            'limit' => -1,
7960
            'search' => false,
7961
            'pagination' => false
7962
        );
7963
7964
        if ( !empty( $params ) && isset( $params[ 'params' ] ) ) {
7965
            $find = array_merge( $find, (array) $params[ 'params' ] );
7966
7967
            unset( $params[ 'params' ] );
7968
7969
            $pod = pods( $pod, $find );
7970
        }
7971
        elseif ( !is_object( $pod ) ) {
7972
            $pod = pods( $pod, $find );
7973
        }
7974
7975
        $data = array();
7976
7977
        while ( $pod->fetch() ) {
7978
            $data[ $pod->id() ] = $this->export_pod_item( $params, $pod );
7979
        }
7980
7981
        $data = $this->do_hook( 'export', $data, $pod->pod, $pod );
7982
7983
        return $data;
7984
    }
7985
7986
    /**
7987
     * Convert CSV to a PHP array
7988
     *
7989
     * @param string $data The CSV input
7990
     *
7991
     * @return array
7992
     * @since 1.7.1
7993
     *
7994
     * @deprecated 2.3.5
7995
     */
7996
    public function csv_to_php ( $data, $delimiter = ',' ) {
7997
        pods_deprecated( "PodsAPI->csv_to_php", '2.3.5' );
7998
7999
        $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...
8000
8001
        return $data[ 'items' ];
8002
    }
8003
8004
    /**
8005
     * Clear Pod-related cache
8006
     *
8007
     * @param array $pod
8008
     *
8009
     * @return void
8010
     *
8011
     * @since 2.0
8012
     */
8013
    public function cache_flush_pods ( $pod = null ) {
8014
        /**
8015
         * @var $wpdb wpdb
8016
         */
8017
        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...
8018
8019
        pods_transient_clear( 'pods' );
8020
        pods_transient_clear( 'pods_components' );
8021
8022
        if ( null !== $pod && is_array( $pod ) ) {
8023
            pods_transient_clear( 'pods_pod_' . $pod[ 'name' ] );
8024
            pods_cache_clear( $pod[ 'name' ], 'pods-class' );
8025
8026
            foreach ( $pod[ 'fields' ] as $field ) {
8027
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
8028
            }
8029
8030
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) )
8031
                pods_transient_clear( 'pods_wp_cpt_ct' );
8032
        }
8033
        else
8034
            pods_transient_clear( 'pods_wp_cpt_ct' );
8035
8036
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" );
8037
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" );
8038
8039
        pods_cache_clear( true );
8040
8041
        pods_transient_set( 'pods_flush_rewrites', 1 );
8042
    }
8043
8044
    /**
8045
     * Process a Pod-based form
8046
     *
8047
     * @param mixed $params
8048
     * @param object $obj Pod object
8049
     * @param array $fields Fields being submitted in form ( key => settings )
8050
     * @param string $thank_you URL to send to upon success
8051
     *
8052
     * @return mixed
8053
     *
8054
     * @since 2.0
8055
     */
8056
    public function process_form ( $params, $obj = null, $fields = null, $thank_you = null ) {
8057
        $this->display_errors = false;
8058
8059
        $form = null;
8060
8061
        $nonce = pods_var( '_pods_nonce', $params );
8062
        $pod = pods_var( '_pods_pod', $params );
8063
        $id = pods_var( '_pods_id', $params );
8064
        $uri = pods_var( '_pods_uri', $params );
8065
        $form = pods_var( '_pods_form', $params );
8066
        $location = pods_var( '_pods_location', $params );
8067
8068
        if ( is_object( $obj ) ) {
8069
            $pod = $obj->pod;
8070
            $id = $obj->id();
8071
        }
8072
8073
        if ( !empty( $fields ) ) {
8074
            $fields = array_keys( $fields );
8075
            $form = implode( ',', $fields );
8076
        }
8077
        else
8078
            $fields = explode( ',', $form );
8079
8080
        if ( empty( $nonce ) || empty( $pod ) || empty( $uri ) || empty( $fields ) )
8081
            return pods_error( __( 'Invalid submission', 'pods' ), $this );
8082
8083
        $uid = @session_id();
8084
8085
        if ( is_user_logged_in() )
8086
            $uid = 'user_' . get_current_user_id();
8087
8088
		$field_hash = wp_create_nonce( 'pods_fields_' . $form );
8089
8090
        $action = 'pods_form_' . $pod . '_' . $uid . '_' . $id . '_' . $uri . '_' . $field_hash;
8091
8092
        if ( empty( $uid ) )
8093
            return pods_error( __( 'Access denied for your session, please refresh and try again.', 'pods' ), $this );
8094
8095
        if ( false === wp_verify_nonce( $nonce, $action ) )
8096
            return pods_error( __( 'Access denied, please refresh and try again.', 'pods' ), $this );
8097
8098
        $data = array();
8099
8100
        foreach ( $fields as $field ) {
8101
            $data[ $field ] = pods_var_raw( 'pods_field_' . $field, $params, '' );
8102
        }
8103
8104
        $params = array(
8105
            'pod' => $pod,
8106
            'id' => $id,
8107
            'data' => $data,
8108
            'from' => 'process_form',
8109
			'location' => $location
8110
        );
8111
8112
        $id = $this->save_pod_item( $params );
8113
8114
        if ( 0 < $id && !empty( $thank_you ) ) {
8115
            $thank_you = str_replace( 'X_ID_X', $id, $thank_you );
8116
8117
            pods_redirect( $thank_you );
8118
        }
8119
8120
        return $id;
8121
    }
8122
8123
    /**
8124
     * Handle filters / actions for the class
8125
     *
8126
     * @since 2.0
8127
     */
8128 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...
8129
        $args = func_get_args();
8130
        if ( empty( $args ) )
8131
            return false;
8132
        $name = array_shift( $args );
8133
        return pods_do_hook( "api", $name, $args, $this );
8134
    }
8135
8136
    /**
8137
     * Handle variables that have been deprecated
8138
     *
8139
     * @since 2.0
8140
     */
8141
    public function __get ( $name ) {
8142
        $name = (string) $name;
8143
8144 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8145
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8146
            $this->deprecated = new PodsAPI_Deprecated( $this );
8147
        }
8148
8149
        $var = null;
8150
8151
        if ( isset( $this->deprecated->{$name} ) ) {
8152
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8153
8154
            $var = $this->deprecated->{$name};
8155
        }
8156
        else
8157
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8158
8159
        return $var;
8160
    }
8161
8162
    /**
8163
     * Handle methods that have been deprecated
8164
     *
8165
     * @since 2.0
8166
     */
8167
    public function __call ( $name, $args ) {
8168
        $name = (string) $name;
8169
8170 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8171
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8172
            $this->deprecated = new PodsAPI_Deprecated( $this );
8173
        }
8174
8175
        if ( method_exists( $this->deprecated, $name ) )
8176
            return call_user_func_array( array( $this->deprecated, $name ), $args );
8177
        else
8178
            pods_deprecated( "PodsAPI::{$name}", '2.0' );
8179
    }
8180
}