Completed
Push — 2.x ( 070e4c...38f1a0 )
by Scott Kingsley
10s
created

PodsAPI::get_current_language()   F

Complexity

Conditions 53

Size

Total Lines 203
Code Lines 68

Duplication

Lines 73
Ratio 35.96 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
cc 53
eloc 68
c 6
b 0
f 1
nop 0
dl 73
loc 203
rs 2

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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

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

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
11
12
	/**
13
	 * @var array PodsAPI
14
	 */
15
	static $instances = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $instances.

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

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
16
17
18
    /**
19
     * @var bool
20
     */
21
    public $display_errors = false;
22
23
    /**
24
     * @var array|bool|mixed|null|void
25
     */
26
    public $pod_data;
27
28
    /**
29
     * @var
30
     */
31
    public $pod;
32
33
    /**
34
     * @var
35
     */
36
    public $pod_id;
37
38
    /**
39
     * @var
40
     */
41
    public $fields;
42
43
    /**
44
     * @var
45
     * @deprecated 2.0
46
     */
47
    public $format = null;
48
49
    /**
50
     * @var
51
     */
52
    private $deprecated;
53
54
	/**
55
	 * @var array
56
	 * @since 2.5
57
	 */
58
	private $fields_cache = array();
59
60
	/**
61
	 * @var array
62
	 * @since 2.5
63
	 *
64
	 */
65
	private static $table_info_cache = array();
66
67
	/**
68
	 * @var array
69
	 * @since 2.5
70
	 *
71
	 */
72
	private static $related_item_cache = array();
73
74
	/**
75
     * Singleton-ish handling for a basic pods_api() request
76
     *
77
     * @param string $pod (optional) The pod name
78
     * @param string $format (deprecated) Format for import/export, "php" or "csv"
79
     *
80
     * @return \PodsAPI
81
     *
82
     * @since 2.3.5
83
     */
84
	public static function init ( $pod = null, $format = null ) {
85
		if ( null !== $pod || null !== $format ) {
86
			if ( ! isset( self::$instances[ $pod ] ) ) {
87
				// Cache API singleton per Pod
88
				self::$instances[ $pod ] = new PodsAPI( $pod, $format );
89
			}
90
			return self::$instances[ $pod ];
91
		}
92
		elseif ( !is_object( self::$instance ) ) {
93
			self::$instance = new PodsAPI();
94
		}
95
96
		return self::$instance;
97
	}
98
99
100
    /**
101
     * Store and retrieve data programatically
102
     *
103
     * @param string $pod (optional) The pod name
104
     * @param string $format (deprecated) Format for import/export, "php" or "csv"
105
     *
106
     * @return \PodsAPI
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

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

Please refer to the PHP core documentation on constructors.

Loading history...
107
     *
108
     * @license http://www.gnu.org/licenses/gpl-2.0.html
109
     * @since 1.7.1
110
     */
111
    public function __construct ( $pod = null, $format = null ) {
112
        if ( null !== $pod && 0 < strlen( (string) $pod ) ) {
113
            if ( null !== $format ) {
114
                $this->format = $format;
0 ignored issues
show
Deprecated Code introduced by
The property PodsAPI::$format has been deprecated with message: 2.0

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading history...
689
        if ( ! function_exists( 'get_term_meta' ) ) {
690
        	return $id;
691
        }
692
693
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
694
695
        $conflicted = pods_no_conflict_check( 'taxonomy' );
696
697
        if ( !$conflicted )
698
            pods_no_conflict_on( 'taxonomy' );
699
700
        if ( !is_array( $term_meta ) )
701
            $term_meta = array();
702
703
        $id = (int) $id;
704
705
        $meta = get_term_meta( $id );
706
707
        foreach ( $meta as $k => $value ) {
708
            if ( is_array( $value ) && 1 == count( $value ) )
709
                $meta[ $k ] = current( $value );
710
        }
711
712
        foreach ( $term_meta as $meta_key => $meta_value ) {
713
            if ( null === $meta_value || ( $strict && '' === $term_meta[ $meta_key ] ) ) {
714
                $old_meta_value = '';
715
716
                if ( isset( $meta[ $meta_key ] ) )
717
                    $old_meta_value = $meta[ $meta_key ];
718
719
                delete_term_meta( $id, $meta_key, $old_meta_value );
720
            }
721
            else {
722
				$simple = false;
723
724
				if ( isset( $fields[ $meta_key ] ) ) {
725
					$field_data = $fields[ $meta_key ];
726
727
					$simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
728
				}
729
730
				if ( $simple ) {
731
					delete_term_meta( $id, $meta_key );
732
733
					update_term_meta( $id, '_pods_' . $meta_key, $meta_value );
734
735
					if ( ! is_array( $meta_value ) ) {
736
						$meta_value = array( $meta_value );
737
					}
738
739
					foreach ( $meta_value as $value ) {
740
						add_term_meta( $id, $meta_key, $value );
741
					}
742
				}
743
				else {
744
                	update_term_meta( $id, $meta_key, $meta_value );
745
				}
746
			}
747
        }
748
749
        if ( $strict ) {
750
            foreach ( $meta as $meta_key => $meta_value ) {
751
                if ( !isset( $term_meta[ $meta_key ] ) )
752
                    delete_term_meta( $id, $meta_key, $meta_value );
753
            }
754
        }
755
756
        if ( !$conflicted )
757
            pods_no_conflict_off( 'taxonomy' );
758
759
        return $id;
760
    }
761
762
    /**
763
     * Save a set of options
764
     *
765
     * @param string $setting Setting group name
766
     * @param array $option_data All option data to be saved
767
     * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
768
     *
769
     * @return bool
770
     *
771
     * @since 2.3
772
     */
773
    public function save_setting ( $setting, $option_data, $sanitized = false ) {
774 View Code Duplication
        if ( !is_array( $option_data ) || empty( $option_data ) )
775
            return pods_error( __( 'Setting data is required but is either invalid or empty', 'pods' ), $this );
776
777
        $conflicted = pods_no_conflict_check( 'settings' );
778
779
        if ( !$conflicted )
780
            pods_no_conflict_on( 'settings' );
781
782
        if ( $sanitized )
783
            $option_data = pods_unsanitize( $option_data );
784
785
        foreach ( $option_data as $option => $value ) {
786
            if ( !empty( $setting ) )
787
                $option = $setting . '_' . $option;
788
789
            update_option( $option, $value );
790
        }
791
792
        if ( !$conflicted )
793
            pods_no_conflict_off( 'settings' );
794
795
        return true;
796
    }
797
798
    /**
799
     * Rename a WP object's type
800
     *
801
     * @param string $object_type Object type: post|taxonomy|comment|setting
802
     * @param string $old_name The old name
803
     * @param string $new_name The new name
804
     *
805
     * @return bool
806
     *
807
     * @since 2.0
808
     */
809
    public function rename_wp_object_type ( $object_type, $old_name, $new_name ) {
810
        /**
811
         * @var $wpdb wpdb
812
         */
813
        global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
814
815
        if ( 'post_type' == $object_type )
816
            $object_type = 'post';
817
818
        if ( 'post' == $object_type ) {
819
            pods_query( "UPDATE `{$wpdb->posts}` SET `post_type` = %s WHERE `post_type` = %s", array(
820
                $new_name,
821
                $old_name
822
            ) );
823
        }
824
        elseif ( 'taxonomy' == $object_type ) {
825
            pods_query( "UPDATE `{$wpdb->term_taxonomy}` SET `taxonomy` = %s WHERE `taxonomy` = %s", array(
826
                $new_name,
827
                $old_name
828
            ) );
829
        }
830
        elseif ( 'comment' == $object_type ) {
831
            pods_query( "UPDATE `{$wpdb->comments}` SET `comment_type` = %s WHERE `comment_type` = %s", array(
832
                $new_name,
833
                $old_name
834
            ) );
835
        }
836
        elseif ( 'settings' == $object_type ) {
837
            pods_query( "UPDATE `{$wpdb->options}` SET `option_name` = REPLACE( `option_name`, %s, %s ) WHERE `option_name` LIKE '" . pods_sanitize_like( $old_name ) . "_%'", array(
838
                $new_name . '_',
839
                $old_name . '_'
840
            ) );
841
        }
842
843
        return true;
844
    }
845
846
    /**
847
     * Get a list of core WP object fields for a specific object
848
     *
849
     * @param string $object The pod type to look for, possible values: post_type, user, comment, taxonomy
850
     * @param array $pod Array of Pod data
851
     * @param boolean $refresh Whether to force refresh the information
852
     *
853
     * @return array Array of fields
854
     *
855
     * @since 2.0
856
     */
857
    public function get_wp_object_fields ( $object = 'post_type', $pod = null, $refresh = false ) {
858
        $pod_name = pods_var_raw( 'name', $pod, $object, null, true );
859
860
		if ( 'media' == $pod_name ) {
861
			$object = 'post_type';
862
			$pod_name = 'attachment';
863
		}
864
865
        $fields = false;
866
867
        if ( pods_api_cache() )
868
            $fields = pods_transient_get( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ) );
869
870
        if ( false !== $fields && !$refresh )
871
            return $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
872
873
        $fields = array();
874
875
        if ( 'post_type' == $object ) {
876
            $fields = array(
877
	            'ID' => array(
878
		            'name' => 'ID',
879
		            'label' => 'ID',
880
		            'type' => 'number',
881
		            'alias' => array( 'id' ),
882
	                'options' => array(
883
                        'number_format' => '9999.99'
884
	                )
885
	            ),
886
                'post_title' => array(
887
                    'name' => 'post_title',
888
                    'label' => 'Title',
889
                    'type' => 'text',
890
                    'alias' => array( 'title', 'name' ),
891
                    'options' => array(
892
                        'display_filter' => 'the_title',
893
                        'display_filter_args' => array( 'post_ID' )
894
                    )
895
                ),
896
                'post_content' => array(
897
                    'name' => 'post_content',
898
                    'label' => 'Content',
899
                    'type' => 'wysiwyg',
900
                    'alias' => array( 'content' ),
901
                    'options' => array(
902
                        'wysiwyg_allowed_html_tags' => '',
903
                        'display_filter' => 'the_content',
904
                        'pre_save' => 0
905
                    )
906
                ),
907
                'post_excerpt' => array(
908
                    'name' => 'post_excerpt',
909
                    'label' => 'Excerpt',
910
                    'type' => 'paragraph',
911
                    'alias' => array( 'excerpt' ),
912
                    'options' => array(
913
                        'paragraph_allow_html' => 1,
914
                        'paragraph_allowed_html_tags' => '',
915
                        'display_filter' => 'the_excerpt',
916
                        'pre_save' => 0
917
                    )
918
                ),
919
                'post_author' => array(
920
                    'name' => 'post_author',
921
                    'label' => 'Author',
922
                    'type' => 'pick',
923
                    'alias' => array( 'author' ),
924
                    'pick_object' => 'user',
925
                    'options' => array(
926
                        'pick_format_type' => 'single',
927
                        'pick_format_single' => 'autocomplete',
928
                        'default_value' => '{@user.ID}'
929
                    )
930
                ),
931
                'post_date' => array(
932
                    'name' => 'post_date',
933
                    'label' => 'Publish Date',
934
                    'type' => 'datetime',
935
                    'alias' => array( 'created', 'date' )
936
                ),
937
                'post_date_gmt' => array(
938
                    'name' => 'post_date_gmt',
939
                    'label' => 'Publish Date (GMT)',
940
                    'type' => 'datetime',
941
                    'alias' => array(),
942
                    'hidden' => true
943
                ),
944
                'post_status' => array(
945
                    'name' => 'post_status',
946
                    'label' => 'Status',
947
                    'type' => 'pick',
948
                    'pick_object' => 'post-status',
949
                    'default' => $this->do_hook( 'default_status_' . $pod_name, pods_var( 'default_status', pods_var_raw( 'options', $pod ), 'draft', null, true ), $pod ),
950
                    'alias' => array( 'status' )
951
                ),
952
                'comment_status' => array(
953
                    'name' => 'comment_status',
954
                    'label' => 'Comment Status',
955
                    'type' => 'text',
956
                    'default' => get_option( 'default_comment_status', 'open' ),
957
                    'alias' => array(),
958
                    'data' => array(
959
                        'open' => __( 'Open', 'pods' ),
960
                        'closed' => __( 'Closed', 'pods' )
961
                    )
962
                ),
963
                'ping_status' => array(
964
                    'name' => 'ping_status',
965
                    'label' => 'Ping Status',
966
                    'default' => get_option( 'default_ping_status', 'open' ),
967
                    'type' => 'text',
968
                    'alias' => array(),
969
                    'data' => array(
970
                        'open' => __( 'Open', 'pods' ),
971
                        'closed' => __( 'Closed', 'pods' )
972
                    )
973
                ),
974
                'post_password' => array(
975
                    'name' => 'post_password',
976
                    'label' => 'Password',
977
                    'type' => 'text',
978
                    'alias' => array()
979
                ),
980
                'post_name' => array(
981
                    'name' => 'post_name',
982
                    'label' => 'Permalink',
983
                    'type' => 'slug',
984
                    'alias' => array( 'slug', 'permalink' )
985
                ),
986
                'to_ping' => array(
987
                    'name' => 'to_ping',
988
                    'label' => 'To Ping',
989
                    'type' => 'text',
990
                    'alias' => array(),
991
                    'hidden' => true
992
                ),
993
                'pinged' => array(
994
                    'name' => 'pinged',
995
                    'label' => 'Pinged',
996
                    'type' => 'text',
997
                    'alias' => array(),
998
                    'hidden' => true
999
                ),
1000
                'post_modified' => array(
1001
                    'name' => 'post_modified',
1002
                    'label' => 'Last Modified Date',
1003
                    'type' => 'datetime',
1004
                    'alias' => array( 'modified' ),
1005
                    'hidden' => true
1006
                ),
1007
                'post_modified_gmt' => array(
1008
                    'name' => 'post_modified_gmt',
1009
                    'label' => 'Last Modified Date (GMT)',
1010
                    'type' => 'datetime',
1011
                    'alias' => array(),
1012
                    'hidden' => true
1013
                ),
1014
                'post_content_filtered' => array(
1015
                    'name' => 'post_content_filtered',
1016
                    'label' => 'Content (filtered)',
1017
                    'type' => 'paragraph',
1018
                    'alias' => array(),
1019
                    'hidden' => true,
1020
                    'options' => array(
1021
                        'paragraph_allow_html' => 1,
1022
                        'paragraph_oembed' => 1,
1023
                        'paragraph_wptexturize' => 1,
1024
                        'paragraph_convert_chars' => 1,
1025
                        'paragraph_wpautop' => 1,
1026
                        'paragraph_allow_shortcode' => 1,
1027
                        'paragraph_allowed_html_tags' => ''
1028
                    )
1029
                ),
1030
                'post_parent' => array(
1031
                    'name' => 'post_parent',
1032
                    'label' => 'Parent',
1033
                    'type' => 'pick',
1034
                    'pick_object' => 'post_type',
1035
                    'pick_val' => '__current__',
1036
                    'alias' => array( 'parent' ),
1037
                    'data' => array(),
1038
                    'hidden' => true
1039
                ),
1040
                'guid' => array(
1041
                    'name' => 'guid',
1042
                    'label' => 'GUID',
1043
                    'type' => 'text',
1044
                    'alias' => array(),
1045
                    'hidden' => true
1046
                ),
1047
                'menu_order' => array(
1048
                    'name' => 'menu_order',
1049
                    'label' => 'Menu Order',
1050
                    'type' => 'number',
1051
                    'alias' => array(),
1052
	                'options' => array(
1053
                        'number_format' => '9999.99'
1054
	                )
1055
                ),
1056
                'post_type' => array(
1057
                    'name' => 'post_type',
1058
                    'label' => 'Type',
1059
                    'type' => 'text',
1060
                    'alias' => array( 'type' ),
1061
                    'hidden' => true
1062
                ),
1063
                'post_mime_type' => array(
1064
                    'name' => 'post_mime_type',
1065
                    'label' => 'Mime Type',
1066
                    'type' => 'text',
1067
                    'alias' => array(),
1068
                    'hidden' => true
1069
                ),
1070
                'comment_count' => array(
1071
                    'name' => 'comment_count',
1072
                    'label' => 'Comment Count',
1073
                    'type' => 'number',
1074
                    'alias' => array(),
1075
                    'hidden' => true
1076
                )
1077
            );
1078
1079
            if ( !empty( $pod ) ) {
1080
                $taxonomies = get_object_taxonomies( $pod_name, 'objects' );
1081
1082
                foreach ( $taxonomies as $taxonomy ) {
1083
                    $fields[ $taxonomy->name ] = array(
1084
                        'name' => $taxonomy->name,
1085
                        'label' => $taxonomy->labels->name,
1086
                        'type' => 'taxonomy',
1087
						'pick_object' => 'taxonomy',
1088
						'pick_val' => $taxonomy->name,
1089
                        'alias' => array(),
1090
                        'hidden' => true,
1091
						'options' => array(
1092
							'taxonomy_format_type' => 'multi'
1093
						)
1094
                    );
1095
                }
1096
            }
1097
        }
1098
        elseif ( 'user' == $object ) {
1099
            $fields = array(
1100
	            'ID' => array(
1101
		            'name' => 'ID',
1102
		            'label' => 'ID',
1103
		            'type' => 'number',
1104
		            'alias' => array( 'id' ),
1105
	                'options' => array(
1106
                        'number_format' => '9999.99'
1107
	                )
1108
	            ),
1109
                'user_login' => array(
1110
                    'name' => 'user_login',
1111
                    'label' => 'Title',
1112
                    'type' => 'text',
1113
                    'alias' => array( 'login' ),
1114
                    'options' => array(
1115
                        'required' => 1
1116
                    )
1117
                ),
1118
                'user_nicename' => array(
1119
                    'name' => 'user_nicename',
1120
                    'label' => 'Permalink',
1121
                    'type' => 'slug',
1122
                    'alias' => array( 'nicename', 'slug', 'permalink' )
1123
                ),
1124
                'display_name' => array(
1125
                    'name' => 'display_name',
1126
                    'label' => 'Display Name',
1127
                    'type' => 'text',
1128
                    'alias' => array( 'title', 'name' )
1129
                ),
1130
                'user_pass' => array(
1131
                    'name' => 'user_pass',
1132
                    'label' => 'Password',
1133
                    'type' => 'text',
1134
                    'alias' => array( 'password', 'pass' ),
1135
                    'options' => array(
1136
                        'required' => 1,
1137
                        'text_format_type' => 'password'
1138
                    )
1139
                ),
1140
                'user_email' => array(
1141
                    'name' => 'user_email',
1142
                    'label' => 'E-mail',
1143
                    'type' => 'text',
1144
                    'alias' => array( 'email' ),
1145
                    'options' => array(
1146
                        'required' => 1,
1147
                        'text_format_type' => 'email'
1148
                    )
1149
                ),
1150
                'user_url' => array(
1151
                    'name' => 'user_url',
1152
                    'label' => 'URL',
1153
                    'type' => 'text',
1154
                    'alias' => array( 'url', 'website' ),
1155
                    'options' => array(
1156
                        'required' => 0,
1157
                        'text_format_type' => 'website',
1158
                        'text_format_website' => 'normal'
1159
                    )
1160
                ),
1161
                'user_registered' => array(
1162
                    'name' => 'user_registered',
1163
                    'label' => 'Registration Date',
1164
                    'type' => 'date',
1165
                    'alias' => array( 'created', 'date', 'registered' ),
1166
                    'options' => array(
1167
                        'date_format_type' => 'datetime'
1168
                    )
1169
                )
1170
            );
1171
        }
1172
        elseif ( 'comment' == $object ) {
1173
            $fields = array(
1174
	            'comment_ID' => array(
1175
		            'name' => 'comment_ID',
1176
		            'label' => 'ID',
1177
		            'type' => 'number',
1178
		            'alias' => array( 'id', 'ID', 'comment_id' ),
1179
	                'options' => array(
1180
                        'number_format' => '9999.99'
1181
	                )
1182
	            ),
1183
                'comment_content' => array(
1184
                    'name' => 'comment_content',
1185
                    'label' => 'Content',
1186
                    'type' => 'wysiwyg',
1187
                    'alias' => array( 'content' )
1188
                ),
1189
                'comment_approved' => array(
1190
                    'name' => 'comment_approved',
1191
                    'label' => 'Approved',
1192
                    'type' => 'number',
1193
                    'alias' => array( 'approved' ),
1194
	                'options' => array(
1195
                        'number_format' => '9999.99'
1196
	                )
1197
                ),
1198
                'comment_post_ID' => array(
1199
                    'name' => 'comment_post_ID',
1200
                    'label' => 'Post',
1201
                    'type' => 'pick',
1202
                    'alias' => array( 'post', 'post_id' ),
1203
                    'data' => array()
1204
                ),
1205
                'user_id' => array(
1206
                    'name' => 'user_id',
1207
                    'label' => 'Author',
1208
                    'type' => 'pick',
1209
                    'alias' => array( 'author' ),
1210
                    'pick_object' => 'user',
1211
                    'data' => array()
1212
                ),
1213
                'comment_date' => array(
1214
                    'name' => 'comment_date',
1215
                    'label' => 'Date',
1216
                    'type' => 'date',
1217
                    'alias' => array( 'created', 'date' ),
1218
                    'options' => array(
1219
                        'date_format_type' => 'datetime'
1220
                    )
1221
                ),
1222
                'comment_author' => array(
1223
                    'name' => 'comment_author',
1224
                    'label' => 'Author',
1225
                    'type' => 'text',
1226
                    'alias' => array( 'author' )
1227
                ),
1228
                'comment_author_email' => array(
1229
                    'name' => 'comment_author_email',
1230
                    'label' => 'Author E-mail',
1231
                    'type' => 'email',
1232
                    'alias' => array( 'author_email' )
1233
                ),
1234
                'comment_author_url' => array(
1235
                    'name' => 'comment_author_url',
1236
                    'label' => 'Author URL',
1237
                    'type' => 'text',
1238
                    'alias' => array( 'author_url' )
1239
                ),
1240
                'comment_author_IP' => array(
1241
                    'name' => 'comment_author_IP',
1242
                    'label' => 'Author IP',
1243
                    'type' => 'text',
1244
                    'alias' => array( 'author_IP' )
1245
                ),
1246
                'comment_type' => array(
1247
                    'name' => 'comment_type',
1248
                    'label' => 'Type',
1249
                    'type' => 'text',
1250
                    'alias' => array( 'type' ),
1251
                    'hidden' => true
1252
                ),
1253
                'comment_parent' => array(
1254
                    'name' => 'comment_parent',
1255
                    'label' => 'Parent',
1256
                    'type' => 'pick',
1257
                    'pick_object' => 'comment',
1258
                    'pick_val' => '__current__',
1259
                    'alias' => array( 'parent' ),
1260
                    'data' => array(),
1261
                    'hidden' => true
1262
                )
1263
            );
1264
        }
1265
        elseif ( 'taxonomy' == $object ) {
1266
            $fields = array(
1267
	            'term_id' => array(
1268
		            'name' => 'term_id',
1269
		            'label' => 'ID',
1270
		            'type' => 'number',
1271
		            'alias' => array( 'id', 'ID' ),
1272
	                'options' => array(
1273
                        'number_format' => '9999.99'
1274
	                )
1275
	            ),
1276
                'name' => array(
1277
                    'name' => 'name',
1278
                    'label' => 'Title',
1279
                    'type' => 'text',
1280
                    'alias' => array( 'title' )
1281
                ),
1282
                'slug' => array(
1283
                    'name' => 'slug',
1284
                    'label' => 'Permalink',
1285
                    'type' => 'slug',
1286
                    'alias' => array( 'permalink' )
1287
                ),
1288
                'description' => array(
1289
                    'name' => 'description',
1290
                    'label' => 'Description',
1291
                    'type' => 'wysiwyg',
1292
                    'alias' => array( 'content' )
1293
                ),
1294
                'taxonomy' => array(
1295
                    'name' => 'taxonomy',
1296
                    'label' => 'Taxonomy',
1297
                    'type' => 'pick',
1298
                    'alias' => array()
1299
                ),
1300
                'parent' => array(
1301
                    'name' => 'parent',
1302
                    'label' => 'Parent',
1303
                    'type' => 'pick',
1304
                    'pick_object' => 'taxonomy',
1305
                    'pick_val' => '__current__',
1306
                    'alias' => array( 'parent' ),
1307
                    'data' => array(),
1308
                    'hidden' => true
1309
                ),
1310
                'term_taxonomy_id' => array(
1311
                    'name' => 'term_taxonomy_id',
1312
                    'label' => 'Term Taxonomy ID',
1313
                    'type' => 'number',
1314
                    'alias' => array(),
1315
                    'hidden' => true,
1316
	                'options' => array(
1317
                        'number_format' => '9999.99'
1318
	                )
1319
                ),
1320
                'term_group' => array(
1321
                    'name' => 'term_group',
1322
                    'label' => 'Term Group',
1323
                    'type' => 'number',
1324
                    'alias' => array( 'group' ),
1325
                    'hidden' => true,
1326
	                'options' => array(
1327
                        'number_format' => '9999.99'
1328
	                )
1329
                ),
1330
                'count' => array(
1331
                    'name' => 'count',
1332
                    'label' => 'Count',
1333
                    'type' => 'number',
1334
                    'alias' => array(),
1335
                    'hidden' => true,
1336
	                'options' => array(
1337
                        'number_format' => '9999.99'
1338
	                )
1339
                )
1340
            );
1341
        }
1342
1343
        $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
1344
1345
        foreach ( $fields as $field => $options ) {
1346
            if ( !isset( $options[ 'alias' ] ) )
1347
                $options[ 'alias' ] = array();
1348
            else
1349
                $options[ 'alias' ] = (array) $options[ 'alias' ];
1350
1351
            if ( !isset( $options[ 'name' ] ) )
1352
                $options[ 'name' ] = $field;
1353
1354
            $fields[ $field ] = $options;
1355
        }
1356
1357
        $fields = PodsForm::fields_setup( $fields );
1358
1359 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
1360
            pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields );
1361
1362
        return $fields;
1363
    }
1364
1365
    /**
1366
     *
1367
     * @see PodsAPI::save_pod
1368
     *
1369
     * Add a Pod via the Wizard
1370
     *
1371
     * $params['create_extend'] string Create or Extend a Content Type
1372
     * $params['create_pod_type'] string Pod Type (for Creating)
1373
     * $params['create_name'] string Pod Name (for Creating)
1374
     * $params['create_label_plural'] string Plural Label (for Creating)
1375
     * $params['create_label_singular'] string Singular Label (for Creating)
1376
     * $params['create_storage'] string Storage Type (for Creating Post Types)
1377
     * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies)
1378
     * $params['extend_pod_type'] string Pod Type (for Extending)
1379
     * $params['extend_post_type'] string Post Type (for Extending Post Types)
1380
     * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies)
1381
     * $params['extend_storage'] string Storage Type (for Extending Post Types / Users / Comments)
1382
     *
1383
     * @param array $params An associative array of parameters
1384
     *
1385
     * @return bool|int Pod ID
1386
     * @since 2.0
1387
     */
1388
    public function add_pod ( $params ) {
1389
        $defaults = array(
1390
            'create_extend' => 'create',
1391
            'create_pod_type' => 'post_type',
1392
1393
            'create_name' => '',
1394
            'create_label_singular' => '',
1395
            'create_label_plural' => '',
1396
            'create_storage' => 'meta',
1397
            'create_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' ),
1398
1399
            'create_setting_name' => '',
1400
            'create_label_title' => '',
1401
            'create_label_menu' => '',
1402
            'create_menu_location' => 'settings',
1403
1404
            'extend_pod_type' => 'post_type',
1405
            'extend_post_type' => 'post',
1406
            'extend_taxonomy' => 'category',
1407
            'extend_table' => '',
1408
            'extend_storage' => 'meta',
1409
            'extend_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'table' ),
1410
        );
1411
1412
        $params = (object) array_merge( $defaults, (array) $params );
1413
1414
        if ( empty( $params->create_extend ) || !in_array( $params->create_extend, array( 'create', 'extend' ) ) )
1415
            return pods_error( __( 'Please choose whether to Create or Extend a Content Type', 'pods' ), $this );
1416
1417
        $pod_params = array(
1418
            'name' => '',
1419
            'label' => '',
1420
            'type' => '',
1421
            'storage' => 'table',
1422
            'object' => '',
1423
            'options' => array()
1424
        );
1425
1426
        if ( 'create' == $params->create_extend ) {
1427
            $label = ucwords( str_replace( '_', ' ', $params->create_name ) );
1428
1429
            if ( !empty( $params->create_label_singular ) )
1430
                $label = $params->create_label_singular;
1431
1432
            $pod_params[ 'name' ] = $params->create_name;
1433
            $pod_params[ 'label' ] = ( !empty( $params->create_label_plural ) ? $params->create_label_plural : $label );
1434
            $pod_params[ 'type' ] = $params->create_pod_type;
1435
            $pod_params[ 'options' ] = array(
1436
                'label_singular' => ( !empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params[ 'label' ] ),
1437
                'public' => 1,
1438
                'show_ui' => 1
1439
            );
1440
1441
            // Auto-generate name if not provided
1442
            if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'options' ][ 'label_singular' ] ) )
1443
                $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'options' ][ 'label_singular' ] );
1444
1445
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1446
                if ( empty(  $pod_params[ 'name' ] ) )
1447
                    return pods_error( 'Please enter a Name for this Pod', $this );
1448
1449
                $pod_params[ 'storage' ] = $params->create_storage;
1450
1451
                if ( pods_tableless() )
1452
                    $pod_params[ 'storage' ] = 'meta';
1453
            }
1454 View Code Duplication
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1455
                if ( empty(  $pod_params[ 'name' ] ) )
1456
                    return pods_error( 'Please enter a Name for this Pod', $this );
1457
1458
                $pod_params[ 'storage' ] = $params->create_storage_taxonomy;
1459
1460
                if ( pods_tableless() )
1461
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1462
            }
1463 View Code Duplication
            elseif ( 'pod' == $pod_params[ 'type' ] ) {
1464
                if ( empty(  $pod_params[ 'name' ] ) )
1465
                    return pods_error( 'Please enter a Name for this Pod', $this );
1466
1467
                if ( pods_tableless() ) {
1468
                    $pod_params[ 'type' ] = 'post_type';
1469
                    $pod_params[ 'storage' ] = 'meta';
1470
                }
1471
            }
1472
            elseif ( 'settings' == $pod_params[ 'type' ] ) {
1473
                $pod_params[ 'name' ] = $params->create_setting_name;
1474
                $pod_params[ 'label' ] = ( !empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) );
1475
                $pod_params[ 'options' ] = array(
1476
                    'menu_name' => ( !empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params[ 'label' ] ),
1477
                    'menu_location' => $params->create_menu_location
1478
                );
1479
                $pod_params[ 'storage' ] = 'none';
1480
1481
                // Auto-generate name if not provided
1482
                if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'label' ] ) )
1483
                    $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'label' ] );
1484
1485
                if ( empty( $pod_params[ 'name' ] ) )
1486
                    return pods_error( 'Please enter a Name for this Pod', $this );
1487
            }
1488
        }
1489
        elseif ( 'extend' == $params->create_extend ) {
1490
            $pod_params[ 'type' ] = $params->extend_pod_type;
1491
1492
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1493
                $pod_params[ 'storage' ] = $params->extend_storage;
1494
1495
                if ( pods_tableless() )
1496
                    $pod_params[ 'storage' ] = 'meta';
1497
1498
                $pod_params[ 'name' ] = $params->extend_post_type;
1499
            }
1500
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1501
                $pod_params[ 'storage' ] = $params->extend_storage_taxonomy;
1502
1503
                if ( pods_tableless() )
1504
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1505
1506
                $pod_params[ 'name' ] = $params->extend_taxonomy;
1507
            }
1508
            elseif ( 'table' == $pod_params[ 'type' ] ) {
1509
                $pod_params[ 'storage' ] = 'table';
1510
                $pod_params[ 'name' ] = $params->extend_table;
1511
            }
1512
            else {
1513
                $pod_params[ 'storage' ] = $params->extend_storage;
1514
1515
                if ( pods_tableless() )
1516
                    $pod_params[ 'storage' ] = 'meta';
1517
1518
                $pod_params[ 'name' ] = $params->extend_pod_type;
1519
            }
1520
1521
            $pod_params[ 'label' ] = ucwords( str_replace( '_', ' ', $pod_params[ 'name' ] ) );
1522
            $pod_params[ 'object' ] = $pod_params[ 'name' ];
1523
        }
1524
1525
        if ( empty( $pod_params[ 'object' ] ) ) {
1526
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1527
                $check = get_post_type_object( $pod_params[ 'name' ] );
1528
1529 View Code Duplication
                if ( !empty( $check ) )
1530
                    return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1531
1532
                $pod_params[ 'options' ][ 'supports_title' ] = 1;
1533
                $pod_params[ 'options' ][ 'supports_editor' ] = 1;
1534
            }
1535
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1536
                $check = get_taxonomy( $pod_params[ 'name' ] );
1537
1538 View Code Duplication
                if ( !empty( $check ) )
1539
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1540
            }
1541
        }
1542
1543
        if ( !empty( $pod_params ) )
1544
            return $this->save_pod( $pod_params );
1545
1546
        return false;
1547
    }
1548
1549
    /**
1550
     * Add or edit a Pod
1551
     *
1552
     * $params['id'] int The Pod ID
1553
     * $params['name'] string The Pod name
1554
     * $params['label'] string The Pod label
1555
     * $params['type'] string The Pod type
1556
     * $params['object'] string The object being extended (if any)
1557
     * $params['storage'] string The Pod storage
1558
     * $params['options'] array Options
1559
     *
1560
     * @param array $params An associative array of parameters
1561
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
1562
     * @param bool|int $db (optional) Whether to save into the DB or just return Pod array.
1563
     *
1564
     * @return int Pod ID
1565
     * @since 1.7.9
1566
     */
1567
    public function save_pod ( $params, $sanitized = false, $db = true ) {
1568
        $tableless_field_types = PodsForm::tableless_field_types();
1569
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
1570
1571
        $load_params = (object) $params;
1572
1573
        if ( isset( $load_params->id ) && isset( $load_params->name ) )
1574
            unset( $load_params->name );
1575
1576
        if ( isset( $load_params->old_name ) )
1577
            $load_params->name = $load_params->old_name;
1578
1579
        $load_params->table_info = true;
1580
1581
        $pod = $this->load_pod( $load_params, false );
1582
1583
        $params = (object) $params;
1584
1585
        if ( false === $sanitized )
1586
            $params = pods_sanitize( $params );
1587
1588
        $old_id = $old_name = $old_storage = null;
1589
1590
        $old_fields = $old_options = array();
1591
1592
		if ( isset( $params->name ) && ! isset( $params->object ) ) {
1593
			$params->name = pods_clean_name( $params->name );
1594
		}
1595
1596
        if ( !empty( $pod ) ) {
1597
            if ( isset( $params->id ) && 0 < $params->id )
1598
                $old_id = $params->id;
1599
1600
            $params->id = $pod[ 'id' ];
1601
1602
            $old_name = $pod[ 'name' ];
1603
            $old_storage = $pod[ 'storage' ];
1604
            $old_fields = $pod[ 'fields' ];
1605
            $old_options = $pod[ 'options' ];
1606
1607
            if ( !isset( $params->name ) && empty( $params->name ) )
1608
                $params->name = $pod[ 'name' ];
1609
1610
            if ( $old_name != $params->name && false !== $this->pod_exists( array( 'name' => $params->name ) ) )
1611
                return pods_error( sprintf( __( 'Pod %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1612
1613
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'user', 'comment', 'media' ) ) && in_array( $pod[ 'object' ], array( 'user', 'comment', 'media' ) ) )
1614
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1615
1616
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && !empty( $pod[ 'object' ] ) && $pod[ 'object' ] == $old_name )
1617
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1618
1619
            if ( $old_id != $params->id ) {
1620
                if ( $params->type == $pod[ 'type' ] && isset( $params->object ) && $params->object == $pod[ 'object' ] )
1621
                    return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this );
1622
                else
1623
                    return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this );
1624
            }
1625
        }
1626
		elseif ( in_array( $params->name, array( 'order','orderby','post_type' ) ) && 'post_type' == pods_var( 'type', $params ) ) {
1627
			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 );
1628
		}
1629
        else {
1630
            $pod = array(
1631
                'id' => 0,
1632
                'name' => $params->name,
1633
                'label' => $params->name,
1634
                'description' => '',
1635
                'type' => 'pod',
1636
                'storage' => 'table',
1637
                'object' => '',
1638
                'alias' => '',
1639
                'options' => array(),
1640
                'fields' => array()
1641
            );
1642
        }
1643
1644
        // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite)
1645
        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1646
            $pod[ 'fields' ] = array();
1647
            $pod[ 'options' ] = array();
1648
        }
1649
1650
        // Setup options
1651
        $options = get_object_vars( $params );
1652
1653
        if ( isset( $options[ 'method' ] ) )
1654
            unset( $options[ 'method' ] );
1655
1656
        $options_ignore = array(
1657
            'object_type',
1658
            'object_name',
1659
            'table',
1660
            'meta_table',
1661
            'pod_table',
1662
            'field_id',
1663
            'field_index',
1664
            'field_slug',
1665
            'field_type',
1666
            'field_parent',
1667
            'field_parent_select',
1668
            'meta_field_id',
1669
            'meta_field_index',
1670
            'meta_field_value',
1671
            'pod_field_id',
1672
            'pod_field_index',
1673
            'object_fields',
1674
            'join',
1675
            'where',
1676
            'where_default',
1677
            'orderby',
1678
            'pod',
1679
            'recurse',
1680
            'table_info',
1681
            'attributes',
1682
            'group',
1683
            'grouped',
1684
            'developer_mode',
1685
            'dependency',
1686
            'depends-on',
1687
            'excludes-on'
1688
        );
1689
1690
        foreach ( $options_ignore as $ignore ) {
1691
            if ( isset( $options[ $ignore ] ) )
1692
                unset( $options[ $ignore ] );
1693
        }
1694
1695
        $exclude = array(
1696
            'id',
1697
            'name',
1698
            'label',
1699
            'description',
1700
            'type',
1701
            'storage',
1702
            'object',
1703
            'alias',
1704
            'options',
1705
            'fields'
1706
        );
1707
1708 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
1709
            $aliases = array( $exclude_field );
1710
1711
            if ( is_array( $exclude_field ) ) {
1712
                $aliases = array_merge( array( $k ), $exclude_field );
1713
                $exclude_field = $k;
1714
            }
1715
1716
            foreach ( $aliases as $alias ) {
1717
                if ( isset( $options[ $alias ] ) ) {
1718
                    $pod[ $exclude_field ] = pods_trim( $options[ $alias ] );
1719
1720
                    unset( $options[ $alias ] );
1721
                }
1722
            }
1723
        }
1724
1725
        if ( pods_tableless() && !in_array( $pod[ 'type' ], array( 'settings', 'table' ) ) ) {
1726
            if ( 'pod' == $pod[ 'type' ] )
1727
                $pod[ 'type' ] = 'post_type';
1728
1729 View Code Duplication
            if ( 'table' == $pod[ 'storage' ] ) {
1730
                if ( 'taxonomy' == $pod[ 'type' ] && ! function_exists( 'get_term_meta' ) )
1731
                    $pod[ 'storage' ] = 'none';
1732
                else
1733
                    $pod[ 'storage' ] = 'meta';
1734
            }
1735
        }
1736
1737
        $pod[ 'options' ][ 'type' ] = $pod[ 'type' ];
1738
        $pod[ 'options' ][ 'storage' ] = $pod[ 'storage' ];
1739
        $pod[ 'options' ][ 'object' ] = $pod[ 'object' ];
1740
        $pod[ 'options' ][ 'alias' ] = $pod[ 'alias' ];
1741
1742
        $pod[ 'options' ] = array_merge( $pod[ 'options' ], $options );
1743
1744
		/**
1745
		 * @var WP_Query
1746
		 */
1747
		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...
1748
1749
		$reserved_query_vars = array(
1750
			'post_type',
1751
			'taxonomy',
1752
			'output'
1753
		);
1754
1755
		if ( is_object( $wp_query ) ) {
1756
			$reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
1757
		}
1758
1759 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var_string' ] ) ) {
1760
			if ( in_array( $pod[ 'options' ][ 'query_var_string' ], $reserved_query_vars ) ) {
1761
				$pod[ 'options' ][ 'query_var_string' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var_string' ];
1762
			}
1763
		}
1764
1765 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var' ] ) ) {
1766
			if ( in_array( $pod[ 'options' ][ 'query_var' ], $reserved_query_vars ) ) {
1767
				$pod[ 'options' ][ 'query_var' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var' ];
1768
			}
1769
		}
1770
1771
        if ( strlen( $pod[ 'label' ] ) < 1 )
1772
            $pod[ 'label' ] = $pod[ 'name' ];
1773
1774
        if ( 'post_type' == $pod[ 'type' ] ) {
1775
            // Max length for post types are 20 characters
1776
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 20 );
1777
        }
1778
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1779
            // Max length for taxonomies are 32 characters
1780
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 32 );
1781
        }
1782
1783
        $params->id = $pod[ 'id' ];
1784
        $params->name = $pod[ 'name' ];
1785
1786
        if ( null !== $old_name && $old_name != $params->name && empty( $pod[ 'object' ] ) ) {
1787
            if ( 'post_type' == $pod[ 'type' ] ) {
1788
                $check = get_post_type_object( $params->name );
1789
1790 View Code Duplication
                if ( !empty( $check ) )
1791
                    return pods_error( sprintf( __( 'Post Type %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1792
            }
1793
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1794
                $check = get_taxonomy( $params->name );
1795
1796 View Code Duplication
                if ( !empty( $check ) )
1797
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1798
            }
1799
        }
1800
1801
        $field_table_operation = true;
1802
1803
        // Add new pod
1804
        if ( empty( $params->id ) ) {
1805
            if ( strlen( $params->name ) < 1 )
1806
                return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this );
1807
1808
            $post_data = array(
1809
                'post_name' => $pod[ 'name' ],
1810
                'post_title' => $pod[ 'label' ],
1811
                'post_content' => $pod[ 'description' ],
1812
                'post_type' => '_pods_pod',
1813
                'post_status' => 'publish'
1814
            );
1815
1816
            if ( 'pod' == $pod[ 'type' ] && ( !is_array( $pod[ 'fields' ] ) || empty( $pod[ 'fields' ] ) ) ) {
1817
                $pod[ 'fields' ] = array();
1818
1819
                $pod[ 'fields' ][ 'name' ] = array(
1820
                    'name' => 'name',
1821
                    'label' => 'Name',
1822
                    'type' => 'text',
1823
                    'options' => array(
1824
                        'required' => '1'
1825
                    )
1826
                );
1827
1828
                $pod[ 'fields' ][ 'created' ] = array(
1829
                    'name' => 'created',
1830
                    'label' => 'Date Created',
1831
                    'type' => 'datetime',
1832
                    'options' => array(
1833
                        'datetime_format' => 'ymd_slash',
1834
                        'datetime_time_type' => '12',
1835
                        'datetime_time_format' => 'h_mm_ss_A'
1836
                    )
1837
                );
1838
1839
                $pod[ 'fields' ][ 'modified' ] = array(
1840
                    'name' => 'modified',
1841
                    'label' => 'Date Modified',
1842
                    'type' => 'datetime',
1843
                    'options' => array(
1844
                        'datetime_format' => 'ymd_slash',
1845
                        'datetime_time_type' => '12',
1846
                        'datetime_time_format' => 'h_mm_ss_A'
1847
                    )
1848
                );
1849
1850
                $pod[ 'fields' ][ 'author' ] = array(
1851
                    'name' => 'author',
1852
                    'label' => 'Author',
1853
                    'type' => 'pick',
1854
                    'pick_object' => 'user',
1855
                    'options' => array(
1856
                        'pick_format_type' => 'single',
1857
                        'pick_format_single' => 'autocomplete',
1858
                        'default_value' => '{@user.ID}'
1859
                    )
1860
                );
1861
1862
                $pod[ 'fields' ][ 'permalink' ] = array(
1863
                    'name' => 'permalink',
1864
                    'label' => 'Permalink',
1865
                    'type' => 'slug',
1866
                    'description' => 'Leave blank to auto-generate from Name'
1867
                );
1868
1869
                if ( !isset( $pod[ 'options' ][ 'pod_index' ] ) )
1870
                    $pod[ 'options' ][ 'pod_index' ] = 'name';
1871
            }
1872
1873
            $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db );
1874
1875
            $field_table_operation = false;
1876
        }
1877
        else {
1878
            $post_data = array(
1879
                'ID' => $pod[ 'id' ],
1880
                'post_name' => $pod[ 'name' ],
1881
                'post_title' => $pod[ 'label' ],
1882
                'post_content' => $pod[ 'description' ],
1883
                'post_status' => 'publish'
1884
            );
1885
        }
1886
1887 View Code Duplication
        if ( true === $db ) {
1888
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
1889
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
1890
1891
            $conflicted = false;
1892
1893
            // Headway compatibility fix
1894
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
1895
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1896
1897
                $conflicted = true;
1898
            }
1899
1900
            $params->id = $this->save_wp_object( 'post', $post_data, $pod[ 'options' ], true, true );
1901
1902
            if ( $conflicted )
1903
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1904
1905
            if ( false === $params->id )
1906
                return pods_error( __( 'Cannot save Pod', 'pods' ), $this );
1907
        }
1908
        elseif ( empty( $params->id ) )
1909
            $params->id = (int) $db;
1910
1911
        $pod[ 'id' ] = $params->id;
1912
1913
        // Setup / update tables
1914
        if ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $old_storage != $pod[ 'storage' ] && $db ) {
1915
            $definitions = array( "`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY" );
1916
1917
            $defined_fields = array();
1918
1919
            foreach ( $pod[ 'fields' ] as $field ) {
1920
                if ( !is_array( $field ) || !isset( $field[ 'name' ] ) || in_array( $field[ 'name' ], $defined_fields ) )
1921
                    continue;
1922
1923
                $defined_fields[] = $field[ 'name' ];
1924
1925
                if ( !in_array( $field[ 'type' ], $tableless_field_types ) || ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) ) {
1926
                    $definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, pods_var_raw( 'options', $field, array() ) ) );
1927
1928
                    if ( 0 < strlen( $definition ) )
1929
                        $definitions[] = "`{$field['name']}` " . $definition;
1930
                }
1931
            }
1932
1933
            pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`" );
1934
1935
            $result = pods_query( "CREATE TABLE `@wp_pods_{$params->name}` (" . implode( ', ', $definitions ) . ") DEFAULT CHARSET utf8", $this );
1936
1937
            if ( empty( $result ) )
1938
                return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this );
1939
1940
        }
1941
        elseif ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $pod[ 'storage' ] == $old_storage && null !== $old_name && $old_name != $params->name && $db ) {
1942
            $result = pods_query( "ALTER TABLE `@wp_pods_{$old_name}` RENAME `@wp_pods_{$params->name}`", $this );
1943
1944
            if ( empty( $result ) )
1945
                return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this );
1946
        }
1947
1948
        /**
1949
         * @var $wpdb wpdb
1950
         */
1951
        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...
1952
1953
		if ( null !== $old_name && $old_name != $params->name && $db ) {
1954
        	// Rename items in the DB pointed at the old WP Object names
1955
			if ( 'post_type' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1956
				$this->rename_wp_object_type( 'post', $old_name, $params->name );
1957
			}
1958 View Code Duplication
			elseif ( 'taxonomy' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1959
				$this->rename_wp_object_type( 'taxonomy', $old_name, $params->name );
1960
			}
1961 View Code Duplication
			elseif ( 'comment' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1962
				$this->rename_wp_object_type( 'comment', $old_name, $params->name );
1963
			}
1964
			elseif ( 'settings' == $pod[ 'type' ] ) {
1965
				$this->rename_wp_object_type( 'settings', $old_name, $params->name );
1966
			}
1967
1968
        	// Sync any related fields if the name has changed
1969
            $fields = pods_query( "
1970
                SELECT `p`.`ID`
1971
                FROM `{$wpdb->posts}` AS `p`
1972
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1973
                LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID`
1974
                WHERE
1975
                    `p`.`post_type` = '_pods_field'
1976
                    AND `pm`.`meta_key` = 'pick_object'
1977
                    AND (
1978
                    	`pm`.`meta_value` = 'pod'
1979
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "'
1980
					)
1981
                    AND `pm2`.`meta_key` = 'pick_val'
1982
                    AND `pm2`.`meta_value` = '{$old_name}'
1983
            " );
1984
1985 View Code Duplication
            if ( !empty( $fields ) ) {
1986
                foreach ( $fields as $field ) {
1987
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
1988
                    update_post_meta( $field->ID, 'pick_val', $params->name );
1989
                }
1990
            }
1991
1992
            $fields = pods_query( "
1993
                SELECT `p`.`ID`
1994
                FROM `{$wpdb->posts}` AS `p`
1995
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1996
                WHERE
1997
                    `p`.`post_type` = '_pods_field'
1998
                    AND `pm`.`meta_key` = 'pick_object'
1999
                    AND (
2000
                    	`pm`.`meta_value` = 'pod-{$old_name}'
2001
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "-{$old_name}'
2002
					)
2003
            " );
2004
2005 View Code Duplication
            if ( !empty( $fields ) ) {
2006
                foreach ( $fields as $field ) {
2007
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
2008
                    update_post_meta( $field->ID, 'pick_val', $params->name );
2009
                }
2010
            }
2011
        }
2012
2013
        // Sync built-in options for post types and taxonomies
2014
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) && $db ) {
2015
            // Build list of 'built_in' for later
2016
            $built_in = array();
2017
2018
            foreach ( $pod[ 'options' ] as $key => $val ) {
2019
                if ( false === strpos( $key, 'built_in_' ) )
2020
                    continue;
2021
                elseif ( false !== strpos( $key, 'built_in_post_types_' ) )
2022
                    $built_in_type = 'post_type';
2023
                elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) )
2024
                    $built_in_type = 'taxonomy';
2025
                else
2026
                    continue;
2027
2028
                if ( $built_in_type == $pod[ 'type' ] )
2029
                    continue;
2030
2031
                if ( !isset( $built_in[ $built_in_type ] ) )
2032
                    $built_in[ $built_in_type ] = array();
2033
2034
                $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key );
2035
2036
                $built_in[ $built_in_type ][ $built_in_object ] = (int) $val;
2037
            }
2038
2039
            $lookup_option = $lookup_built_in = false;
2040
2041
            $lookup_name = $pod[ 'name' ];
2042
2043
            if ( 'post_type' == $pod[ 'type' ] ) {
2044
                $lookup_option = 'built_in_post_types_' . $lookup_name;
2045
                $lookup_built_in = 'taxonomy';
2046
            }
2047
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
2048
                $lookup_option = 'built_in_taxonomies_' . $lookup_name;
2049
                $lookup_built_in = 'post_type';
2050
            }
2051
2052
            if ( !empty( $lookup_option ) && !empty( $lookup_built_in ) && isset( $built_in[ $lookup_built_in ] ) ) {
2053
                foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) {
2054
                    $search_val = 1;
2055
2056
                    if ( 1 == $val )
2057
                        $search_val = 0;
2058
2059
                    $query = "SELECT p.ID FROM {$wpdb->posts} AS p
2060
                                LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}'
2061
                                LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}'
2062
                                LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = ''
2063
                                WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}'
2064
                                    AND pm2.meta_id IS NOT NULL
2065
                                    AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )";
2066
2067
                    $results = pods_query( $query );
2068
2069
                    if ( !empty( $results ) ) {
2070
                        foreach ( $results as $the_pod ) {
2071
                            delete_post_meta( $the_pod->ID, $lookup_option );
2072
2073
                            add_post_meta( $the_pod->ID, $lookup_option, $val );
2074
                        }
2075
                    }
2076
                }
2077
            }
2078
        }
2079
2080
        $saved = array();
2081
        $errors = array();
2082
2083
        $field_index_change = false;
2084
        $field_index_id = 0;
2085
2086
        $id_required = false;
2087
2088
        $field_index = pods_var( 'pod_index', $pod[ 'options' ], 'id', null, true );
2089
2090
        if ( 'pod' == $pod[ 'type' ] && !empty( $pod[ 'fields' ] ) && isset( $pod[ 'fields' ][ $field_index ] ) )
2091
            $field_index_id = $pod[ 'fields' ][ $field_index ];
2092
2093
        if ( isset( $params->fields ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
2094
            $fields = array();
2095
2096
            if ( isset( $params->fields ) ) {
2097
                $params->fields = (array) $params->fields;
2098
2099
                $weight = 0;
2100
2101
                foreach ( $params->fields as $field ) {
2102
                    if ( !is_array( $field ) || !isset( $field[ 'name' ] ) )
2103
                        continue;
2104
2105
                    if ( !isset( $field[ 'weight' ] ) ) {
2106
                        $field[ 'weight' ] = $weight;
2107
2108
                        $weight++;
2109
                    }
2110
2111
                    $fields[ $field[ 'name' ] ] = $field;
2112
                }
2113
            }
2114
2115
            $weight = 0;
2116
2117
            $saved_field_ids = array();
2118
2119
            foreach ( $pod[ 'fields' ] as $k => $field ) {
2120
                if ( !empty( $old_id ) && ( !is_array( $field ) || !isset( $field[ 'name' ] ) || !isset( $fields[ $field[ 'name' ] ] ) ) ) {
2121
                    // Iterative change handling for setup-edit.php
2122
                    if ( !is_array( $field ) && isset( $old_fields[ $k ] ) )
2123
                        $saved[ $old_fields[ $k ][ 'name' ] ] = true;
2124
2125
                    continue;
2126
                }
2127
2128
                if ( !empty( $old_id ) )
2129
                    $field = array_merge( $field, $fields[ $field[ 'name' ] ] );
2130
2131
                $field[ 'pod' ] = $pod;
2132
2133
                if ( !isset( $field[ 'weight' ] ) ) {
2134
                    $field[ 'weight' ] = $weight;
2135
2136
                    $weight++;
2137
                }
2138
2139
                if ( 0 < $field_index_id && pods_var( 'id', $field ) == $field_index_id )
2140
                    $field_index_change = $field[ 'name' ];
2141
2142
                if ( 0 < pods_var( 'id', $field ) )
2143
                    $id_required = true;
2144
2145
                if ( $id_required )
2146
                    $field[ 'id_required' ] = true;
2147
2148
                $field_data = $field;
2149
2150
                $field = $this->save_field( $field_data, $field_table_operation, true, $db );
2151
2152
                if ( true !== $db ) {
2153
                    $pod[ 'fields' ][ $k ] = $field;
2154
                    $saved_field_ids[] = $field[ 'id' ];
2155
                }
2156
                else {
2157
                    if ( !empty( $field ) && 0 < $field ) {
2158
                        $saved[ $field_data[ 'name' ] ] = true;
2159
                        $saved_field_ids[] = $field;
2160
                    }
2161
                    else
2162
                        $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data[ 'name' ] );
2163
                }
2164
            }
2165
2166
            if ( true === $db ) {
2167
                foreach ( $old_fields as $field ) {
2168
                    if ( isset( $pod[ 'fields' ][ $field[ 'name' ] ] ) || isset( $saved[ $field[ 'name' ] ] ) || in_array( $field[ 'id' ], $saved_field_ids ) )
2169
                        continue;
2170
2171
                    if ( $field[ 'id' ] == $field_index_id )
2172
                        $field_index_change = 'id';
2173
                    elseif ( $field[ 'name' ] == $field_index )
2174
                        $field_index_change = 'id';
2175
2176
                    $this->delete_field( array(
2177
                        'id' => (int) $field[ 'id' ],
2178
                        'name' => $field[ 'name' ],
2179
                        'pod' => $pod
2180
                    ), $field_table_operation );
2181
                }
2182
            }
2183
2184
            // Update field index if the name has changed or the field has been removed
2185
            if ( false !== $field_index_change && true === $db )
2186
                update_post_meta( $pod[ 'id' ], 'pod_index', $field_index_change );
2187
        }
2188
2189
        if ( !empty( $errors ) )
2190
            return pods_error( $errors, $this );
2191
2192
        $this->cache_flush_pods( $pod );
2193
        
2194
		$refresh_pod = $this->load_pod( array( 'name' => $pod['name'] ), false );
2195
        
2196
		if ( $refresh_pod ) {
2197
			$pod = $refresh_pod;
2198
		}
2199
2200
		if ( 'post_type' == $pod['type'] ) {
2201
			PodsMeta::$post_types[ $pod['id'] ] = $pod;
2202
		} elseif ( 'taxonomy' == $pod['type'] ) {
2203
			PodsMeta::$taxonomies[ $pod['id'] ] = $pod;
2204
		} elseif ( 'media' == $pod['type'] ) {
2205
			PodsMeta::$media[ $pod['id'] ] = $pod;
2206
		} elseif ( 'user' == $pod['type'] ) {
2207
			PodsMeta::$user[ $pod['id'] ] = $pod;
2208
		} elseif ( 'comment' == $pod['type'] ) {
2209
			PodsMeta::$comment[ $pod['id'] ] = $pod;
2210
		}
2211
2212
        // Register Post Types / Taxonomies post-registration from PodsInit
2213
        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...
2214
            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...
2215
2216
            $pods_init->setup_content_types( true );
2217
        }
2218
2219
        if ( true === $db )
2220
            return $pod[ 'id' ];
2221
        else
2222
            return $pod;
2223
    }
2224
2225
    /**
2226
     * Add or edit a field within a Pod
2227
     *
2228
     * $params['id'] int Field ID (id OR pod_id+pod+name required)
2229
     * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
2230
     * $params['pod'] string Pod name (id OR pod_id+pod+name required)
2231
     * $params['name'] string Field name (id OR pod_id+pod+name required)
2232
     * $params['label'] string (optional) Field label
2233
     * $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)
2234
     * $params['pick_object'] string (optional) Related Object (for relationships)
2235
     * $params['pick_val'] string (optional) Related Object name (for relationships)
2236
     * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
2237
     * $params['weight'] int (optional) Order in which the field appears
2238
     * $params['options'] array (optional) Options
2239
     *
2240
     * @param array $params An associative array of parameters
2241
     * @param bool $table_operation (optional) Whether or not to handle table operations
2242
     * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2243
     * @param bool|int $db (optional) Whether to save into the DB or just return field array.
2244
     *
2245
     * @return int|array The field ID or field array (if !$db)
2246
     * @since 1.7.9
2247
     */
2248
    public function save_field ( $params, $table_operation = true, $sanitized = false, $db = true ) {
2249
        /**
2250
         * @var $wpdb wpdb
2251
         */
2252
        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...
2253
2254
        if ( true !== $db )
2255
            $table_operation = false;
2256
2257
        $tableless_field_types = PodsForm::tableless_field_types();
2258
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
2259
2260
        $params = (object) $params;
2261
2262
        if ( false === $sanitized )
2263
            $params = pods_sanitize( $params );
2264
2265
        if ( isset( $params->pod_id ) )
2266
            $params->pod_id = pods_absint( $params->pod_id );
2267
2268
        if ( true !== $db )
2269
            $params->pod_id = (int) $db;
2270
2271
        $pod = null;
2272
        $save_pod = false;
2273
        $id_required = false;
2274
2275
        if ( isset( $params->id_required ) ) {
2276
            unset( $params->id_required );
2277
2278
            $id_required = true;
2279
        }
2280
2281 View Code Duplication
        if ( ( !isset( $params->pod ) || empty( $params->pod ) ) && ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) )
2282
            return pods_error( __( 'Pod ID or name is required', 'pods' ), $this );
2283
2284
        if ( isset( $params->pod ) && is_array( $params->pod ) ) {
2285
            $pod = $params->pod;
2286
2287
            $save_pod = true;
2288
        }
2289 View Code Duplication
        elseif ( ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) )
2290
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
2291 View Code Duplication
        elseif ( !isset( $params->pod ) && ( true === $db || 0 < $db ) )
2292
            $pod = $this->load_pod( array( 'id' => $params->pod_id, 'table_info' => true ) );
2293 View Code Duplication
        elseif ( true === $db || 0 < $db )
2294
            $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
2295
2296
        if ( empty( $pod ) && true === $db )
2297
            return pods_error( __( 'Pod not found', 'pods' ), $this );
2298
2299
        $params->pod_id = $pod[ 'id' ];
2300
        $params->pod = $pod[ 'name' ];
2301
        $params->pod_data = $pod;
2302
2303
        $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2304
2305
        if ( !isset( $params->id ) )
2306
            $params->id = 0;
2307
2308
        if ( empty( $params->name ) )
2309
            return pods_error( 'Pod field name is required', $this );
2310
2311
        $field = $this->load_field( $params );
2312
2313
        unset( $params->pod_data );
2314
2315
        $old_id = $old_name = $old_type = $old_definition = $old_simple = $old_options = $old_sister_id = null;
2316
2317
        if ( !empty( $field ) ) {
2318
            $old_id = pods_var( 'id', $field );
2319
            $old_name = pods_clean_name( $field[ 'name' ], true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2320
            $old_type = $field[ 'type' ];
2321
            $old_options = $field[ 'options' ];
2322
            $old_sister_id = (int) pods_var( 'sister_id', $old_options, 0 );
2323
2324
            $old_simple = ( 'pick' == $old_type && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
2325
2326
            if ( isset( $params->name ) && !empty( $params->name ) )
2327
                $field[ 'name' ] = $params->name;
2328
2329
            if ( $old_name != $field[ 'name' ] && false !== $this->field_exists( $params ) )
2330
                return pods_error( sprintf( __( 'Field %s already exists, you cannot rename %s to that', 'pods' ), $field[ 'name' ], $old_name ), $this );
2331
2332
            if ( ( $id_required || !empty( $params->id ) ) && ( empty( $old_id ) || $old_id != $params->id ) )
2333
                return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field[ 'name' ] ), $this );
2334
2335
            if ( empty( $params->id ) )
2336
                $params->id = $old_id;
2337
2338
            if ( !in_array( $old_type, $tableless_field_types ) || $old_simple ) {
2339
                $definition = $this->get_field_definition( $old_type, array_merge( $field, $old_options ) );
2340
2341
                if ( 0 < strlen( $definition ) )
2342
                    $old_definition = "`{$old_name}` " . $definition;
2343
            }
2344
        }
2345
        else {
2346
            $field = array(
2347
                'id' => 0,
2348
                'pod_id' => $params->pod_id,
2349
                'name' => $params->name,
2350
                'label' => $params->name,
2351
                'description' => '',
2352
                'type' => 'text',
2353
                'pick_object' => '',
2354
                'pick_val' => '',
2355
                'sister_id' => '',
2356
                'weight' => null,
2357
                'options' => array()
2358
            );
2359
        }
2360
2361
        // Setup options
2362
        $options = get_object_vars( $params );
2363
2364
        $options_ignore = array(
2365
            'method',
2366
            'table_info',
2367
            'attributes',
2368
            'group',
2369
            'grouped',
2370
            'developer_mode',
2371
            'dependency',
2372
            'depends-on',
2373
            'excludes-on'
2374
        );
2375
2376
        foreach ( $options_ignore as $ignore ) {
2377
            if ( isset( $options[ $ignore ] ) )
2378
                unset( $options[ $ignore ] );
2379
        }
2380
2381
        if ( isset( $options[ 'method' ] ) )
2382
            unset( $options[ 'method' ] );
2383
        elseif ( isset( $options[ 'table_info' ] ) )
2384
            unset( $options[ 'table_info' ] );
2385
2386
        $exclude = array(
2387
            'id',
2388
            'pod_id',
2389
            'pod',
2390
            'name',
2391
            'label',
2392
            'description',
2393
            'type',
2394
            'pick_object',
2395
            'pick_val',
2396
            'sister_id',
2397
            'weight',
2398
            'options'
2399
        );
2400
2401 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2402
            $aliases = array( $exclude_field );
2403
2404
            if ( is_array( $exclude_field ) ) {
2405
                $aliases = array_merge( array( $k ), $exclude_field );
2406
                $exclude_field = $k;
2407
            }
2408
2409
            foreach ( $aliases as $alias ) {
2410
                if ( isset( $options[ $alias ] ) ) {
2411
                    $field[ $exclude_field ] = pods_trim( $options[ $alias ] );
2412
2413
                    unset( $options[ $alias ] );
2414
                }
2415
            }
2416
        }
2417
2418
        if ( strlen( $field[ 'label' ] ) < 1 )
2419
            $field[ 'label' ] = $field[ 'name' ];
2420
2421
        $field[ 'options' ][ 'type' ] = $field[ 'type' ];
2422
2423
        if ( in_array( $field[ 'options' ][ 'type' ], $tableless_field_types ) ) {
2424
            // Clean up special drop-down in field editor and save out pick_val
2425
            $field[ 'pick_object' ] = pods_var( 'pick_object', $field, '', null, true );
2426
2427
            if ( 0 === strpos( $field[ 'pick_object' ], 'pod-' ) ) {
2428
                $field[ 'pick_val' ] = pods_str_replace( 'pod-', '', $field[ 'pick_object' ], 1 );
2429
                $field[ 'pick_object' ] = 'pod';
2430
            }
2431 View Code Duplication
            elseif ( 0 === strpos( $field[ 'pick_object' ], 'post_type-' ) ) {
2432
                $field[ 'pick_val' ] = pods_str_replace( 'post_type-', '', $field[ 'pick_object' ], 1 );
2433
                $field[ 'pick_object' ] = 'post_type';
2434
            }
2435 View Code Duplication
            elseif ( 0 === strpos( $field[ 'pick_object' ], 'taxonomy-' ) ) {
2436
                $field[ 'pick_val' ] = pods_str_replace( 'taxonomy-', '', $field[ 'pick_object' ], 1 );
2437
                $field[ 'pick_object' ] = 'taxonomy';
2438
            }
2439
            elseif ( 'table' == $field[ 'pick_object' ] && 0 < strlen( pods_var_raw( 'pick_table', $field[ 'options' ] ) ) ) {
2440
                $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_table' ];
2441
                $field[ 'pick_object' ] = 'table';
2442
            }
2443
            elseif ( false === strpos( $field[ 'pick_object' ], '-' ) && !in_array( $field[ 'pick_object' ], array( 'pod', 'post_type', 'taxonomy' ) ) ) {
2444
                $field[ 'pick_val' ] = '';
2445
			}
2446
			elseif ( 'custom-simple' == $field[ 'pick_object' ] ) {
2447
                $field[ 'pick_val' ] = '';
2448
			}
2449
2450
            $field[ 'options' ][ 'pick_object' ] = $field[ 'pick_object' ];
2451
            $field[ 'options' ][ 'pick_val' ] = $field[ 'pick_val' ];
2452
            $field[ 'options' ][ 'sister_id' ] = pods_var( 'sister_id', $field );
2453
2454
            unset( $field[ 'pick_object' ] );
2455
            unset( $field[ 'pick_val' ] );
2456
2457
            if ( isset( $field[ 'sister_id' ] ) )
2458
                unset( $field[ 'sister_id' ] );
2459
        }
2460
2461
        $field[ 'options' ] = array_merge( $field[ 'options' ], $options );
2462
2463
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
2464
2465
        if ( 0 < $old_id && defined( 'PODS_FIELD_STRICT' ) && !PODS_FIELD_STRICT )
2466
            $params->id = $field[ 'id' ] = $old_id;
2467
2468
        // Add new field
2469
        if ( !isset( $params->id ) || empty( $params->id ) || empty( $field ) ) {
2470
            if ( $table_operation && in_array( $field[ 'name' ], array( 'created', 'modified' ) ) && !in_array( $field[ 'type' ], array( 'date', 'datetime' ) ) && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2471
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2472
2473
            if ( $table_operation && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2474
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2475
2476 View Code Duplication
            if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) )
2477
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2478
2479
            foreach ( $object_fields as $object_field => $object_field_opt ) {
2480
                if ( $object_field == $field[ 'name' ] || in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2481
                    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 );
2482
            }
2483
2484
            if ( in_array( $field[ 'name' ], array( 'rss' ) ) ) // Reserved post_name values that can't be used as field names
2485
                $field[ 'name' ] .= '2';
2486
2487
            if ( 'slug' == $field[ 'type' ] && true === $db ) {
2488 View Code Duplication
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy', 'user' ) ) )
2489
                    return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this );
2490
2491
                $slug_field = get_posts( array(
2492
                    'post_type' => '_pods_field',
2493
                    'orderby' => 'menu_order',
2494
                    'order' => 'ASC',
2495
                    'posts_per_page' => 1,
2496
                    'post_parent' => $field[ 'pod_id' ],
2497
                    'meta_query' => array(
2498
                        array(
2499
                            'key' => 'type',
2500
                            'value' => 'slug'
2501
                        )
2502
                    )
2503
                ) );
2504
2505
                if ( !empty( $slug_field ) )
2506
                    return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this );
2507
            }
2508
2509
            // Sink the new field to the bottom of the list
2510
            if ( null === $field[ 'weight' ] ) {
2511
                $field[ 'weight' ] = 0;
2512
2513
                $bottom_most_field = get_posts( array(
2514
                    'post_type' => '_pods_field',
2515
                    'orderby' => 'menu_order',
2516
                    'order' => 'DESC',
2517
                    'posts_per_page' => 1,
2518
                    'post_parent' => $field[ 'pod_id' ]
2519
                ) );
2520
2521
                if ( !empty( $bottom_most_field ) )
2522
                    $field[ 'weight' ] = pods_absint( $bottom_most_field[ 0 ]->menu_order ) + 1;
2523
            }
2524
2525
            $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2526
2527
            $post_data = array(
2528
                'post_name' => $field[ 'name' ],
2529
                'post_title' => $field[ 'label' ],
2530
                'post_content' => $field[ 'description' ],
2531
                'post_type' => '_pods_field',
2532
                'post_parent' => $field[ 'pod_id' ],
2533
                'post_status' => 'publish',
2534
                'menu_order' => $field[ 'weight' ]
2535
            );
2536
        }
2537
        else {
2538
            if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) ) {
2539 View Code Duplication
                if ( null !== $old_name )
2540
                    return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2541
                else
2542
                    return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2543
            }
2544
2545
            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 ) )
2546
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2547
2548
            if ( null !== $old_name && $field[ 'name' ] != $old_name && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2549
                return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2550
2551
            foreach ( $object_fields as $object_field => $object_field_opt ) {
2552
                if ( $object_field != $field[ 'name' ] && !in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2553
                    continue;
2554
2555 View Code Duplication
                if ( null !== $old_name )
2556
                    return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2557
                else
2558
                    return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2559
            }
2560
2561
            $post_data = array(
2562
                'ID' => $field[ 'id' ],
2563
                'post_name' => $field[ 'name' ],
2564
                'post_title' => $field[ 'label' ],
2565
                'post_content' => $field[ 'description' ]
2566
            );
2567
2568
            if ( null !== $field[ 'weight' ] ) {
2569
                $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2570
2571
                $post_data[ 'menu_order' ] = $field[ 'weight' ];
2572
            }
2573
        }
2574
2575 View Code Duplication
        if ( true === $db ) {
2576
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
2577
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
2578
2579
            $conflicted = false;
2580
2581
            // Headway compatibility fix
2582
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
2583
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2584
2585
                $conflicted = true;
2586
            }
2587
2588
            $params->id = $this->save_wp_object( 'post', $post_data, $field[ 'options' ], true, true );
2589
2590
            if ( $conflicted )
2591
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2592
2593
            if ( false === $params->id )
2594
                return pods_error( __( 'Cannot save Field', 'pods' ), $this );
2595
        }
2596
        else
2597
            $params->id = $field[ 'name' ];
2598
2599
        $field[ 'id' ] = $params->id;
2600
2601
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field[ 'options' ] ), $simple_tableless_objects ) );
2602
2603
        $definition = false;
2604
2605
        if ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) {
2606
            $field_definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, $field[ 'options' ] ) );
2607
2608
            if ( 0 < strlen( $field_definition ) )
2609
                $definition = '`' . $field[ 'name' ] . '` ' . $field_definition;
2610
        }
2611
2612
        $sister_id = (int) pods_var( 'sister_id', $field[ 'options' ], 0 );
2613
2614
        if ( $table_operation && 'table' == $pod[ 'storage' ] && !pods_tableless() ) {
2615
            if ( !empty( $old_id ) ) {
2616
                if ( ( $field[ 'type' ] != $old_type || $old_simple != $simple ) && empty( $definition ) )
2617
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false );
2618
                elseif ( 0 < strlen( $definition ) ) {
2619
                    if ( $old_name != $field[ 'name' ] || $old_simple != $simple ) {
2620
                        $test = false;
2621
2622 View Code Duplication
                        if ( 0 < strlen( $old_definition ) )
2623
                            $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2624
2625
                        // If the old field doesn't exist, continue to add a new field
2626
                        if ( false === $test )
2627
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2628
                    }
2629
                    elseif ( null !== $old_definition && $definition != $old_definition ) {
2630
                        $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2631
2632
                        // If the old field doesn't exist, continue to add a new field
2633
                        if ( false === $test )
2634
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2635
                    }
2636
                }
2637
            }
2638
            elseif ( 0 < strlen( $definition ) ) {
2639
                $test = false;
2640
2641 View Code Duplication
                if ( 0 < strlen( $old_definition ) )
2642
                    $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `" . $field[ 'name' ] . "` {$definition}", false );
2643
2644
                // If the old field doesn't exist, continue to add a new field
2645
                if ( false === $test )
2646
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2647
            }
2648
        }
2649
2650
        if ( !empty( $old_id ) && 'meta' == $pod[ 'storage' ] && $old_name != $field[ 'name' ] && $pod[ 'meta_table' ] != $pod[ 'table' ] ) {
2651
            $prepare = array(
2652
                $field[ 'name' ],
2653
                $old_name
2654
            );
2655
2656
            // Users don't have a type
2657
            if ( !empty( $pod[ 'field_type' ] ) )
2658
                $prepare[] = $pod[ 'name' ];
2659
2660
            pods_query( "
2661
                UPDATE `{$pod[ 'meta_table' ]}` AS `m`
2662
                LEFT JOIN `{$pod[ 'table' ]}` AS `t`
2663
                    ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}`
2664
                SET
2665
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2666
                WHERE
2667
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2668
            " . ( !empty( $pod[ 'field_type' ] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ),
2669
                $prepare
2670
            );
2671
        }
2672
2673
        if ( $field[ 'type' ] != $old_type && in_array( $old_type, $tableless_field_types ) ) {
2674
            delete_post_meta( $old_sister_id, 'sister_id' );
2675
2676
            if ( true === $db ) {
2677
                pods_query( "
2678
                        DELETE pm
2679
                        FROM {$wpdb->postmeta} AS pm
2680
                        LEFT JOIN {$wpdb->posts} AS p
2681
                            ON p.post_type = '_pods_field'
2682
                            AND p.ID = pm.post_id
2683
                        WHERE
2684
                            p.ID IS NOT NULL
2685
                            AND pm.meta_key = 'sister_id'
2686
                            AND pm.meta_value = %d
2687
                    ", array(
2688
                        $params->id
2689
                    )
2690
                );
2691
2692
                if ( !pods_tableless() ) {
2693
                    pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false );
2694
2695
                    pods_query( "
2696
                            UPDATE `@wp_podsrel`
2697
                            SET `related_field_id` = 0
2698
                            WHERE `field_id` = %d
2699
                        ", array(
2700
                            $old_sister_id
2701
                        )
2702
                    );
2703
                }
2704
            }
2705
        }
2706 View Code Duplication
        elseif ( 0 < $sister_id ) {
2707
            update_post_meta( $sister_id, 'sister_id', $params->id );
2708
2709
            if ( true === $db && ( !pods_tableless() ) ) {
2710
                pods_query( "
2711
                        UPDATE `@wp_podsrel`
2712
                        SET `related_field_id` = %d
2713
                        WHERE `field_id` = %d
2714
                    ",
2715
                    array(
2716
                        $params->id,
2717
                        $sister_id
2718
                    )
2719
                );
2720
            }
2721
        }
2722 View Code Duplication
        elseif ( 0 < $old_sister_id ) {
2723
            delete_post_meta( $old_sister_id, 'sister_id' );
2724
2725
            if ( true === $db && ( !pods_tableless() ) ) {
2726
                pods_query( "
2727
                        UPDATE `@wp_podsrel`
2728
                        SET `related_field_id` = 0
2729
                        WHERE `field_id` = %d
2730
                    ", array(
2731
                        $old_sister_id
2732
                    )
2733
                );
2734
            }
2735
        }
2736
2737
        if ( !empty( $old_id ) && $old_name != $field[ 'name' ] && true === $db ) {
2738
            pods_query( "
2739
                    UPDATE `@wp_postmeta`
2740
                    SET `meta_value` = %s
2741
                    WHERE
2742
                        `post_id` = %d
2743
                        AND `meta_key` = 'pod_index'
2744
                        AND `meta_value` = %s
2745
                ", array(
2746
                    $field[ 'name' ],
2747
                    $pod[ 'id' ],
2748
                    $old_name
2749
                )
2750
            );
2751
        }
2752
2753
        if ( !$save_pod )
2754
            $this->cache_flush_pods( $pod );
2755
        else {
2756
            pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
2757
2758
            if ( !empty( $old_id ) && $old_name != $field[ 'name' ] )
2759
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $old_name );
2760
        }
2761
2762
        if ( true === $db )
2763
            return $params->id;
2764
        else
2765
            return $field;
2766
    }
2767
2768
    /**
2769
     * Fix Pod / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name)
2770
     *
2771
     * @param string $slug Unique slug value
2772
     * @param int $post_ID Post ID
2773
     * @param string $post_status Post Status
2774
     * @param string $post_type Post Type
2775
     * @param int $post_parent Post Parent ID
2776
     * @param string $original_slug Original slug value
2777
     *
2778
     * @return string Final slug value
2779
     *
2780
     * @since 2.3.3
2781
     */
2782
    public function save_slug_fix ( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) {
2783
        if ( in_array( $post_type, array( '_pods_field', '_pods_pod' ) ) && false !== strpos( $slug, '-' ) )
2784
            $slug = $original_slug;
2785
2786
        return $slug;
2787
    }
2788
2789
    /**
2790
     * Add or Edit a Pods Object
2791
     *
2792
     * $params['id'] int The Object ID
2793
     * $params['name'] string The Object name
2794
     * $params['type'] string The Object type
2795
     * $params['options'] Associative array of Object options
2796
     *
2797
     * @param array|object $params An associative array of parameters
2798
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
2799
     *
2800
     * @return int The Object ID
2801
     * @since 2.0
2802
     */
2803
    public function save_object ( $params, $sanitized = false ) {
2804
        $params = (object) $params;
2805
2806
        if ( false === $sanitized )
2807
            $params = pods_sanitize( $params );
2808
2809 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
2810
            return pods_error( __( 'Name must be given to save an Object', 'pods' ), $this );
2811
2812 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
2813
            return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this );
2814
2815
        $object = array(
2816
            'id' => 0,
2817
            'name' => $params->name,
2818
            'type' => $params->type,
2819
            'code' => '',
2820
            'options' => array()
2821
        );
2822
2823
        // Setup options
2824
        $options = get_object_vars( $params );
2825
2826
        if ( isset( $options[ 'method' ] ) )
2827
            unset( $options[ 'method' ] );
2828
2829
        $exclude = array(
2830
            'id',
2831
            'name',
2832
            'helper_type',
2833
            'code',
2834
            'options',
2835
            'status'
2836
        );
2837
2838 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2839
            $aliases = array( $exclude_field );
2840
2841
            if ( is_array( $exclude_field ) ) {
2842
                $aliases = array_merge( array( $k ), $exclude_field );
2843
                $exclude_field = $k;
2844
            }
2845
2846
            foreach ( $aliases as $alias ) {
2847
                if ( isset( $options[ $alias ] ) ) {
2848
                    $object[ $exclude_field ] = pods_trim( $options[ $alias ] );
2849
2850
                    unset( $options[ $alias ] );
2851
                }
2852
            }
2853
        }
2854
2855
        if ( 'helper' == $object[ 'type' ] )
2856
            $object[ 'options' ][ 'helper_type' ] = $object[ 'helper_type' ];
2857
2858
        if ( isset( $object[ 'options' ][ 'code' ] ) )
2859
            unset( $object[ 'options' ][ 'code' ] );
2860
2861
        $object[ 'options' ] = array_merge( $object[ 'options' ], $options );
2862
2863
        $post_data = array(
2864
            'post_name' => pods_clean_name( $object[ 'name' ], true),
2865
            'post_title' => $object[ 'name' ],
2866
            'post_content' => $object[ 'code' ],
2867
            'post_type' => '_pods_' . $object[ 'type' ],
2868
            'post_status' => 'publish'
2869
        );
2870
2871
        if ( !empty( $object[ 'id' ] ) )
2872
            $post_data[ 'ID' ] = $object[ 'id' ];
2873
2874
        if ( null !== pods_var( 'status', $object, null, null, true ) )
2875
            $post_data[ 'post_status' ] = pods_var( 'status', $object, null, null, true );
2876
2877
        remove_filter( 'content_save_pre', 'balanceTags', 50 );
2878
2879
        $post_data = pods_sanitize( $post_data );
2880
2881
        $params->id = $this->save_post( $post_data, $object[ 'options' ], true, true );
2882
2883
        pods_transient_clear( 'pods_objects_' . $params->type );
2884
        pods_transient_clear( 'pods_objects_' . $params->type . '_get' );
2885
2886
        return $params->id;
2887
    }
2888
2889
    /**
2890
     * @see PodsAPI::save_object
2891
     *
2892
     * Add or edit a Pod Template
2893
     *
2894
     * $params['id'] int The template ID
2895
     * $params['name'] string The template name
2896
     * $params['code'] string The template code
2897
     *
2898
     * @param array|object $params An associative array of parameters
2899
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2900
     *
2901
     * @return int The Template ID
2902
     *
2903
     * @since 1.7.9
2904
     */
2905
    public function save_template ( $params, $sanitized = false ) {
2906
        $params = (object) $params;
2907
2908
        $params->type = 'template';
2909
2910
        return $this->save_object( $params, $sanitized );
2911
    }
2912
2913
    /**
2914
     * @see PodsAPI::save_object
2915
     *
2916
     * Add or edit a Pod Page
2917
     *
2918
     * $params['id'] int The page ID
2919
     * $params['name'] string The page URI
2920
     * $params['code'] string The page code
2921
     *
2922
     * @param array|object $params An associative array of parameters
2923
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2924
     *
2925
     * @return int The page ID
2926
     * @since 1.7.9
2927
     */
2928
    public function save_page ( $params, $sanitized = false ) {
2929
        $params = (object) $params;
2930
2931
        if ( !isset( $params->name ) ) {
2932
            $params->name = $params->uri;
2933
            unset( $params->uri );
2934
        }
2935
2936
        if ( isset( $params->phpcode ) ) {
2937
            $params->code = $params->phpcode;
2938
            unset( $params->phpcode );
2939
        }
2940
2941
        $params->name = trim( $params->name, '/' );
2942
        $params->type = 'page';
2943
2944
        return $this->save_object( $params, $sanitized );
2945
    }
2946
2947
    /**
2948
     * @see PodsAPI::save_object
2949
     *
2950
     * Add or edit a Pod Helper
2951
     *
2952
     * $params['id'] int The helper ID
2953
     * $params['name'] string The helper name
2954
     * $params['helper_type'] string The helper type ("pre_save", "display", etc)
2955
     * $params['code'] string The helper code
2956
     *
2957
     * @param array $params An associative array of parameters
2958
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2959
     *
2960
     * @return int The helper ID
2961
     * @since 1.7.9
2962
     */
2963
    public function save_helper ( $params, $sanitized = false ) {
2964
        $params = (object) $params;
2965
2966
        if ( isset( $params->phpcode ) ) {
2967
            $params->code = $params->phpcode;
2968
            unset( $params->phpcode );
2969
        }
2970
2971
        if ( isset( $params->type ) ) {
2972
            $params->helper_type = $params->type;
2973
            unset( $params->type );
2974
        }
2975
2976
        $params->type = 'helper';
2977
2978
        return $this->save_object( $params, $sanitized );
2979
    }
2980
2981
    /**
2982
     * Add or edit a single pod item
2983
     *
2984
     * $params['pod'] string The Pod name (pod or pod_id is required)
2985
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
2986
     * $params['id'] int The item ID
2987
     * $params['data'] array (optional) Associative array of field names + values
2988
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
2989
	 * $params['track_changed_fields'] bool Set to true to enable tracking of saved fields via PodsAPI::get_changed_fields()
2990
     *
2991
     * @param array|object $params An associative array of parameters
2992
     *
2993
     * @return int The item ID
2994
     *
2995
     * @since 1.7.9
2996
     */
2997
    public function save_pod_item ( $params ) {
2998
2999
		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...
3000
3001
        $params = (object) pods_str_replace( '@wp_', '{prefix}', $params );
3002
3003
        $tableless_field_types = PodsForm::tableless_field_types();
3004
        $repeatable_field_types = PodsForm::repeatable_field_types();
3005
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
3006
3007
        // @deprecated 2.0
3008
        if ( isset( $params->datatype ) ) {
3009
            pods_deprecated( '$params->pod instead of $params->datatype', '2.0' );
3010
3011
            $params->pod = $params->datatype;
3012
3013
            unset( $params->datatype );
3014
3015
            if ( isset( $params->pod_id ) ) {
3016
                pods_deprecated( '$params->id instead of $params->pod_id', '2.0' );
3017
3018
                $params->id = $params->pod_id;
3019
3020
                unset( $params->pod_id );
3021
            }
3022
3023
            if ( isset( $params->data ) && !empty( $params->data ) && is_array( $params->data ) ) {
3024
                $check = current( $params->data );
3025
3026
                if ( is_array( $check ) ) {
3027
                    pods_deprecated( 'PodsAPI::save_pod_items', '2.0' );
3028
3029
                    return $this->save_pod_items( $params, $params->data );
3030
                }
3031
            }
3032
        }
3033
3034
        // @deprecated 2.0
3035
        if ( isset( $params->tbl_row_id ) ) {
3036
            pods_deprecated( '$params->id instead of $params->tbl_row_id', '2.0' );
3037
3038
            $params->id = $params->tbl_row_id;
3039
3040
            unset( $params->tbl_row_id );
3041
        }
3042
3043
        // @deprecated 2.0
3044
        if ( isset( $params->columns ) ) {
3045
            pods_deprecated( '$params->data instead of $params->columns', '2.0' );
3046
3047
            $params->data = $params->columns;
3048
3049
            unset( $params->columns );
3050
        }
3051
3052
        if ( !isset( $params->pod ) )
3053
            $params->pod = false;
3054 View Code Duplication
        if ( isset( $params->pod_id ) )
3055
            $params->pod_id = pods_absint( $params->pod_id );
3056
        else
3057
            $params->pod_id = 0;
3058
3059 View Code Duplication
        if ( isset( $params->id ) )
3060
            $params->id = pods_absint( $params->id );
3061
        else
3062
            $params->id = 0;
3063
3064
        if ( !isset( $params->from ) )
3065
            $params->from = 'save';
3066
3067
        if ( !isset( $params->location ) )
3068
            $params->location = null;
3069
3070
        if ( !isset( $params->track_changed_fields ) )
3071
            $params->track_changed_fields = false;
3072
3073
		/**
3074
		 * Override $params['track_changed_fields']
3075
		 *
3076
		 * Use for globally setting field change tracking.
3077
		 *
3078
		 * @param bool
3079
		 *
3080
		 * @since 2.3.19
3081
		 */
3082
		$track_changed_fields = apply_filters( 'pods_api_save_pod_item_track_changed_fields_' . $params->pod, (boolean) $params->track_changed_fields, $params );
3083
		$changed_fields = array();
3084
3085
		if ( !isset( $params->clear_slug_cache ) ) {
3086
			$params->clear_slug_cache = true;
3087
		}
3088
3089
        // Support for bulk edit
3090
        if ( isset( $params->id ) && !empty( $params->id ) && is_array( $params->id ) ) {
3091
            $ids = array();
3092
            $new_params = $params;
3093
3094
            foreach ( $params->id as $id ) {
3095
                $new_params->id = $id;
3096
3097
                $ids[] = $this->save_pod_item( $new_params );
3098
            }
3099
3100
            return $ids;
3101
        }
3102
3103
        // Allow Helpers to know what's going on, are we adding or saving?
3104
        $is_new_item = false;
3105
3106
        if ( empty( $params->id ) )
3107
            $is_new_item = true;
3108
3109
        if ( isset( $params->is_new_item ) )
3110
            $is_new_item = (boolean) $params->is_new_item;
3111
3112
        // Allow Helpers to bypass subsequent helpers in recursive save_pod_item calls
3113
        $bypass_helpers = false;
3114
3115
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
3116
            $bypass_helpers = true;
3117
3118
        // Allow Custom Fields not defined by Pods to be saved
3119
        $allow_custom_fields = false;
3120
3121
        if ( isset( $params->allow_custom_fields ) && false !== $params->allow_custom_fields )
3122
            $allow_custom_fields = true;
3123
3124
        // Get array of Pods
3125
        $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
3126
3127
        if ( false === $pod )
3128
            return pods_error( __( 'Pod not found', 'pods' ), $this );
3129
3130
        $params->pod = $pod[ 'name' ];
3131
        $params->pod_id = $pod[ 'id' ];
3132
3133
        if ( 'settings' == $pod[ 'type' ] )
3134
            $params->id = $pod[ 'id' ];
3135
3136
        $fields = $pod[ 'fields' ];
3137
3138
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
3139
3140
        $fields_active = array();
3141
        $custom_data = array();
3142
3143
        // Find the active fields (loop through $params->data to retain order)
3144
        if ( !empty( $params->data ) && is_array( $params->data ) ) {
3145
            $custom_fields = array();
3146
3147
            foreach ( $params->data as $field => $value ) {
3148
                if ( isset( $object_fields[ $field ] ) ) {
3149
                    $object_fields[ $field ][ 'value' ] = $value;
3150
                    $fields_active[] = $field;
3151
                }
3152
                elseif ( isset( $fields[ $field ] ) ) {
3153
                    if ( 'save' == $params->from || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3154
                        $fields[ $field ][ 'value' ] = $value;
3155
                        $fields_active[] = $field;
3156
                    }
3157
                    elseif ( !pods_has_permissions( $fields[ $field ][ 'options' ] ) && pods_var( 'hidden', $fields[ $field ][ 'options' ], false ) ) {
3158
                        $fields[ $field ][ 'value' ] = $value;
3159
                        $fields_active[] = $field;
3160
                    }
3161
                }
3162
                else {
3163
                    $found = false;
3164
3165
                    foreach ( $object_fields as $object_field => $object_field_opt ) {
3166
                        if ( in_array( $field, $object_field_opt[ 'alias' ] ) ) {
3167
                            $object_fields[ $object_field ][ 'value' ] = $value;
3168
                            $fields_active[] = $object_field;
3169
3170
                            $found = true;
3171
3172
                            break;
3173
                        }
3174
                    }
3175
3176
                    if ( $allow_custom_fields && !$found )
3177
                        $custom_fields[] = $field;
3178
                }
3179
            }
3180
3181
            if ( $allow_custom_fields && !empty( $custom_fields ) ) {
3182
                foreach ( $custom_fields as $field ) {
3183
                    $custom_data[ $field ] = $params->data[ $field ];
3184
                }
3185
            }
3186
3187
           unset( $params->data );
3188
        }
3189
3190 View Code Duplication
		if ( empty( $params->id ) && !in_array( 'created', $fields_active ) && isset( $fields[ 'created' ] ) && in_array( $fields[ 'created' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3191
			$fields[ 'created' ][ 'value' ] = current_time( 'mysql' );
3192
			$fields_active[] = 'created';
3193
		}
3194
3195 View Code Duplication
		if ( !in_array( 'modified', $fields_active ) && isset( $fields[ 'modified' ] ) && in_array( $fields[ 'modified' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3196
			$fields[ 'modified' ][ 'value' ] = current_time( 'mysql' );
3197
			$fields_active[] = 'modified';
3198
		}
3199
3200
        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' ] ] ) ) {
3201
			$fields[ $pod[ 'pod_field_slug' ] ][ 'value' ] = ''; // this will get picked up by slug pre_save method
3202
			$fields_active[] = $pod[ 'pod_field_slug' ];
3203
        }
3204
3205
        // Handle hidden fields
3206
        if ( empty( $params->id ) ) {
3207
            foreach ( $fields as $field => $field_data ) {
3208
                if ( in_array( $field, $fields_active ) )
3209
                    continue;
3210
3211
                if ( in_array( $params->from, array( 'save', 'process_form' ) ) || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3212
                    $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 );
3213
3214
                    if ( null !== $value && '' !== $value && false !== $value ) {
3215
                        $fields[ $field ][ 'value' ] = $value;
3216
                        $fields_active[] = $field;
3217
                    }
3218
                }
3219
            }
3220
3221
			// Set default field values for object fields
3222
			if ( !empty( $object_fields ) ) {
3223 View Code Duplication
				foreach ( $object_fields as $field => $field_data ) {
3224
					if ( in_array( $field, $fields_active ) ) {
3225
						continue;
3226
					}
3227
					elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3228
						continue;
3229
					}
3230
3231
                    $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 );
3232
3233
                    if ( null !== $value && '' !== $value && false !== $value ) {
3234
                        $object_fields[ $field ][ 'value' ] = $value;
3235
                        $fields_active[] = $field;
3236
                    }
3237
				}
3238
			}
3239
3240
			// Set default field values for Pod fields
3241 View Code Duplication
			foreach ( $fields as $field => $field_data ) {
3242
				if ( in_array( $field, $fields_active ) ) {
3243
					continue;
3244
				}
3245
				elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3246
					continue;
3247
				}
3248
3249
				$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 );
3250
3251
				if ( null !== $value && '' !== $value && false !== $value ) {
3252
					$fields[ $field ][ 'value' ] = $value;
3253
					$fields_active[] = $field;
3254
				}
3255
			}
3256
        }
3257
3258
        $columns =& $fields; // @deprecated 2.0
3259
        $active_columns =& $fields_active; // @deprecated 2.0
3260
        $params->tbl_row_id =& $params->id; // @deprecated 2.0
3261
3262
        $pre_save_helpers = $post_save_helpers = array();
3263
3264
		$pieces = array(
3265
			'fields',
3266
			'params',
3267
			'pod',
3268
			'fields_active',
3269
			'object_fields',
3270
			'custom_fields',
3271
			'custom_data',
3272
			'track_changed_fields',
3273
			'changed_fields'
3274
		);
3275
3276
        if ( false === $bypass_helpers ) {
3277
            // Plugin hooks
3278
            $hooked = $this->do_hook( 'pre_save_pod_item', compact( $pieces ), $is_new_item, $params->id );
3279
3280
            if ( is_array( $hooked ) && !empty( $hooked ) )
3281
                extract( $hooked );
3282
3283
            $hooked = $this->do_hook( "pre_save_pod_item_{$params->pod}", compact( $pieces ), $is_new_item, $params->id );
3284
3285
            if ( is_array( $hooked ) && !empty( $hooked ) )
3286
                extract( $hooked );
3287
3288
            if ( $is_new_item ) {
3289
                $hooked = $this->do_hook( 'pre_create_pod_item', compact( $pieces ) );
3290
3291
                if ( is_array( $hooked ) && !empty( $hooked ) )
3292
                    extract( $hooked );
3293
3294
                $hooked = $this->do_hook( "pre_create_pod_item_{$params->pod}", compact( $pieces ) );
3295
3296
                if ( is_array( $hooked ) && !empty( $hooked ) )
3297
                    extract( $hooked );
3298
            }
3299
            else {
3300
                $hooked = $this->do_hook( 'pre_edit_pod_item', compact( $pieces ), $params->id );
3301
3302
                if ( is_array( $hooked ) && !empty( $hooked ) )
3303
                    extract( $hooked );
3304
3305
                $hooked = $this->do_hook( "pre_edit_pod_item_{$params->pod}", compact( $pieces ), $params->id );
3306
3307
                if ( is_array( $hooked ) && !empty( $hooked ) )
3308
                    extract( $hooked );
3309
            }
3310
3311
            // Call any pre-save helpers (if not bypassed)
3312 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3313
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
3314
                    $helpers = array( 'pre_save_helpers', 'post_save_helpers' );
3315
3316
                    foreach ( $helpers as $helper ) {
3317
                        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...
3318
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
3319
                    }
3320
                }
3321
3322
                if ( !empty( $pre_save_helpers ) ) {
3323
                    pods_deprecated( sprintf( __( 'Pre-save helpers are deprecated, use the action pods_pre_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3324
3325
                    foreach ( $pre_save_helpers as $helper ) {
3326
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3327
3328
                        if ( false !== $helper )
3329
                            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...
3330
                    }
3331
                }
3332
            }
3333
        }
3334
3335
		if ( $track_changed_fields ) {
3336
			$changed_fields = $this->get_changed_fields( compact( $pieces ) );
3337
		}
3338
3339
        $table_data = $table_formats = $update_values = $rel_fields = $rel_field_ids = array();
3340
3341
        $object_type = $pod[ 'type' ];
3342
3343
        $object_ID = 'ID';
3344
3345
        if ( 'comment' == $object_type )
3346
            $object_ID = 'comment_ID';
3347
        elseif ( 'taxonomy' == $object_type )
3348
            $object_ID = 'term_id';
3349
3350
        $object_data = $object_meta = $post_term_data = array();
3351
3352
        if ( 'settings' == $object_type )
3353
            $object_data[ 'option_id' ] = $pod[ 'name' ];
3354
        elseif ( !empty( $params->id ) )
3355
            $object_data[ $object_ID ] = $params->id;
3356
3357
        $fields_active = array_unique( $fields_active );
3358
3359
        // Loop through each active field, validating and preparing the table data
3360
        foreach ( $fields_active as $field ) {
3361 View Code Duplication
            if ( isset( $object_fields[ $field ] ) )
3362
                $field_data = $object_fields[ $field ];
3363
            elseif ( isset( $fields[ $field ] ) )
3364
                $field_data = $fields[ $field ];
3365
            else
3366
                continue;
3367
3368
            $value = $field_data[ 'value' ];
3369
            $type = $field_data[ 'type' ];
3370
            $options = pods_var( 'options', $field_data, array() );
3371
3372
            // WPML AJAX compatibility
3373
            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' ) )
3374
                $options[ 'unique' ] = $fields[ $field ][ 'options' ][ 'unique' ] = $options[ 'required' ] = $fields[ $field ][ 'options' ][ 'required' ] = 0;
3375
            else {
3376
                // Validate value
3377
                $validate = $this->handle_field_validation( $value, $field, $object_fields, $fields, $pod, $params );
3378
3379
                if ( false === $validate )
3380
                    $validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field_data[ 'label' ] );
3381
                elseif ( true !== $validate )
3382
                    $validate = (array) $validate;
3383
3384
                if ( !is_bool( $validate ) && !empty( $validate ) )
3385
                    return pods_error( $validate, $this );
3386
            }
3387
3388
            $value = PodsForm::pre_save( $field_data[ 'type' ], $value, $params->id, $field, array_merge( $field_data, $options ), array_merge( $fields, $object_fields ), $pod, $params );
3389
3390
            $field_data[ 'value' ] = $value;
3391
3392
            if ( isset( $object_fields[ $field ] ) ) {
3393
				if ( 'taxonomy' == $object_fields[ $field ][ 'type' ] ) {
3394
					$post_term_data[ $field ] = $value;
3395
				}
3396
				else {
3397
                	$object_data[ $field ] = $value;
3398
				}
3399
			}
3400
            else {
3401
                $simple = ( 'pick' == $type && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
3402
                $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field_data, $field, $fields, $pod, $params );
3403
3404
                // Handle Simple Relationships
3405
                if ( $simple ) {
3406
                    if ( !is_array( $value ) )
3407
                        $value = explode( ',', $value );
3408
3409
                    $pick_limit = (int) pods_var_raw( 'pick_limit', $options, 0 );
3410
3411
                    if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
3412
                        $pick_limit = 1;
3413
3414
                    if ( 'custom-simple' == pods_var( 'pick_object', $field_data ) ) {
3415
                        $custom = pods_var_raw( 'pick_custom', $options, '' );
3416
3417
                        $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data[ 'name' ], $value, array_merge( $field_data, $options ), $pod, $params->id );
3418
3419
                        if ( empty( $value ) || empty( $custom ) )
3420
                            $value = '';
3421
                        elseif ( !empty( $custom ) ) {
3422
                            if ( !is_array( $custom ) ) {
3423
                                $custom = explode( "\n", $custom );
3424
3425
                                $custom_values = array();
3426
3427
                                foreach ( $custom as $c => $cv ) {
3428
                                    if ( 0 < strlen( $cv ) ) {
3429
                                        $custom_label = explode( '|', $cv );
3430
3431
                                        if ( !isset( $custom_label[ 1 ] ) )
3432
                                            $custom_label[ 1 ] = $custom_label[ 0 ];
3433
3434
                                        $custom_label[ 0 ] = trim( (string) $custom_label[ 0 ] );
3435
                                        $custom_label[ 1 ] = trim( (string) $custom_label[ 1 ] );
3436
                                        $custom_values[ $custom_label[ 0 ] ] = $custom_label[ 1 ];
3437
                                    }
3438
                                }
3439
                            }
3440
                            else
3441
                                $custom_values = $custom;
3442
3443
                            $values = array();
3444
3445
                            foreach ( $value as $k => $v ) {
3446
                                $v = pods_unsanitize( $v );
3447
3448
                                if ( isset( $custom_values[ $v ] ) )
3449
                                    $values[ $k ] = $v;
3450
                            }
3451
3452
                            $value = $values;
3453
                        }
3454
                    }
3455
3456
                    if ( 0 < $pick_limit && !empty( $value ) )
3457
                        $value = array_slice( $value, 0, $pick_limit );
3458
3459
                    // Don't save an empty array, just make it an empty string
3460 View Code Duplication
                    if ( empty( $value ) )
3461
                        $value = '';
3462
                    elseif ( is_array( $value ) ) {
3463
                        // If there's just one item, don't save as an array, save the string
3464
                        if ( 1 == $pick_limit || 1 == count( $value ) )
3465
                            $value = implode( '', $value );
3466
                        // If storage is set to table, json encode, otherwise WP will serialize automatically
3467
                        elseif ( 'table' == pods_var( 'storage', $pod ) )
3468
                            $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...
3469
                    }
3470
                }
3471
3472
                // Prepare all table / meta data
3473
                if ( !in_array( $type, $tableless_field_types ) || $simple ) {
3474
                    if ( in_array( $type, $repeatable_field_types ) && 1 == pods_var( $type . '_repeatable', $field_data, 0 ) ) {
3475
                        // Don't save an empty array, just make it an empty string
3476 View Code Duplication
                        if ( empty( $value ) )
3477
                            $value = '';
3478
                        elseif ( is_array( $value ) ) {
3479
                            // If there's just one item, don't save as an array, save the string
3480
                            if ( 1 == count( $value ) )
3481
                                $value = implode( '', $value );
3482
                            // If storage is set to table, json encode, otherwise WP will serialize automatically
3483
                            elseif ( 'table' == pods_var( 'storage', $pod ) )
3484
                                $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...
3485
                        }
3486
                    }
3487
3488
                    $table_data[ $field ] = str_replace( array( '{prefix}', '@wp_' ), array( '{/prefix/}', '{prefix}' ), $value ); // Fix for pods_query
3489
                    $table_formats[] = PodsForm::prepare( $type, $options );
3490
3491
                    $object_meta[ $field ] = $value;
3492
                }
3493
                // Store relational field data to be looped through later
3494
                else {
3495
                    // Convert values from a comma-separated string into an array
3496
                    if ( !is_array( $value ) )
3497
                        $value = explode( ',', $value );
3498
3499
                    $rel_fields[ $type ][ $field ] = $value;
3500
                    $rel_field_ids[] = $field_data[ 'id' ];
3501
                }
3502
            }
3503
        }
3504
3505
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) ) {
3506
            $object_name = $pod[ 'name' ];
3507
3508
            if ( !empty( $pod[ 'object' ] ) )
3509
                $object_name = $pod[ 'object' ];
3510
3511
            $object_name_field = 'post_type';
3512
3513
            if ( 'taxonomy' == $pod['type'] ) {
3514
                $object_name_field = 'taxonomy';
3515
            }
3516
3517
            $object_data[ $object_name_field ] = $object_name;
3518
        }
3519
3520
        if ( ( 'meta' == $pod[ 'storage' ] || 'settings' == $pod[ 'type' ] || ( 'taxonomy' == $pod[ 'type' ] && 'none' == $pod[ 'storage' ] ) ) && !in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3521
            if ( $allow_custom_fields && !empty( $custom_data ) )
3522
                $object_meta = array_merge( $custom_data, $object_meta );
3523
3524
			$fields_to_send = array_flip( array_keys( $object_meta ) );
3525
3526
			foreach ( $fields_to_send as $field => $field_data ) {
3527 View Code Duplication
				if ( isset( $object_fields[ $field ] ) ) {
3528
					$field_data = $object_fields[ $field ];
3529
				}
3530
				elseif ( isset( $fields[ $field ] ) ) {
3531
					$field_data = $fields[ $field ];
3532
				}
3533
				else {
3534
					unset( $fields_to_send[ $field ] );
3535
				}
3536
3537
				$fields_to_send[ $field ] = $field_data;
3538
			}
3539
3540
            $params->id = $this->save_wp_object( $object_type, $object_data, $object_meta, false, true, $fields_to_send );
3541
3542
            if ( !empty( $params->id ) && 'settings' == $object_type )
3543
                $params->id = $pod[ 'id' ];
3544
        }
3545
        else {
3546
            if ( ! in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3547
                $params->id = $this->save_wp_object( $object_type, $object_data, array(), false, true );
3548
            }
3549
3550
            if ( 'table' == $pod[ 'storage' ] ) {
3551
                // Every row should have an id set here, otherwise Pods with nothing
3552
                // but relationship fields won't get properly ID'd
3553
                if ( empty( $params->id ) )
3554
                    $params->id = 0;
3555
3556
                $table_data = array( 'id' => $params->id ) + $table_data;
3557
                array_unshift( $table_formats, '%d' );
3558
3559
                if ( !empty( $table_data ) ) {
3560
                    $sql = pods_data()->insert_on_duplicate( "@wp_pods_{$params->pod}", $table_data, $table_formats );
3561
3562
                    $id = pods_query( $sql, 'Cannot add/save table row' );
3563
3564
                    if ( empty( $params->id ) )
3565
                        $params->id = $id;
3566
                }
3567
            }
3568
        }
3569
3570
        $params->id = (int) $params->id;
3571
3572
		// Save terms for taxonomies associated to a post type
3573
        if ( 0 < $params->id && 'post_type' == $pod[ 'type' ] && !empty( $post_term_data ) ) {
3574
			foreach ( $post_term_data as $post_taxonomy => $post_terms ) {
3575
                $post_terms = (array) $post_terms;
3576
3577
                foreach ( $post_terms as $k => $v ) {
3578
                    if ( ! preg_match( '/[^0-9]/', $v ) ) {
3579
                        $v = (int) $v;
3580
                    }
3581
3582
                    $post_terms[ $k ] = $v;
3583
                }
3584
3585
				wp_set_object_terms( $params->id, $post_terms, $post_taxonomy );
3586
			}
3587
		}
3588
3589
        $no_conflict = pods_no_conflict_check( $pod[ 'type' ] );
3590
3591
        if ( !$no_conflict )
3592
            pods_no_conflict_on( $pod[ 'type' ] );
3593
3594
        // Save relationship / file data
3595
        if ( !empty( $rel_fields ) ) {
3596
            foreach ( $rel_fields as $type => $data ) {
3597
                // Only handle tableless fields
3598
                if ( !in_array( $type, $tableless_field_types ) ) {
3599
                    continue;
3600
				}
3601
3602
                foreach ( $data as $field => $values ) {
3603
                    $pick_val = pods_var( 'pick_val', $fields[ $field ] );
3604
3605
                    if ( 'table' == pods_var( 'pick_object', $fields[ $field ] ) ) {
3606
                        $pick_val = pods_var( 'pick_table', $fields[ $field ][ 'options' ], $pick_val, null, true );
3607
					}
3608
3609 View Code Duplication
                    if ( '__current__' == $pick_val ) {
3610
                        if ( is_object( $pod ) ) {
3611
                            $pick_val = $pod->pod;
3612
						}
3613
                        elseif ( is_array( $pod ) ) {
3614
                            $pick_val = $pod[ 'name' ];
3615
						}
3616
                        elseif ( 0 < strlen( $pod ) ) {
3617
                            $pick_val = $pod;
3618
						}
3619
                    }
3620
3621
                    $fields[ $field ][ 'options' ][ 'table_info' ] = pods_api()->get_table_info( pods_var( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ][ 'options' ] );
3622
3623
                    if ( isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && !empty( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] ) ) {
3624
						$search_data = pods( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] );
3625
3626
						$data_mode = 'pods';
3627
                    }
3628
					else {
3629
						$search_data = pods_data();
3630
						$search_data->table( $fields[ $field ][ 'options' ][ 'table_info' ] );
3631
3632
						$data_mode = 'data';
3633
					}
3634
3635
					$find_rel_params = array(
3636
						'select' => "`t`.`{$search_data->field_id}`",
3637
						'where' => "`t`.`{$search_data->field_slug}` = %s OR `t`.`{$search_data->field_index}` = %s",
3638
						'limit' => 1,
3639
						'pagination' => false,
3640
						'search' => false
3641
					);
3642
3643
					if ( empty( $search_data->field_slug ) && !empty( $search_data->field_index ) ) {
3644
						$find_rel_params[ 'where' ] = "`t`.`{$search_data->field_index}` = %s";
3645
					}
3646
					elseif ( empty( $search_data->field_slug ) && empty( $search_data->field_index ) ) {
3647
						$find_rel_params = false;
3648
					}
3649
3650
                    $related_limit = (int) pods_var_raw( $type . '_limit', $fields[ $field ][ 'options' ], 0 );
3651
3652 View Code Duplication
                    if ( 'single' == pods_var_raw( $type . '_format_type', $fields[ $field ][ 'options' ] ) ) {
3653
                        $related_limit = 1;
3654
					}
3655
3656
                    // Enforce integers / unique values for IDs
3657
                    $value_ids = array();
3658
3659
					$is_file_field = in_array( $type, PodsForm::file_field_types() );
3660
					$is_taggable = ( in_array( $type, PodsForm::tableless_field_types() ) && 1 == pods_v( $type . '_taggable', $fields[ $field ][ 'options' ] ) );
3661
3662
					// @todo Handle simple relationships eventually
3663
                    foreach ( $values as $v ) {
3664
                        if ( !empty( $v ) ) {
3665
							if ( !is_array( $v ) ) {
3666
								if ( !preg_match( '/[^0-9]/', $v ) ) {
3667
									$v = (int) $v;
3668
								}
3669
								// File handling
3670
								elseif ( $is_file_field ) {
3671
									// Get ID from GUID
3672
									$v = pods_image_id_from_field( $v );
3673
3674
									// If file not found, add it
3675
									if ( empty( $v ) ) {
3676
										$v = pods_attachment_import( $v );
3677
									}
3678
								}
3679
								// Reference by slug
3680
								else {
3681
									$v_data = false;
3682
3683
									if ( false !== $find_rel_params ) {
3684
										$rel_params = $find_rel_params;
3685
										$rel_params[ 'where' ] = $wpdb->prepare( $rel_params[ 'where' ], array( $v, $v ) );
3686
3687
										$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...
3688
3689
										$v_data = $search_data->fetch( $v );
3690
									}
3691
3692
									if ( !empty( $v_data ) && isset( $v_data[ $search_data->field_id ] ) ) {
3693
										$v = (int) $v_data[ $search_data->field_id ];
3694
									}
3695
									// Allow tagging for Pods objects
3696
									elseif ( $is_taggable && 'pods' == $data_mode ) {
3697
										$tag_data = array(
3698
											$search_data->field_index => $v
3699
										);
3700
3701
										if ( 'post_type' == $search_data->pod_data[ 'type' ] ) {
3702
											$tag_data[ 'post_status' ] = 'publish';
3703
										}
3704
3705
										/**
3706
										 * Filter for changing tag before adding new item.
3707
										 *
3708
										 * @param array $tag_data Fields for creating new item.
3709
										 * @param int $v Field ID of tag.
3710
										 * @param obj $search_data Search object for tag.
3711
										 * @param string $field Table info for field.
3712
										 * @param array	$pieces Field array.
3713
										 *
3714
										 * @since 2.3.19
3715
										 */
3716
										$tag_data = apply_filters( 'pods_api_save_pod_item_taggable_data', $tag_data, $v, $search_data, $field, compact( $pieces ) );
3717
3718
										// Save $v to a new item on related object
3719
										$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...
3720
3721
										// @todo Support non-Pods for tagging
3722
									}
3723
								}
3724
							}
3725
							elseif ( $is_file_field && isset( $v[ 'id' ] ) ) {
3726
								$v = (int) $v[ 'id' ];
3727
							}
3728
							else {
3729
								continue;
3730
							}
3731
3732
							if ( !empty( $v ) && !in_array( $v, $value_ids ) ) {
3733
								$value_ids[] = $v;
3734
							}
3735
                        }
3736
                    }
3737
3738
                    $value_ids = array_unique( array_filter( $value_ids ) );
3739
3740
                    // Limit values
3741
                    if ( 0 < $related_limit && !empty( $value_ids ) )
3742
                        $value_ids = array_slice( $value_ids, 0, $related_limit );
3743
3744
                    // Get current values
3745
                    if ( 'pick' == $type && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ] ) )
3746
                        $related_ids = PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ];
3747
                    else
3748
                        $related_ids = $this->lookup_related_items( $fields[ $field ][ 'id' ], $pod[ 'id' ], $params->id, $fields[ $field ], $pod );
3749
3750
                    // Get ids to remove
3751
                    $remove_ids = array_diff( $related_ids, $value_ids );
3752
3753
                    // Delete relationships
3754
                    if ( !empty( $remove_ids ) )
3755
                        $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] );
3756
3757
                    // Save relationships
3758
                    if ( !empty( $value_ids ) )
3759
                        $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] );
3760
3761
                    // Run save function for field type (where needed)
3762
                    PodsForm::save( $type, $values, $params->id, $field, array_merge( $fields[ $field ], $fields[ $field ][ 'options' ] ), array_merge( $fields, $object_fields ), $pod, $params );
3763
                }
3764
3765
                // Unset data no longer needed
3766
                if ( 'pick' == $type ) {
3767
                    foreach ( $data as $field => $values ) {
3768
                        if ( isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) ) {
3769
                            unset( PodsField_Pick::$related_data[ PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'related_field' ][ 'id' ] ] );
3770
                            unset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] );
3771
                        }
3772
                    }
3773
                }
3774
            }
3775
        }
3776
3777
        if ( !$no_conflict )
3778
            pods_no_conflict_off( $pod[ 'type' ] );
3779
3780
        if ( false === $bypass_helpers ) {
3781
            $pieces = compact( $pieces );
3782
3783
            // Plugin hooks
3784
            $this->do_hook( 'post_save_pod_item', $pieces, $is_new_item, $params->id );
3785
            $this->do_hook( "post_save_pod_item_{$params->pod}", $pieces, $is_new_item, $params->id );
3786
3787
            if ( $is_new_item ) {
3788
                $this->do_hook( 'post_create_pod_item', $pieces, $params->id );
3789
                $this->do_hook( "post_create_pod_item_{$params->pod}", $pieces, $params->id );
3790
            }
3791
            else {
3792
                $this->do_hook( 'post_edit_pod_item', $pieces, $params->id );
3793
                $this->do_hook( "post_edit_pod_item_{$params->pod}", $pieces, $params->id );
3794
            }
3795
3796
            // Call any post-save helpers (if not bypassed)
3797
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3798 View Code Duplication
                if ( !empty( $post_save_helpers ) ) {
3799
                    pods_deprecated( sprintf( __( 'Post-save helpers are deprecated, use the action pods_post_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3800
3801
                    foreach ( $post_save_helpers as $helper ) {
3802
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3803
3804
                        if ( false !== $helper && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
3805
                            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...
3806
                    }
3807
                }
3808
            }
3809
        }
3810
3811
        // Clear cache
3812
        pods_cache_clear( $params->id, 'pods_items_' . $pod[ 'name' ] );
3813
3814
		if ( $params->clear_slug_cache && !empty( $pod[ 'field_slug' ] ) ) {
3815
			$slug = pods( $pod[ 'name' ], $params->id )->field( $pod[ 'field_slug' ] );
3816
3817
			if ( 0 < strlen( $slug ) ) {
3818
        		pods_cache_clear( $slug, 'pods_items_' . $pod[ 'name' ] );
3819
			}
3820
		}
3821
3822
        // Clear WP meta cache
3823
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3824
            $meta_type = $pod[ 'type' ];
3825
3826
            if ( 'post_type' == $meta_type )
3827
                $meta_type = 'post';
3828
3829
            wp_cache_delete( $params->id, $meta_type . '_meta' );
3830
            wp_cache_delete( $params->id, 'pods_' . $meta_type . '_meta' );
3831
        }
3832
3833
        // Success! Return the id
3834
        return $params->id;
3835
3836
    }
3837
3838
    /**
3839
     * @see PodsAPI::save_pod_item
3840
     * Add multiple pod items
3841
     *
3842
     * $params['pod'] string The Pod name (pod or pod_id is required)
3843
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
3844
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
3845
     *
3846
     * $data['id'] int The item ID (optional)
3847
     * $data['data'] array An associative array of field names + values
3848
     *
3849
     * @param array|object $params An associative array of parameters, data excluded
3850
     * @param array $data An associative array of pod ids and field names + values (arrays of field data)
3851
     *
3852
     * @return int The item ID
3853
     * @since 2.0
3854
     */
3855
    public function save_pod_items ( $params, $data ) {
3856
        $params = (object) $params;
3857
3858
        $ids = array();
3859
3860
        foreach ( $data as $fields ) {
3861
            $params->data = $fields;
3862
3863
            if ( isset( $fields[ 'id' ] ) && isset( $fields[ 'data' ] ) ) {
3864
                $params->id = $fields[ 'id' ];
3865
                $params->data = $fields[ 'data' ];
3866
            }
3867
3868
            $ids[] = $this->save_pod_item( $params );
3869
        }
3870
3871
        return $ids;
3872
    }
3873
3874
	/**
3875
	 * Get the fields that have changed during a save
3876
	 *
3877
	 * @param array $pieces Pieces array from save_pod_item
3878
	 *
3879
	 * @return array Array of fields and values that have changed
3880
	 */
3881
	public function get_changed_fields( $pieces ) {
3882
3883
		$fields = $pieces[ 'fields' ];
3884
		$fields_active = $pieces[ 'fields_active' ];
3885
3886
		$fields_changed = array();
3887
3888
		if ( 0 < $pieces[ 'params' ]->id ) {
3889
			$pod = pods( $pieces[ 'params' ]->pod, $pieces[ 'params' ]->id );
3890
3891
			foreach ( $fields_active as $field ) {
3892
				if ( isset( $fields[ $field ] ) && $pod->raw( $field ) != $fields[ $field ][ 'value' ] ) {
3893
					$fields_changed[ $field ] = $fields[ $field ][ 'value' ];
3894
				}
3895
			}
3896
		}
3897
3898
		return $fields_changed;
3899
3900
	}
3901
3902
    /**
3903
     * Save relationships
3904
     *
3905
     * @param int $id ID of item
3906
     * @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...
3907
     * @param array $pod Pod data
3908
     * @param array $field Field data
3909
     */
3910
    public function save_relationships ( $id, $related_ids, $pod, $field ) {
3911
        // Get current values
3912
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ] ) )
3913
            $current_ids = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ];
3914
        else
3915
            $current_ids = $this->lookup_related_items( $field[ 'id' ], $pod[ 'id' ], $id, $field, $pod );
3916
3917
        if ( !is_array( $related_ids ) )
3918
            $related_ids = implode( ',', $related_ids );
3919
3920
        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...
3921
            $related_ids[ $k ] = (int) $related_id;
3922
        }
3923
3924
        $related_ids = array_unique( array_filter( $related_ids ) );
3925
3926
        $related_limit = (int) pods_var_raw( $field[ 'type' ] . '_limit', $field[ 'options' ], 0 );
3927
3928 View Code Duplication
        if ( 'single' == pods_var_raw( $field[ 'type' ] . '_format_type', $field[ 'options' ] ) )
3929
            $related_limit = 1;
3930
3931
        // Limit values
3932
        if ( 0 < $related_limit && !empty( $related_ids ) )
3933
            $related_ids = array_slice( $related_ids, 0, $related_limit );
3934
3935
        // Post Types, Media, Users, and Comments (meta-based)
3936 View Code Duplication
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3937
            $object_type = $pod[ 'type' ];
3938
3939
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
3940
                $object_type = 'post';
3941
            elseif ( 'taxonomy' == $object_type )
3942
                $object_type = 'term';
3943
3944
            delete_metadata( $object_type, $id, $field[ 'name' ] );
3945
3946
            if ( !empty( $related_ids ) ) {
3947
                update_metadata( $object_type, $id, '_pods_' . $field[ 'name' ], $related_ids );
3948
3949
                foreach ( $related_ids as $related_id ) {
3950
                    add_metadata( $object_type, $id, $field[ 'name' ], $related_id );
3951
                }
3952
            }
3953
            else
3954
                delete_metadata( $object_type, $id, '_pods_' . $field[ 'name' ] );
3955
        }
3956
        // Custom Settings Pages (options-based)
3957
        elseif ( 'settings' == $pod[ 'type' ] ) {
3958
            if ( !empty( $related_ids ) )
3959
                update_option( $pod[ 'name' ] . '_' . $field[ 'name' ], $related_ids );
3960
            else
3961
                delete_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
3962
        }
3963
3964
        $related_pod_id = $related_field_id = 0;
3965
3966
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && !empty( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ] ) ) {
3967
            $related_pod_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_pod' ][ 'id' ];
3968
            $related_field_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ][ 'id' ];
3969
        }
3970
3971
        // Relationships table
3972
        if ( !pods_tableless() ) {
3973
            $related_weight = 0;
3974
3975
            foreach ( $related_ids as $related_id ) {
3976
                if ( in_array( $related_id, $current_ids ) ) {
3977
                    pods_query( "
3978
                        UPDATE `@wp_podsrel`
3979
                        SET
3980
                            `pod_id` = %d,
3981
                            `field_id` = %d,
3982
                            `item_id` = %d,
3983
                            `related_pod_id` = %d,
3984
                            `related_field_id` = %d,
3985
                            `related_item_id` = %d,
3986
                            `weight` = %d
3987
                        WHERE
3988
                            `pod_id` = %d
3989
                            AND `field_id` = %d
3990
                            AND `item_id` = %d
3991
                            AND `related_item_id` = %d
3992
                    ", array(
3993
                        $pod[ 'id' ],
3994
                        $field[ 'id' ],
3995
                        $id,
3996
                        $related_pod_id,
3997
                        $related_field_id,
3998
                        $related_id,
3999
                        $related_weight,
4000
4001
                        $pod[ 'id' ],
4002
                        $field[ 'id' ],
4003
                        $id,
4004
                        $related_id,
4005
                    ) );
4006
                }
4007
                else {
4008
                    pods_query( "
4009
                        INSERT INTO `@wp_podsrel`
4010
                            (
4011
                                `pod_id`,
4012
                                `field_id`,
4013
                                `item_id`,
4014
                                `related_pod_id`,
4015
                                `related_field_id`,
4016
                                `related_item_id`,
4017
                                `weight`
4018
                            )
4019
                        VALUES ( %d, %d, %d, %d, %d, %d, %d )
4020
                    ", array(
4021
                        $pod[ 'id' ],
4022
                        $field[ 'id' ],
4023
                        $id,
4024
                        $related_pod_id,
4025
                        $related_field_id,
4026
                        $related_id,
4027
                        $related_weight
4028
                    ) );
4029
                }
4030
4031
                $related_weight++;
4032
            }
4033
        }
4034
    }
4035
4036
    /**
4037
     * Duplicate a Pod
4038
     *
4039
     * $params['id'] int The Pod ID
4040
     * $params['name'] string The Pod name
4041
     * $params['new_name'] string The new Pod name
4042
     *
4043
     * @param array $params An associative array of parameters
4044
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4045
     *
4046
     * @return int New Pod ID
4047
     * @since 2.3
4048
     */
4049
    public function duplicate_pod ( $params, $strict = false ) {
4050 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4051
            if ( is_numeric( $params ) )
4052
                $params = array( 'id' => $params );
4053
            else
4054
                $params = array( 'name' => $params );
4055
4056
            $params = (object) pods_sanitize( $params );
4057
        }
4058
        else
4059
            $params = (object) pods_sanitize( $params );
4060
4061
        $params->table_info = false;
4062
4063
        $pod = $this->load_pod( $params, $strict );
4064
4065
        if ( empty( $pod ) ) {
4066
            if ( false !== $strict )
4067
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4068
4069
            return false;
4070
        }
4071
        elseif ( in_array( $pod[ 'type' ], array( 'media', 'user', 'comment' ) ) ) {
4072
            if ( false !== $strict )
4073
                return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this );
4074
4075
            return false;
4076
        }
4077
        elseif ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod[ 'object' ] ) ) {
4078
			$pod[ 'object' ] = '';
4079
        }
4080
4081
        unset( $pod[ 'id' ] );
4082
4083
        if ( isset( $params->new_name ) )
4084
            $pod[ 'name' ] = $params->new_name;
4085
4086
        $try = 1;
4087
4088
        $check_name = $pod[ 'name' ];
4089
        $new_label = $pod[ 'label' ];
4090
4091 View Code Duplication
        while ( $this->load_pod( array( 'name' => $check_name, 'table_info' => false ), false ) ) {
4092
            $try++;
4093
4094
            $check_name = $pod[ 'name' ] . $try;
4095
            $new_label = $pod[ 'label' ] . $try;
4096
        }
4097
4098
        $pod[ 'name' ] = $check_name;
4099
        $pod[ 'label' ] = $new_label;
4100
4101
        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
4102
            unset( $pod[ 'fields' ][ $field ][ 'id' ] );
4103
        }
4104
4105
        return $this->save_pod( $pod );
4106
    }
4107
4108
    /**
4109
     * Duplicate a Field
4110
     *
4111
     * $params['pod_id'] int The Pod ID
4112
     * $params['pod'] string The Pod name
4113
     * $params['id'] int The Field ID
4114
     * $params['name'] string The Field name
4115
     * $params['new_name'] string The new Field name
4116
     *
4117
     * @param array $params An associative array of parameters
4118
     * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error
4119
     *
4120
     * @return int New Field ID
4121
     * @since 2.3.10
4122
     */
4123
	public function duplicate_field( $params, $strict = false ) {
4124
4125
		if ( !is_object( $params ) && !is_array( $params ) ) {
4126
			if ( is_numeric( $params ) ) {
4127
				$params = array( 'id' => $params );
4128
			}
4129
			else {
4130
				$params = array( 'name' => $params );
4131
			}
4132
		}
4133
4134
		$params = (object) pods_sanitize( $params );
4135
4136
		$params->table_info = false;
4137
4138
		$field = $this->load_field( $params, $strict );
4139
4140
		if ( empty( $field ) ) {
4141
			if ( false !== $strict ) {
4142
				return pods_error( __( 'Field not found', 'pods' ), $this );
4143
			}
4144
4145
			return false;
4146
		}
4147
4148
		unset( $field[ 'id' ] );
4149
4150
		if ( isset( $params->new_name ) ) {
4151
			$field[ 'name' ] = $params->new_name;
4152
		}
4153
4154
		$try = 1;
4155
4156
		$check_name = $field[ 'name' ];
4157
		$new_label = $field[ 'label' ];
4158
4159 View Code Duplication
		while ( $this->load_field( array( 'pod_id' => $field[ 'pod_id' ], 'name' => $check_name, 'table_info' => false ), false ) ) {
4160
			$try++;
4161
4162
			$check_name = $field[ 'name' ] . $try;
4163
			$new_label = $field[ 'label' ] . $try;
4164
		}
4165
4166
		$field[ 'name' ] = $check_name;
4167
		$field[ 'label' ] = $new_label;
4168
4169
		return $this->save_field( $field );
4170
4171
	}
4172
4173
    /**
4174
     * @see PodsAPI::save_pod_item
4175
     *
4176
     * Duplicate a pod item
4177
     *
4178
     * $params['pod'] string The Pod name
4179
     * $params['id'] int The item's ID from the wp_pods_* table
4180
     *
4181
     * @param array $params An associative array of parameters
4182
     *
4183
     * @return int The table row ID
4184
     * @since 1.12
4185
     */
4186
    public function duplicate_pod_item ( $params ) {
4187
        $params = (object) pods_sanitize( $params );
4188
4189
        $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ) );
4190
4191
        if ( false === $pod )
4192
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4193
4194
        $pod = pods( $params->pod, $params->id );
4195
4196
        $params->pod = $pod->pod;
4197
        $params->pod_id = $pod->pod_id;
4198
4199
        $fields = (array) pods_var_raw( 'fields', $pod->pod_data, array(), null, true );
4200
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4201
4202
        if ( !empty( $object_fields ) )
4203
            $fields = array_merge( $object_fields, $fields );
4204
4205
        $save_params = array(
4206
            'pod' => $params->pod,
4207
            'data' => array()
4208
        );
4209
4210
        foreach ( $fields as $field ) {
4211
            $value = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'ids' ) );
4212
4213
            if ( !empty( $value ) || ( !is_array( $value ) && 0 < strlen( $value ) ) )
4214
                $save_params[ 'data' ][ $field[ 'name' ] ] = $value;
4215
        }
4216
4217
        $save_params = $this->do_hook( 'duplicate_pod_item', $save_params, $pod->pod, $pod->id(), $params );
4218
4219
        $id = $this->save_pod_item( $save_params );
4220
4221
        return $id;
4222
    }
4223
4224
    /**
4225
     * @see pods()
4226
     *
4227
     * Export a pod item
4228
     *
4229
     * $params['pod'] string The Pod name
4230
     * $params['id'] int The item's ID from the wp_pods_* table
4231
     * $params['fields'] array The fields to export
4232
     * $params['depth'] int How many levels deep to export data
4233
     *
4234
     * @param array $params An associative array of parameters
4235
     * @param object $pod (optional) Pods object
4236
     *
4237
     * @return int The table row ID
4238
     * @since 1.12
4239
     */
4240
    public function export_pod_item ( $params, $pod = null ) {
4241
        if ( !is_object( $pod ) || 'Pods' != get_class( $pod ) ) {
4242
            if ( empty( $params ) )
4243
                return false;
4244
4245
            $params = (object) pods_sanitize( $params );
4246
4247
            $pod = pods( $params->pod, $params->id, false );
4248
4249
            if ( empty( $pod ) )
4250
                return false;
4251
        }
4252
4253
        $fields = (array) pods_var_raw( 'fields', $params, array(), null, true );
4254
        $depth = (int) pods_var_raw( 'depth', $params, 2, null, true );
4255
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4256
        $flatten = (boolean) pods_var( 'flatten', $params, false, null, true );
4257
4258
        if ( empty( $fields ) ) {
4259
            $fields = $pod->fields;
4260
            $fields = array_merge( $fields, $object_fields );
4261
        }
4262
4263
        $data = $this->export_pod_item_level( $pod, $fields, $depth, $flatten );
4264
4265
        $data = $this->do_hook( 'export_pod_item', $data, $pod->pod, $pod->id(), $pod, $fields, $depth, $flatten );
4266
4267
        return $data;
4268
    }
4269
4270
    /**
4271
     * Export a pod item by depth level
4272
     *
4273
     * @param Pods $pod Pods object
4274
     * @param array $fields Fields to export
4275
     * @param int $depth Depth limit
4276
     * @param boolean $flatten Whether to flatten arrays for display
4277
     * @param int $current_depth Current depth level
4278
     *
4279
     * @return array Data array
4280
     *
4281
     * @since 2.3
4282
     */
4283
    private function export_pod_item_level ( $pod, $fields, $depth, $flatten = false, $current_depth = 1 ) {
4284
        $tableless_field_types = PodsForm::tableless_field_types();
4285
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4286
4287
        $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4288
4289
        $export_fields = array();
4290
4291
        foreach ( $fields as $k => $field ) {
4292
            if ( !is_array( $field ) ) {
4293
                $field = array(
4294
                    'id' => 0,
4295
                    'name' => $field
4296
                );
4297
            }
4298
4299
            if ( isset( $pod->fields[ $field[ 'name' ] ] ) ) {
4300
                $field = $pod->fields[ $field[ 'name' ] ];
4301
                $field[ 'lookup_name' ] = $field[ 'name' ];
4302
4303
                if ( in_array( $field[ 'type' ], $tableless_field_types ) && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4304
                    if ( 'pick' == $field[ 'type' ] ) {
4305
                        if ( empty( $field[ 'table_info' ] ) )
4306
                            $field[ 'table_info' ] = $this->get_table_info( pods_var_raw( 'pick_object', $field ), pods_var_raw( 'pick_val', $field ), null, null, $field );
4307
4308
                        if ( !empty( $field[ 'table_info' ] ) )
4309
                            $field[ 'lookup_name' ] .= '.' . $field[ 'table_info' ][ 'field_id' ];
4310
                    }
4311
                    elseif ( in_array( $field[ 'type' ], PodsForm::file_field_types() ) )
4312
                        $field[ 'lookup_name' ] .= '.guid';
4313
                }
4314
4315
                $export_fields[ $field[ 'name' ] ] = $field;
4316
            }
4317
            elseif ( isset( $object_fields[ $field[ 'name' ] ] ) ) {
4318
                $field = $object_fields[ $field[ 'name' ] ];
4319
                $field[ 'lookup_name' ] = $field[ 'name' ];
4320
4321
                $export_fields[ $field[ 'name' ] ] = $field;
4322
            }
4323
            elseif ( $field[ 'name' ] == $pod->pod_data[ 'field_id' ] ) {
4324
                $field[ 'type' ] = 'number';
4325
                $field[ 'lookup_name' ] = $field[ 'name' ];
4326
4327
                $export_fields[ $field[ 'name' ] ] = $field;
4328
            }
4329
        }
4330
4331
        $data = array();
4332
4333
        foreach ( $export_fields as $field ) {
4334
            // Return IDs (or guid for files) if only one level deep
4335
            if ( 1 == $depth )
4336
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'lookup_name' ], 'output' => 'arrays' ) );
4337
            // Recurse depth levels for pick fields if $depth allows
4338
            elseif ( ( -1 == $depth || $current_depth < $depth ) && 'pick' == $field[ 'type' ] && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4339
                $related_data = array();
4340
4341
                $related_ids = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'ids' ) );
4342
4343
                if ( !empty( $related_ids ) ) {
4344
                    $related_ids = (array) $related_ids;
4345
4346
                    $pick_object = pods_var_raw( 'pick_object', $field );
4347
4348
                    $related_pod = pods( pods_var_raw( 'pick_val', $field ), null, false );
4349
4350
                    // If this isn't a Pod, return data exactly as Pods does normally
4351
                    if ( empty( $related_pod ) || ( 'pod' != $pick_object && $pick_object != $related_pod->pod_data[ 'type' ] ) || $related_pod->pod == $pod->pod )
4352
                        $related_data = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4353
                    else {
4354
                        $related_object_fields = (array) pods_var_raw( 'object_fields', $related_pod->pod_data, array(), null, true );
4355
4356
                        $related_fields = array_merge( $related_pod->fields, $related_object_fields );
4357
4358
                        foreach ( $related_ids as $related_id ) {
4359
                            if ( $related_pod->fetch( $related_id ) ) {
4360
                                $related_item = $this->export_pod_item_level( $related_pod, $related_fields, $depth, $flatten, ( $current_depth + 1 ) );
4361
4362
                                $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 ) );
4363
                            }
4364
                        }
4365
4366
                        if ( $flatten && !empty( $related_data ) )
4367
                            $related_data = pods_serial_comma( array_values( $related_data ), array( 'and' => '', 'field_index' => $related_pod->pod_data[ 'field_index' ] ) );
4368
                    }
4369
                }
4370
4371
                $data[ $field[ 'name' ] ] = $related_data;
4372
            }
4373
            // Return data exactly as Pods does normally
4374
            else
4375
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4376
4377
            if ( $flatten && is_array( $data[ $field[ 'name' ] ] ) )
4378
                $data[ $field[ 'name' ] ] = pods_serial_comma( $data[ $field[ 'name' ] ], array( 'field' => $field[ 'name' ], 'fields' => $export_fields, 'and' => '' ) );
4379
        }
4380
4381
	$data[ 'id' ] = (int) $pod->id();
4382
        return $data;
4383
    }
4384
4385
    /**
4386
     * Reorder a Pod
4387
     *
4388
     * $params['pod'] string The Pod name
4389
     * $params['field'] string The field name of the field to reorder
4390
     * $params['order'] array The key => value array of items to reorder (key should be an integer)
4391
     *
4392
     * @param array $params An associative array of parameters
4393
     *
4394
     * @return bool
4395
     *
4396
     * @since 1.9.0
4397
     */
4398
    public function reorder_pod_item ( $params ) {
4399
        $params = (object) pods_sanitize( $params );
4400
4401
        // @deprecated 2.0
4402
        if ( isset( $params->datatype ) ) {
4403
            pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4404
4405
            $params->pod = $params->datatype;
4406
4407
            unset( $params->datatype );
4408
        }
4409
4410
        if ( null === pods_var_raw( 'pod', $params, null, null, true ) )
4411
            return pods_error( __( '$params->pod is required', 'pods' ), $this );
4412
4413
        if ( !is_array( $params->order ) )
4414
            $params->order = explode( ',', $params->order );
4415
4416
        $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
4417
4418
        $params->name = $pod[ 'name' ];
4419
4420
        if ( false === $pod )
4421
            return pods_error( __( 'Pod is required', 'pods' ), $this );
4422
4423
        foreach ( $params->order as $order => $id ) {
4424
            if ( isset( $pod[ 'fields' ][ $params->field ] ) || isset( $pod[ 'object_fields' ][ $params->field ] ) ) {
4425
                if ( 'table' == $pod[ 'storage' ] && ( !pods_tableless() ) ) {
4426
                    if ( isset( $pod[ 'fields' ][ $params->field ] ) )
4427
                        pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" );
4428
                    else
4429
                        pods_query( "UPDATE `{$pod['table']}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `{$pod['field_id']}` = " . pods_absint( $id ) . " LIMIT 1" );
4430
                }
4431
                else
4432
                    $this->save_pod_item( array( 'pod' => $params->pod, 'pod_id' => $params->pod_id, 'id' => $id, 'data' => array( $params->field => pods_absint( $order ) ) ) );
4433
            }
4434
        }
4435
4436
        return true;
4437
    }
4438
4439
    /**
4440
     *
4441
     * Delete all content for a Pod
4442
     *
4443
     * $params['id'] int The Pod ID
4444
     * $params['name'] string The Pod name
4445
     *
4446
     * @param array $params An associative array of parameters
4447
     * @param array $pod Pod data
4448
     *
4449
     * @return bool
4450
     *
4451
     * @uses pods_query
4452
     * @uses pods_cache_clear
4453
     *
4454
     * @since 1.9.0
4455
     */
4456
    public function reset_pod ( $params, $pod = false ) {
4457
        $params = (object) pods_sanitize( $params );
4458
4459
        $params->table_info = true;
4460
4461
        if ( empty( $pod ) )
4462
            $pod = $this->load_pod( $params );
4463
4464
        if ( false === $pod )
4465
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4466
4467
        $params->id = $pod[ 'id' ];
4468
        $params->name = $pod[ 'name' ];
4469
4470 View Code Duplication
        if ( !pods_tableless() ) {
4471
            if ( 'table' == $pod[ 'storage' ] ) {
4472
                try {
4473
                    pods_query( "TRUNCATE `@wp_pods_{$params->name}`", false );
4474
                }
4475
                catch ( Exception $e ) {
4476
                    // Allow pod to be reset if the table doesn't exist
4477
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4478
                        return pods_error( $e->getMessage(), $this );
4479
                }
4480
            }
4481
4482
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4483
        }
4484
4485
        // @todo Delete relationships from tableless relationships
4486
4487
        // Delete all posts/revisions from this post type
4488
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media' ) ) ) {
4489
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4490
4491
            $sql = "
4492
                DELETE `t`, `r`, `m`
4493
                FROM `{$pod['table']}` AS `t`
4494
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4495
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4496
                LEFT JOIN `{$pod['table']}` AS `r`
4497
                    ON `r`.`post_parent` = `t`.`{$pod['field_id']}` AND `r`.`post_status` = 'inherit'
4498
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4499
            ";
4500
4501
            pods_query( $sql, false );
4502
        }
4503
        // Delete all terms from this taxonomy
4504
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
4505
            if ( function_exists( 'get_term_meta' ) ) {
4506
                $sql = "
4507
                    DELETE `t`, `m`, `tt`, `tr`
4508
                    FROM `{$pod['table']}` AS `t`
4509
                    LEFT JOIN `{$pod['meta_table']}` AS `m`
4510
                        ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4511
                    " . $pod['join']['tt'] . "
4512
                    " . $pod['join']['tr'] . "
4513
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4514
                ";
4515
            } else {
4516
                $sql = "
4517
                    DELETE `t`, `tt`, `tr`
4518
                    FROM `{$pod['table']}` AS `t`
4519
                    " . $pod['join']['tt'] . "
4520
                    " . $pod['join']['tr'] . "
4521
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4522
                ";
4523
            }
4524
4525
            pods_query( $sql, false );
4526
        }
4527
        // Delete all users except the current one
4528
        elseif ( 'user' == $pod[ 'type' ] ) {
4529
            $sql = "
4530
                DELETE `t`, `m`
4531
                FROM `{$pod['table']}` AS `t`
4532
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4533
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4534
                WHERE `t`.`{$pod['field_id']}` != " . (int) get_current_user_id() . "
4535
            ";
4536
4537
            pods_query( $sql, false );
4538
        }
4539
        // Delete all comments
4540
        elseif ( 'comment' == $pod[ 'type' ] ) {
4541
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4542
4543
            $sql = "
4544
                DELETE `t`, `m`
4545
                FROM `{$pod['table']}` AS `t`
4546
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4547
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4548
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4549
            ";
4550
4551
            pods_query( $sql, false );
4552
        }
4553
4554
        pods_cache_clear( true ); // only way to reliably clear out cached data across an entire group
4555
4556
        return true;
4557
    }
4558
4559
    /**
4560
     * Delete a Pod and all its content
4561
     *
4562
     * $params['id'] int The Pod ID
4563
     * $params['name'] string The Pod name
4564
     *
4565
     * @param array $params An associative array of parameters
4566
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4567
     * @param bool $delete_all (optional) Whether to delete all content from a WP object
4568
     *
4569
     * @uses PodsAPI::load_pod
4570
     * @uses wp_delete_post
4571
     * @uses pods_query
4572
     *
4573
     * @return bool
4574
     * @since 1.7.9
4575
     */
4576
    public function delete_pod ( $params, $strict = false, $delete_all = false ) {
4577
        /**
4578
         * @var $wpdb wpdb
4579
         */
4580
        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...
4581
4582 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4583
            if ( is_numeric( $params ) )
4584
                $params = array( 'id' => $params );
4585
            else
4586
                $params = array( 'name' => $params );
4587
4588
            $params = (object) pods_sanitize( $params );
4589
        }
4590
        else
4591
            $params = (object) pods_sanitize( $params );
4592
4593
        $params->table_info = false;
4594
4595
        $pod = $this->load_pod( $params, $strict );
4596
4597
        if ( empty( $pod ) ) {
4598
            if ( false !== $strict )
4599
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4600
4601
            return false;
4602
        }
4603
4604
        $params->id = (int) $pod[ 'id' ];
4605
        $params->name = $pod[ 'name' ];
4606
4607
        foreach ( $pod[ 'fields' ] as $field ) {
4608
            $field[ 'pod' ] = $pod;
4609
4610
            $this->delete_field( $field, false );
4611
        }
4612
4613
        // Only delete the post once the fields are taken care of, it's not required anymore
4614
        $success = wp_delete_post( $params->id );
4615
4616
        if ( !$success )
4617
            return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this );
4618
4619
        // Reset content
4620
        if ( $delete_all )
4621
            $this->reset_pod( $params, $pod );
4622
4623 View Code Duplication
        if ( !pods_tableless() ) {
4624
            if ( 'table' == $pod[ 'storage' ] ) {
4625
                try {
4626
                    pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false );
4627
                }
4628
                catch ( Exception $e ) {
4629
                    // Allow pod to be deleted if the table doesn't exist
4630
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4631
                        return pods_error( $e->getMessage(), $this );
4632
                }
4633
            }
4634
4635
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4636
        }
4637
4638
        // @todo Delete relationships from tableless relationships
4639
4640
        // Delete any relationship references
4641
        $sql = "
4642
            DELETE `pm`
4643
            FROM `{$wpdb->postmeta}` AS `pm`
4644
            LEFT JOIN `{$wpdb->posts}` AS `p`
4645
                ON `p`.`post_type` = '_pods_field'
4646
                    AND `p`.`ID` = `pm`.`post_id`
4647
            LEFT JOIN `{$wpdb->postmeta}` AS `pm2`
4648
                ON `pm2`.`meta_key` = 'pick_object'
4649
                    AND `pm2`.`meta_value` = 'pod'
4650
                    AND `pm2`.`post_id` = `pm`.`post_id`
4651
            WHERE
4652
                `p`.`ID` IS NOT NULL
4653
                AND `pm2`.`meta_id` IS NOT NULL
4654
                AND `pm`.`meta_key` = 'pick_val'
4655
                AND `pm`.`meta_value` = '{$params->name}'
4656
        ";
4657
4658
        pods_query( $sql );
4659
4660
        $this->cache_flush_pods( $pod );
4661
4662
        return true;
4663
    }
4664
4665
    /**
4666
     * Drop a field within a Pod
4667
     *
4668
     * $params['id'] int The field ID
4669
     * $params['name'] int The field name
4670
     * $params['pod'] string The Pod name
4671
     * $params['pod_id'] string The Pod name
4672
     *
4673
     * @param array $params An associative array of parameters
4674
     * @param bool $table_operation Whether or not to handle table operations
4675
     *
4676
     * @uses PodsAPI::load_field
4677
     * @uses wp_delete_post
4678
     * @uses pods_query
4679
     *
4680
     * @return bool
4681
     * @since 1.7.9
4682
     */
4683
    public function delete_field ( $params, $table_operation = true ) {
4684
        /**
4685
         * @var $wpdb wpdb
4686
         */
4687
        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...
4688
4689
        $tableless_field_types = PodsForm::tableless_field_types();
4690
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4691
4692
        $params = (object) pods_sanitize( $params );
4693
4694
        if ( !isset( $params->pod ) )
4695
            $params->pod = '';
4696
4697
        if ( !isset( $params->pod_id ) )
4698
            $params->pod_id = 0;
4699
4700
        $pod = $params->pod;
4701
4702
        $save_pod = false;
4703
4704
        if ( !is_array( $pod ) )
4705
            $pod = $this->load_pod( array( 'name' => $pod, 'id' => $params->pod_id, 'table_info' => false ) );
4706
        else
4707
            $save_pod = true;
4708
4709
        if ( empty( $pod ) )
4710
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4711
4712
        $params->pod_id = $pod[ 'id' ];
4713
        $params->pod = $pod[ 'name' ];
4714
4715
        if ( !isset( $params->name ) )
4716
            $params->name = '';
4717
4718
        if ( !isset( $params->id ) )
4719
            $params->id = 0;
4720
4721
        $field = $this->load_field( array( 'name' => $params->name, 'id' => $params->id, 'pod' => $params->pod, 'pod_id' => $params->pod_id ) );
4722
4723
        if ( false === $field )
4724
            return pods_error( __( 'Field not found', 'pods' ), $this );
4725
4726
        $params->id = $field[ 'id' ];
4727
        $params->name = $field[ 'name' ];
4728
4729
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
4730
        $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params );
4731
4732
        if ( $table_operation && 'table' == $pod[ 'storage' ] && ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) )
4733
            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false );
4734
4735
        $success = wp_delete_post( $params->id );
4736
4737
        if ( !$success )
4738
            return pods_error( __( 'Field unable to be deleted', 'pods' ), $this );
4739
4740
        $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm
4741
            LEFT JOIN {$wpdb->posts} AS p
4742
                ON p.post_type = '_pods_field' AND p.ID = pm.post_id
4743
            WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) );
4744
4745
        if ( ( !pods_tableless() ) && $table_operation ) {
4746
            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 );
4747
        }
4748
4749
        // @todo Delete tableless relationship meta
4750
4751
        if ( true === $save_pod )
4752
            $this->cache_flush_pods( $pod );
4753
4754
        return true;
4755
    }
4756
4757
    /**
4758
     * Drop a Pod Object
4759
     *
4760
     * $params['id'] int The object ID
4761
     * $params['name'] string The object name
4762
     * $params['type'] string The object type
4763
     *
4764
     * @param array|object $params An associative array of parameters
4765
     *
4766
     * @uses wp_delete_post
4767
     *
4768
     * @return bool
4769
     * @since 2.0
4770
     */
4771
    public function delete_object ( $params ) {
4772
        $params = (object) $params;
4773
        $object = $this->load_object( $params );
4774
4775 View Code Duplication
        if ( empty( $object ) )
4776
            return pods_error( sprintf( __( "%s Object not found", 'pods' ), ucwords( $params->type ) ), $this );
4777
4778
        $success = wp_delete_post( $params->id );
4779
4780 View Code Duplication
        if ( !$success )
4781
            return pods_error( sprintf( __( "%s Object not deleted", 'pods' ), ucwords( $params->type ) ), $this );
4782
4783
        pods_transient_clear( 'pods_objects_' . $params->type );
4784
4785
        return true;
4786
    }
4787
4788
    /**
4789
     * @see PodsAPI::delete_object
4790
     *
4791
     * Drop a Pod Template
4792
     *
4793
     * $params['id'] int The template ID
4794
     * $params['name'] string The template name
4795
     *
4796
     * @param array $params An associative array of parameters
4797
     *
4798
     * @return bool
4799
     * @since 1.7.9
4800
     */
4801
    public function delete_template ( $params ) {
4802
        $params = (object) $params;
4803
        $params->type = 'template';
4804
        return $this->delete_object( $params );
4805
    }
4806
4807
    /**
4808
     * @see PodsAPI::delete_object
4809
     *
4810
     * Drop a Pod Page
4811
     *
4812
     * $params['id'] int The page ID
4813
     * $params['uri'] string The page URI
4814
     *
4815
     * @param array $params An associative array of parameters
4816
     *
4817
     * @return bool
4818
     * @since 1.7.9
4819
     */
4820
    public function delete_page ( $params ) {
4821
        $params = (object) $params;
4822
        if ( isset( $params->uri ) ) {
4823
            $params->name = $params->uri;
4824
            unset( $params->uri );
4825
        }
4826
        if ( isset( $params->name ) )
4827
            $params->name = trim( $params->name, '/' );
4828
        $params->type = 'page';
4829
        return $this->delete_object( $params );
4830
    }
4831
4832
    /**
4833
     * @see PodsAPI::delete_object
4834
     *
4835
     * Drop a Pod Helper
4836
     *
4837
     * $params['id'] int The helper ID
4838
     * $params['name'] string The helper name
4839
     *
4840
     * @param array $params An associative array of parameters
4841
     *
4842
     * @return bool
4843
     * @since 1.7.9
4844
     */
4845
    public function delete_helper ( $params ) {
4846
        $params = (object) $params;
4847
        $params->type = 'helper';
4848
        return $this->delete_object( $params );
4849
    }
4850
4851
    /**
4852
     * Drop a single pod item
4853
     *
4854
     * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter)
4855
     * $params['pod'] string (optional) The Pod name (used with id parameter)
4856
     * $params['pod_id'] int (optional) The Pod ID (used with id parameter)
4857
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
4858
     *
4859
     * @param array $params An associative array of parameters
4860
     * @param bool $wp Whether to run WP object delete action
4861
     *
4862
     * @return bool
4863
     * @since 1.7.9
4864
     */
4865
    public function delete_pod_item ( $params, $wp = true ) {
4866
        $params = (object) pods_sanitize( $params );
4867
4868
        // @deprecated 2.0
4869
        if ( isset( $params->datatype_id ) || isset( $params->datatype ) || isset( $params->tbl_row_id ) ) {
4870
            if ( isset( $params->tbl_row_id ) ) {
4871
                pods_deprecated( __( '$params->id instead of $params->tbl_row_id', 'pods' ), '2.0' );
4872
                $params->id = $params->tbl_row_id;
4873
                unset( $params->tbl_row_id );
4874
            }
4875
4876 View Code Duplication
            if ( isset( $params->pod_id ) ) {
4877
                pods_deprecated( __( '$params->id instead of $params->pod_id', 'pods' ), '2.0' );
4878
                $params->id = $params->pod_id;
4879
                unset( $params->pod_id );
4880
            }
4881
4882 View Code Duplication
            if ( isset( $params->dataype_id ) ) {
4883
                pods_deprecated( __( '$params->pod_id instead of $params->datatype_id', 'pods' ), '2.0' );
4884
                $params->pod_id = $params->dataype_id;
4885
                unset( $params->dataype_id );
4886
            }
4887
4888
            if ( isset( $params->datatype ) ) {
4889
                pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4890
                $params->pod = $params->datatype;
4891
                unset( $params->datatype );
4892
            }
4893
        }
4894
4895
        if ( !isset( $params->id ) )
4896
            return pods_error( __( 'Pod Item not found', 'pods' ), $this );
4897
4898
        $params->id = pods_absint( $params->id );
4899
4900
        if ( !isset( $params->pod ) )
4901
            $params->pod = '';
4902
4903
        if ( !isset( $params->pod_id ) )
4904
            $params->pod_id = 0;
4905
4906
        $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ) );
4907
4908
        if ( false === $pod )
4909
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4910
4911
        $params->pod_id = $pod[ 'id' ];
4912
        $params->pod = $pod[ 'name' ];
4913
4914
        // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls
4915
        $bypass_helpers = false;
4916
4917
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
4918
            $bypass_helpers = true;
4919
4920
        $pre_delete_helpers = $post_delete_helpers = array();
4921
4922
        if ( false === $bypass_helpers ) {
4923
            // Plugin hook
4924
            $this->do_hook( 'pre_delete_pod_item', $params, $pod );
4925
            $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod );
4926
4927
            // Call any pre-save helpers (if not bypassed)
4928 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
4929
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
4930
                    $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' );
4931
4932
                    foreach ( $helpers as $helper ) {
4933
                        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...
4934
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
4935
                    }
4936
                }
4937
4938
                if ( !empty( $pre_delete_helpers ) ) {
4939
                    pods_deprecated( sprintf( __( 'Pre-delete helpers are deprecated, use the action pods_pre_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
4940
4941
                    foreach ( $pre_delete_helpers as $helper ) {
4942
                        $helper = $this->load_helper( array( 'name' => $helper ) );
4943
4944
                        if ( false !== $helper )
4945
                            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...
4946
                    }
4947
                }
4948
            }
4949
        }
4950
4951
        // Delete object from relationship fields
4952
        $this->delete_object_from_relationships( $params->id, $pod );
4953
4954
        if ( 'table' == $pod[ 'storage' ] )
4955
            pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" );
4956
4957
        if ( $wp ) {
4958
            if ( 'taxonomy' == $pod['type'] ) {
4959
                $taxonomy = $pod['name'];
4960
4961
                if ( ! empty( $pod['object'] ) ) {
4962
                    $taxonomy = $pod['object'];
4963
                }
4964
4965
                wp_delete_term( $params->id, $taxonomy );
4966
            } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) {
4967
                $this->delete_wp_object( $pod['type'], $params->id );
4968
            }
4969
        }
4970
4971
        if ( false === $bypass_helpers ) {
4972
            // Plugin hook
4973
            $this->do_hook( 'post_delete_pod_item', $params, $pod );
4974
            $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod );
4975
4976
            // Call any post-save helpers (if not bypassed)
4977 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
4978
                if ( !empty( $post_delete_helpers ) ) {
4979
                    pods_deprecated( sprintf( __( 'Post-delete helpers are deprecated, use the action pods_post_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
4980
4981
                    foreach ( $post_delete_helpers as $helper ) {
4982
                        $helper = $this->load_helper( array( 'name' => $helper ) );
4983
4984
                        if ( false !== $helper )
4985
                            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...
4986
                    }
4987
                }
4988
            }
4989
        }
4990
4991
        pods_cache_clear( $params->id, 'pods_items_' . $params->pod );
4992
4993
        return true;
4994
    }
4995
4996
    /**
4997
     * Delete an object from tableless fields
4998
     *
4999
     * @param int $id
5000
     * @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...
5001
     * @param string $name
5002
     *
5003
     * @return bool
5004
     *
5005
     * @since 2.3
5006
     */
5007
    public function delete_object_from_relationships ( $id, $object, $name = null ) {
5008
        /**
5009
         * @var $pods_init \PodsInit
5010
         */
5011
        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...
5012
5013
        $pod = false;
5014
5015
        // Run any bidirectional delete operations
5016
        if ( is_array( $object ) )
5017
            $pod = $object;
5018
        elseif ( is_object( $pods_init ) )
5019
            $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...
5020
5021
        if ( !empty( $pod ) ) {
5022
            $object = $pod[ 'type' ];
5023
            $name = $pod[ 'name' ];
5024
5025
            foreach ( $pod[ 'fields' ] as $field ) {
5026
                PodsForm::delete( $field[ 'type' ], $id, $field[ 'name' ], array_merge( $field, $field[ 'options' ] ), $pod );
5027
            }
5028
        }
5029
5030
        // Lookup related fields (non-bidirectional)
5031
        $params = array(
5032
            'where' => array(
5033
                array(
5034
                    'key' => 'type',
5035
                    'value' => 'pick'
5036
                ),
5037
                array(
5038
                    'key' => 'pick_object',
5039
                    'value' => $object
5040
                )
5041
            )
5042
        );
5043
5044
        if ( !empty( $name ) && $name != $object ) {
5045
            $params[ 'where' ][] = array(
5046
                'key' => 'pick_val',
5047
                'value' => $name
5048
            );
5049
        }
5050
5051
        $fields = $this->load_fields( $params, false );
5052
5053
        if ( !empty( $pod ) && 'media' == $pod[ 'type' ] ) {
5054
            $params[ 'where' ] = array(
5055
                array(
5056
                    'key' => 'type',
5057
                    'value' => 'file'
5058
                )
5059
            );
5060
5061
            $fields = array_merge( $fields, $this->load_fields( $params, false ) );
5062
        }
5063
5064
        if ( is_array( $fields ) && !empty( $fields ) ) {
5065
            foreach ( $fields as $related_field ) {
5066
                $related_pod = $this->load_pod( array( 'id' => $related_field[ 'pod_id' ], 'fields' => false ), false );
5067
5068
                if ( empty( $related_pod ) )
5069
                    continue;
5070
5071
                $related_from = $this->lookup_related_items_from( $related_field[ 'id' ], $related_pod[ 'id' ], $id, $related_field, $related_pod );
5072
5073
                $this->delete_relationships( $related_from, $id, $related_pod, $related_field );
5074
            }
5075
        }
5076
5077
        if ( !empty( $pod ) && !pods_tableless() ) {
5078
            pods_query( "
5079
                DELETE FROM `@wp_podsrel`
5080
                WHERE
5081
                (
5082
                    `pod_id` = %d
5083
                    AND `item_id` = %d
5084
                )
5085
                OR (
5086
                    `related_pod_id` = %d
5087
                    AND `related_item_id` = %d
5088
                )
5089
            ", array(
5090
                $pod[ 'id' ],
5091
                $id,
5092
5093
                $pod[ 'id' ],
5094
                $id
5095
            ) );
5096
        }
5097
5098
        return true;
5099
    }
5100
5101
    /**
5102
     * Delete relationships
5103
     *
5104
     * @param int|array $related_id IDs for items to save
5105
     * @param int|array $id ID or IDs to remove
5106
     * @param array $related_pod Pod data
5107
     * @param array $related_field Field data
5108
     *
5109
     * @return void
5110
     *
5111
     * @since 2.3
5112
     */
5113
    public function delete_relationships ( $related_id, $id, $related_pod, $related_field ) {
5114
        if ( is_array( $related_id ) ) {
5115
            foreach ( $related_id as $rid ) {
5116
                $this->delete_relationships( $rid, $id, $related_pod, $related_field );
5117
            }
5118
5119
            return;
5120
        }
5121
5122
        if ( is_array( $id ) ) {
5123
            foreach ( $id as $rid ) {
5124
                $this->delete_relationships( $related_id, $rid, $related_pod, $related_field );
5125
            }
5126
5127
            return;
5128
        }
5129
5130
        $id = (int) $id;
5131
5132
        if ( empty( $id ) )
5133
            return;
5134
5135
        $related_ids = $this->lookup_related_items( $related_field[ 'id' ], $related_pod[ 'id' ], $related_id, $related_field, $related_pod );
5136
5137
        if ( empty( $related_ids ) )
5138
            return;
5139
        elseif ( !in_array( $id, $related_ids ) )
5140
            return;
5141
5142
	    if ( isset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] ) ) {
5143
		    // Delete relationship from cache
5144
		    unset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] );
5145
	    }
5146
        unset( $related_ids[ array_search( $id, $related_ids ) ] );
5147
5148
        $no_conflict = pods_no_conflict_check( $related_pod[ 'type' ] );
5149
5150
        if ( !$no_conflict )
5151
            pods_no_conflict_on( $related_pod[ 'type' ] );
5152
5153
        // Post Types, Media, Users, and Comments (meta-based)
5154 View Code Duplication
        if ( in_array( $related_pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
5155
            $object_type = $related_pod[ 'type' ];
5156
5157
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
5158
                $object_type = 'post';
5159
            elseif ( 'taxonomy' == $object_type )
5160
                $object_type = 'term';
5161
5162
            delete_metadata( $object_type, $related_id, $related_field[ 'name' ] );
5163
5164
            if ( !empty( $related_ids ) ) {
5165
                update_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ], $related_ids );
5166
5167
                foreach ( $related_ids as $rel_id ) {
5168
                    add_metadata( $object_type, $related_id, $related_field[ 'name' ], $rel_id );
5169
                }
5170
            }
5171
            else
5172
                delete_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ] );
5173
        }
5174
        // Custom Settings Pages (options-based)
5175
        elseif ( 'settings' == $related_pod[ 'type' ] ) {
5176
            if ( !empty( $related_ids ) )
5177
                update_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ], $related_ids );
5178
            else
5179
                delete_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ] );
5180
        }
5181
5182
        // Relationships table
5183
        if ( !pods_tableless() ) {
5184
            pods_query( "
5185
                DELETE FROM `@wp_podsrel`
5186
                WHERE
5187
                (
5188
                    `pod_id` = %d
5189
                    AND `field_id` = %d
5190
                    AND `item_id` = %d
5191
                    AND `related_item_id` = %d
5192
                )
5193
                OR (
5194
                    `related_pod_id` = %d
5195
                    AND `related_field_id` = %d
5196
                    AND `related_item_id` = %d
5197
                    AND `item_id` = %d
5198
                )
5199
            ", array(
5200
                $related_pod[ 'id' ],
5201
                $related_field[ 'id' ],
5202
                $related_id,
5203
                $id,
5204
5205
                $related_pod[ 'id' ],
5206
                $related_field[ 'id' ],
5207
                $related_id,
5208
                $id
5209
            ) );
5210
        }
5211
5212
        if ( !$no_conflict )
5213
            pods_no_conflict_off( $related_pod[ 'type' ] );
5214
    }
5215
5216
    /**
5217
     * Check if a Pod exists
5218
     *
5219
     * $params['id'] int Pod ID
5220
     * $params['name'] string Pod name
5221
     *
5222
     * @param array $params An associative array of parameters
5223
     *
5224
     * @return bool True if exists
5225
     *
5226
     * @since 1.12
5227
     */
5228
    public function pod_exists ( $params, $type = null ) {
5229
        if ( is_string( $params ) )
5230
            $params = array( 'name' => $params );
5231
5232
        $params = (object) pods_sanitize( $params );
5233
5234
        if ( !empty( $params->id ) || !empty( $params->name ) ) {
5235 View Code Duplication
            if ( !isset( $params->name ) )
5236
                $pod = get_post( $dummy = (int) $params->id );
5237
            else {
5238
                $pod = get_posts( array(
5239
                    'name' => $params->name,
5240
                    'post_type' => '_pods_pod',
5241
                    'posts_per_page' => 1
5242
                ) );
5243
            }
5244
5245
            if ( !empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) )
5246
                return true;
5247
        }
5248
5249
        return false;
5250
    }
5251
5252
    /**
5253
     * Load a Pod and all of its fields
5254
     *
5255
     * $params['id'] int The Pod ID
5256
     * $params['name'] string The Pod name
5257
     * $params['fields'] bool Whether to load fields (default is true)
5258
     *
5259
     * @param array|object $params An associative array of parameters or pod name as a string
5260
     * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work
5261
     *
5262
     * @return array|bool|mixed|void
5263
     * @since 1.7.9
5264
     */
5265
    public function load_pod ( $params, $strict = true ) {
5266
5267
        /**
5268
         * @var $sitepress SitePress
5269
		 * @var $wpdb wpdb
5270
         */
5271
        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...
5272
5273
        $current_language = false;
5274
        $load_fields = true;
5275
5276
	    // Get current language data
5277
		$lang_data = self::get_current_language();
5278
5279
	    if ( $lang_data ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $lang_data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
5280
		    if ( ! empty( $lang_data['language'] ) ) {
5281
			    $current_language = $lang_data['language'];
5282
		    }
5283
	    }
5284
5285
        if ( !is_array( $params ) && !is_object( $params ) )
5286
            $params = array( 'name' => $params, 'table_info' => false, 'fields' => true );
5287
5288
        if ( is_object( $params ) && isset( $params->fields ) && !$params->fields )
5289
            $load_fields = false;
5290
        elseif ( is_array( $params ) && isset( $params[ 'fields' ] ) && !$params[ 'fields' ] )
5291
            $load_fields = false;
5292
5293
	    $table_info = false;
5294
5295
        if ( is_object( $params ) && ! empty( $params->table_info ) )
5296
            $table_info = true;
5297
        elseif ( is_array( $params ) && ! empty( $params[ 'table_info' ] ) )
5298
            $table_info = true;
5299
5300
        $transient = 'pods_' . $wpdb->prefix . '_pod';
5301
5302
        if ( !empty( $current_language ) )
5303
            $transient .= '_' . $current_language;
5304
5305
        if ( !$load_fields )
5306
            $transient .= '_nofields';
5307
5308
        if ( $table_info )
5309
            $transient .= '_tableinfo';
5310
5311
        if ( is_object( $params ) && isset( $params->post_name ) ) {
5312
            $pod = false;
5313
5314
            if ( pods_api_cache() )
5315
                $pod = pods_transient_get( $transient . '_' . $params->post_name );
5316
5317 View Code Duplication
            if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5318
	            // @todo Is this needed anymore for WPML?
5319
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
5320
                    $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5321
5322
                return $pod;
5323
            }
5324
5325
            $_pod = get_object_vars( $params );
5326
        }
5327
        else {
5328
            $params = (object) pods_sanitize( $params );
5329
5330 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) ) {
5331
                if ( $strict )
5332
                    return pods_error( 'Either Pod ID or Name are required', $this );
5333
5334
                return false;
5335
            }
5336
5337
            if ( isset( $params->name ) ) {
5338
                $pod = false;
5339
5340
				if ( '_pods_pod' == $params->name ) {
5341
					$pod = array(
5342
						'id' => 0,
5343
						'name' => $params->name,
5344
						'label' => __( 'Pods', 'pods' ),
5345
						'type' => 'post_type',
5346
						'storage' => 'meta',
5347
						'options' => array(
5348
							'label_singular' => __( 'Pod', 'pods' )
5349
						),
5350
						'fields' => array()
5351
					);
5352
				}
5353
				elseif ( '_pods_field' == $params->name ) {
5354
					$pod = array(
5355
						'id' => 0,
5356
						'name' => $params->name,
5357
						'label' => __( 'Pod Fields', 'pods' ),
5358
						'type' => 'post_type',
5359
						'storage' => 'meta',
5360
						'options' => array(
5361
							'label_singular' => __( 'Pod Field', 'pods' )
5362
						),
5363
						'fields' => array()
5364
					);
5365
				}
5366
                elseif ( pods_api_cache() )
5367
                    $pod = pods_transient_get( $transient . '_' . $params->name );
5368
5369 View Code Duplication
                if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5370
                    if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
5371
                        $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5372
5373
                    return $pod;
5374
                }
5375
            }
5376
5377 View Code Duplication
            if ( !isset( $params->name ) )
5378
                $pod = get_post( $dummy = (int) $params->id );
5379
            else {
5380
                $pod = get_posts( array(
5381
                    'name' => $params->name,
5382
                    'post_type' => '_pods_pod',
5383
                    'posts_per_page' => 1
5384
                ) );
5385
            }
5386
5387
            if ( empty( $pod ) ) {
5388
                if ( $strict )
5389
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
5390
5391
                return false;
5392
            }
5393
5394
            if ( is_array( $pod ) )
5395
                $pod = $pod[ 0 ];
5396
5397
            $_pod = get_object_vars( $pod );
5398
        }
5399
5400
        $pod = false;
5401
5402
        if ( pods_api_cache() )
5403
            $pod = pods_transient_get( $transient . '_' . $_pod[ 'post_name' ] );
5404
5405 View Code Duplication
        if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5406
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && is_object( $sitepress ) && !$icl_adjust_id_url_filter_off )
5407
                $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5408
5409
            return $pod;
5410
        }
5411
5412
        $pod = array(
5413
            'id' => $_pod[ 'ID' ],
5414
            'name' => $_pod[ 'post_name' ],
5415
            'label' => $_pod[ 'post_title' ],
5416
            'description' => $_pod[ 'post_content' ]
5417
        );
5418
5419
        if ( strlen( $pod[ 'label' ] ) < 1 )
5420
            $pod[ 'label' ] = $pod[ 'name' ];
5421
5422
        // @todo update with a method to put all options in
5423
        $defaults = array(
5424
            'show_in_menu' => 1,
5425
            'type' => 'post_type',
5426
            'storage' => 'meta',
5427
            'object' => '',
5428
            'alias' => ''
5429
        );
5430
5431
        $pod[ 'options' ] = get_post_meta( $pod[ 'id' ] );
5432
5433 View Code Duplication
        foreach ( $pod[ 'options' ] as $option => $value ) {
5434
            if ( is_array( $value ) ) {
5435
                foreach ( $value as $k => $v ) {
5436
                    if ( !is_array( $v ) )
5437
                        $value[ $k ] = maybe_unserialize( $v );
5438
                }
5439
5440
                if ( 1 == count( $value ) )
5441
                    $value = current( $value );
5442
            }
5443
            else
5444
                $value = maybe_unserialize( $value );
5445
5446
            $pod[ 'options' ][ $option ] = $value;
5447
        }
5448
5449
        $pod[ 'options' ] = array_merge( $defaults, $pod[ 'options' ] );
5450
5451
        $pod[ 'type' ] = $pod[ 'options' ][ 'type' ];
5452
        $pod[ 'storage' ] = $pod[ 'options' ][ 'storage' ];
5453
        $pod[ 'object' ] = $pod[ 'options' ][ 'object' ];
5454
        $pod[ 'alias' ] = $pod[ 'options' ][ 'alias' ];
5455
5456
        unset( $pod[ 'options' ][ 'type' ] );
5457
        unset( $pod[ 'options' ][ 'storage' ] );
5458
        unset( $pod[ 'options' ][ 'object' ] );
5459
        unset( $pod[ 'options' ][ 'alias' ] );
5460
5461
        if ( $table_info )
5462
            $pod = array_merge( $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ), $pod );
5463
5464
        // Override old 'none' storage type
5465 View Code Duplication
        if ( 'taxonomy' == $pod['type'] && 'none' == $pod['storage'] && function_exists( 'get_term_meta' ) ) {
5466
            $pod[ 'storage' ] = 'meta';
5467
        }
5468
5469
        if ( isset( $pod[ 'pod' ] ) )
5470
            unset( $pod[ 'pod' ] );
5471
5472
        $pod[ 'fields' ] = array();
5473
5474
        $pod[ 'object_fields' ] = array();
5475
5476
        if ( 'pod' != $pod[ 'type' ] )
5477
            $pod[ 'object_fields' ] = $this->get_wp_object_fields( $pod[ 'type' ], $pod );
5478
5479
        $fields = get_posts( array(
5480
            'post_type' => '_pods_field',
5481
            'posts_per_page' => -1,
5482
            'nopaging' => true,
5483
            'post_parent' => $pod[ 'id' ],
5484
            'orderby' => 'menu_order',
5485
            'order' => 'ASC'
5486
        ) );
5487
5488
        if ( !empty( $fields ) ) {
5489
            foreach ( $fields as $field ) {
5490
                $field->pod = $pod[ 'name' ];
5491
                $field->table_info = $table_info;
5492
5493
                if ( $load_fields ) {
5494
                    $field = $this->load_field( $field );
5495
5496
                    $field = PodsForm::field_setup( $field, null, $field[ 'type' ] );
5497
                }
5498
                else {
5499
                    $field = array(
5500
                        'id' => $field->ID,
5501
                        'name' => $field->post_name,
5502
                        'label' => $field->post_title,
5503
                        'type' => get_post_meta( $field->ID, 'type', true )
5504
                    );
5505
                }
5506
5507
                $pod[ 'fields' ][ $field[ 'name' ] ] = $field;
5508
            }
5509
        }
5510
5511 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
5512
            pods_transient_set( $transient . '_' . $pod[ 'name' ], $pod );
5513
5514
        return $pod;
5515
    }
5516
5517
    /**
5518
     * Load a list of Pods based on filters specified.
5519
     *
5520
     * $params['type'] string/array Pod Type(s) to filter by
5521
     * $params['object'] string/array Pod Object(s) to filter by
5522
     * $params['options'] array Pod Option(s) key=>value array to filter by
5523
     * $params['orderby'] string ORDER BY clause of query
5524
     * $params['limit'] string Number of Pods to return
5525
     * $params['where'] string WHERE clause of query
5526
     * $params['ids'] string|array IDs of Objects
5527
     * $params['count'] boolean Return only a count of Pods
5528
     * $params['names'] boolean Return only an array of name => label
5529
     * $params['ids'] boolean Return only an array of ID => label
5530
     * $params['fields'] boolean Return pod fields with Pods (default is true)
5531
     * $params['key_names'] boolean Return pods keyed by name
5532
     *
5533
     * @param array $params An associative array of parameters
5534
     *
5535
     * @return array|mixed
5536
     *
5537
     * @uses PodsAPI::load_pod
5538
     *
5539
     * @since 2.0
5540
     */
5541
    public function load_pods ( $params = null ) {
5542
5543
        $current_language = false;
5544
5545
	    // Get current language data
5546
		$lang_data = self::get_current_language();
5547
5548
	    if ( $lang_data ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $lang_data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
5549
		    if ( ! empty( $lang_data['language'] ) ) {
5550
			    $current_language = $lang_data['language'];
5551
		    }
5552
	    }
5553
5554
        $params = (object) pods_sanitize( $params );
5555
5556
        $order = 'ASC';
5557
        $orderby = 'menu_order title';
5558
        $limit = -1;
5559
        $ids = false;
5560
5561
        $meta_query = array();
5562
        $cache_key = '';
5563
5564
        if ( isset( $params->type ) && !empty( $params->type ) ) {
5565
            if ( !is_array( $params->type ) )
5566
                $params->type = array( trim( $params->type ) );
5567
5568
            sort( $params->type );
5569
5570
            $meta_query[] = array(
5571
                'key' => 'type',
5572
                'value' => $params->type,
5573
                'compare' => 'IN'
5574
            );
5575
5576
            if ( 0 < count( $params->type ) )
5577
                $cache_key .= '_type_' . trim( implode( '_', $params->type ) );
5578
        }
5579
5580
        if ( isset( $params->object ) && !empty( $params->object ) ) {
5581
            if ( !is_array( $params->object ) )
5582
                $params->object = array( $params->object );
5583
5584
            $params->object = pods_trim( $params->object );
5585
5586
            sort( $params->object );
5587
5588
            $meta_query[] = array(
5589
                'key' => 'object',
5590
                'value' => $params->object,
5591
                'compare' => 'IN'
5592
            );
5593
5594
            if ( 1 == count( $params->object ) )
5595
                $cache_key .= '_object_' . trim( implode( '', $params->object ) );
5596
        }
5597
5598 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
5599
            foreach ( $params->options as $option => $value ) {
5600
                if ( !is_array( $value ) )
5601
                    $value = array( $value );
5602
5603
                $value = pods_trim( $value );
5604
5605
                sort( $value );
5606
5607
                $meta_query[] = array(
5608
                    'key' => $option,
5609
                    'value' => pods_sanitize( $value ),
5610
                    'compare' => 'IN'
5611
                );
5612
            }
5613
5614
            $cache_key = '';
5615
        }
5616
5617
        if ( isset( $params->where ) && is_array( $params->where ) )
5618
            $meta_query = array_merge( $meta_query, (array) $params->where );
5619
5620 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
5621
            $order = strtoupper( $params->order );
5622
5623
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
5624
            $orderby = strtoupper( $params->orderby );
5625
5626
        if ( isset( $params->limit ) && !empty( $params->limit ) )
5627
            $limit = pods_absint( $params->limit );
5628
5629
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
5630
            $ids = $params->ids;
5631
5632
            if ( !is_array( $ids ) )
5633
                $ids = explode( ',', $ids );
5634
        }
5635
5636
        if ( empty( $ids ) )
5637
            $ids = false;
5638
5639
        $pre_key = '';
5640
5641
        if ( !empty( $current_language ) )
5642
            $pre_key .= '_' . $current_language;
5643
5644
        if ( isset( $params->count ) && $params->count )
5645
            $pre_key .= '_count';
5646
5647
        if ( isset( $params->ids ) && $params->ids && !empty( $ids ) )
5648
            $pre_key .= '_ids_' . implode( '_', $ids );
5649
5650
        if ( isset( $params->names ) && $params->names )
5651
            $pre_key .= '_names';
5652
        elseif ( isset( $params->names_ids ) && $params->names_ids )
5653
            $pre_key .= '_names_ids';
5654
5655
        if ( isset( $params->key_names ) && $params->key_names )
5656
            $pre_key .= '_namekeys';
5657
5658
        if ( isset( $params->fields ) && !$params->fields )
5659
            $pre_key .= '_nofields';
5660
5661
        if ( isset( $params->table_info ) && $params->table_info )
5662
            $pre_key .= '_tableinfo';
5663
5664
5665
        $pre_key .= '_get';
5666
5667
        if ( empty( $cache_key ) )
5668
            $cache_key = 'pods' . $pre_key . '_all';
5669
        else
5670
            $cache_key = 'pods' . $pre_key . $cache_key;
5671
5672
        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 ) ) {
5673
            $the_pods = pods_transient_get( $cache_key );
5674
5675
            if ( false === $the_pods )
5676
                $the_pods = pods_cache_get( $cache_key, 'pods' );
5677
5678
            if ( !is_array( $the_pods ) && 'none' == $the_pods )
5679
                return array();
5680
            elseif ( false !== $the_pods )
5681
                return $the_pods;
5682
        }
5683
5684
        $the_pods = array();
5685
5686
		$args = array(
5687
			'post_type' => '_pods_pod',
5688
			'nopaging' => true,
5689
			'posts_per_page' => $limit,
5690
			'order' => $order,
5691
			'orderby' => $orderby,
5692
			'meta_query' => $meta_query,
5693
		);
5694
5695
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
5696
		if ( false != $ids ) {
5697
			$args[ 'post__in' ] = $ids;
5698
		}
5699
5700
		$_pods = get_posts( $args );
5701
5702
        $export_ignore = array(
5703
            'object_type',
5704
            'object_name',
5705
            'table',
5706
            'meta_table',
5707
            'pod_table',
5708
            'field_id',
5709
            'field_index',
5710
            'field_slug',
5711
            'field_type',
5712
            'field_parent',
5713
            'field_parent_select',
5714
            'meta_field_id',
5715
            'meta_field_index',
5716
            'meta_field_value',
5717
            'pod_field_id',
5718
            'pod_field_index',
5719
            'object_fields',
5720
            'join',
5721
            'where',
5722
            'where_default',
5723
            'orderby',
5724
            'pod',
5725
            'recurse',
5726
            'table_info',
5727
            'attributes',
5728
            'group',
5729
            'grouped',
5730
            'developer_mode',
5731
            'dependency',
5732
            'depends-on',
5733
            'excludes-on'
5734
        );
5735
5736
        $total_fields = 0;
5737
5738
        if ( isset( $params->count ) && $params->count )
5739
            $the_pods = count( $_pods );
5740
        else {
5741
            foreach ( $_pods as $pod ) {
5742
                if ( isset( $params->names ) && $params->names )
5743
                    $the_pods[ $pod->post_name ] = $pod->post_title;
5744
                elseif ( isset( $params->names_ids ) && $params->names_ids )
5745
                    $the_pods[ $pod->ID ] = $pod->post_name;
5746
                else {
5747
                    if ( isset( $params->fields ) && !$params->fields )
5748
                        $pod->fields = false;
5749
5750
                    $pod = $this->load_pod( $pod );
5751
5752
                    // Remove extra data not needed
5753
                    if ( pods_var( 'export', $params, false ) && ( !isset( $params->fields ) || $params->fields ) ) {
5754
                        foreach ( $export_ignore as $ignore ) {
5755
                            if ( isset( $pod[ $ignore ] ) )
5756
                                unset( $pod[ $ignore ] );
5757
                        }
5758
5759
                        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
5760
                            if ( isset( $pod[ 'fields' ][ $field ][ 'table_info' ] ) )
5761
                                unset( $pod[ 'fields' ][ $field ][ 'table_info' ] );
5762
                        }
5763
                    }
5764
5765
                    $total_fields += count( $pod[ 'fields' ] );
5766
5767
                    if ( isset( $params->key_names ) && $params->key_names )
5768
                        $the_pods[ $pod[ 'name' ] ] = $pod;
5769
                    else
5770
                        $the_pods[ $pod[ 'id' ] ] = $pod;
5771
                }
5772
            }
5773
        }
5774
5775
        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 ) ) {
5776
            // Too many Pods can cause issues with the DB when caching is not enabled
5777
            if ( 15 < count( $the_pods ) || 75 < count( $total_fields ) ) {
5778
                pods_transient_clear( $cache_key );
5779
5780 View Code Duplication
                if ( pods_api_cache() ) {
5781
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
5782
                        pods_cache_set( $cache_key, 'none', 'pods' );
5783
                    else
5784
                        pods_cache_set( $cache_key, $the_pods, 'pods' );
5785
                }
5786
            }
5787
            else {
5788
                pods_cache_clear( $cache_key, 'pods' );
5789
5790 View Code Duplication
                if ( pods_api_cache() ) {
5791
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
5792
                        pods_transient_set( $cache_key, 'none' );
5793
                    else
5794
                        pods_transient_set( $cache_key, $the_pods );
5795
                }
5796
            }
5797
        }
5798
5799
        return $the_pods;
5800
    }
5801
5802
    /**
5803
     * Check if a Pod's field exists
5804
     *
5805
     * $params['pod_id'] int The Pod ID
5806
     * $params['id'] int The field ID
5807
     * $params['name'] string The field name
5808
     *
5809
     * @param array $params An associative array of parameters
5810
     *
5811
     * @return bool
5812
     *
5813
     * @since 1.12
5814
     */
5815
    public function field_exists ( $params ) {
5816
        $params = (object) pods_sanitize( $params );
5817
5818
        if ( ( !empty( $params->id ) || !empty( $params->name ) ) && isset( $params->pod_id ) && !empty( $params->pod_id ) ) {
5819 View Code Duplication
            if ( !isset( $params->name ) )
5820
                $field = get_post( $dummy = (int) $params->id );
5821
            else {
5822
                $field = get_posts( array(
5823
                    'name' => $params->name,
5824
                    'post_type' => '_pods_field',
5825
                    'posts_per_page' => 1,
5826
                    'post_parent' => $params->pod_id
5827
                ) );
5828
            }
5829
5830
            if ( !empty( $field ) )
5831
                return true;
5832
        }
5833
5834
        return false;
5835
    }
5836
5837
    /**
5838
     * Load a field
5839
     *
5840
     * $params['pod_id'] int The Pod ID
5841
     * $params['pod'] string The Pod name
5842
     * $params['id'] int The field ID
5843
     * $params['name'] string The field name
5844
     * $params['table_info'] boolean Whether to lookup a pick field's table info
5845
     *
5846
     * @param array $params An associative array of parameters
5847
     * @param boolean $strict Whether to require a field exist or not when loading the info
5848
     *
5849
     * @return array|bool Array with field data, false if field not found
5850
     * @since 1.7.9
5851
     */
5852
    public function load_field ( $params, $strict = false ) {
5853
        $params = (object) $params;
5854
5855
        if ( !isset( $params->table_info ) )
5856
            $params->table_info = false;
5857
5858
        $pod = array();
5859
        $field = array();
5860
5861
        if ( isset( $params->post_title ) )
5862
            $_field = $params;
5863
        elseif ( isset( $params->id ) && !empty( $params->id ) )
5864
            $_field = get_post( $dumb = (int) $params->id );
5865
        else {
5866
            if ( !isset( $params->pod ) )
5867
                $params->pod = '';
5868
5869
            if ( !isset( $params->pod_id ) )
5870
                $params->pod_id = 0;
5871
5872
            if ( isset( $params->pod_data ) )
5873
                $pod = $params->pod_data;
5874 View Code Duplication
            else {
5875
                $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ), false );
5876
5877
                if ( false === $pod ) {
5878
                    if ( $strict )
5879
                        return pods_error( __( 'Pod not found', 'pods' ), $this );
5880
5881
                    return false;
5882
                }
5883
            }
5884
5885
            $params->pod_id = $pod[ 'id' ];
5886
            $params->pod = $pod[ 'name' ];
5887
5888 View Code Duplication
            if ( empty( $params->name ) && empty( $params->pod ) && empty( $params->pod_id ) )
5889
                return pods_error( __( 'Either Field Name or Field ID / Pod ID are required', 'pods' ), $this );
5890
5891
            $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
5892
5893
            if ( isset( $pod[ 'fields' ][ $params->name ] ) && isset( $pod[ 'fields' ][ $params->name ][ 'id' ] ) )
5894
                return $pod[ 'fields' ][ $params->name ];
5895
5896
            $field = false;
5897
5898
            if ( pods_api_cache() )
5899
                $field = pods_transient_get( 'pods_field_' . $params->pod . '_' . $params->name );
5900
5901
            if ( empty( $field ) ) {
5902
                $field = get_posts( array(
5903
                    'name' => $params->name,
5904
                    'post_type' => '_pods_field',
5905
                    'posts_per_page' => 1,
5906
                    'post_parent' => $params->pod_id
5907
                ) );
5908
5909
                if ( empty( $field ) ) {
5910
                    if ( $strict )
5911
                        return pods_error( __( 'Field not found', 'pods' ), $this );
5912
5913
                    return false;
5914
                }
5915
5916
                $_field = $field[ 0 ];
5917
5918
                $field = array();
5919
            }
5920
        }
5921
5922
        if ( empty( $_field ) ) {
5923
            if ( $strict )
5924
                return pods_error( __( 'Field not found', 'pods' ), $this );
5925
5926
            return false;
5927
        }
5928
5929
        $_field = get_object_vars( $_field );
5930
5931
        if ( !isset( $pod[ 'name' ] ) && !isset( $_field[ 'pod' ] ) ) {
5932
            if ( 0 < $_field[ 'post_parent' ] )
5933
                $pod = $this->load_pod( array( 'id' => $_field[ 'post_parent' ], 'table_info' => false ), false );
5934
5935
            if ( empty( $pod ) ) {
5936
                if ( $strict )
5937
                    return pods_error( __( 'Pod for field not found', 'pods' ), $this );
5938
5939
                return false;
5940
            }
5941
        }
5942
5943
        if ( empty( $field ) ) {
5944 View Code Duplication
            if ( pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
5945
                $field = pods_transient_get( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $_field[ 'post_name' ] );
5946
5947
            if ( empty( $field ) ) {
5948
                $defaults = array(
5949
                    'type' => 'text'
5950
                );
5951
5952
                $field = array(
5953
                    'id' => $_field[ 'ID' ],
5954
                    'name' => $_field[ 'post_name' ],
5955
                    'label' => $_field[ 'post_title' ],
5956
                    'description' => $_field[ 'post_content' ],
5957
                    'weight' => $_field[ 'menu_order' ],
5958
                    'pod_id' => $_field[ 'post_parent' ],
5959
                    'pick_object' => '',
5960
                    'pick_val' => '',
5961
                    'sister_id' => '',
5962
                    'table_info' => array()
5963
                );
5964
5965
                if ( isset( $pod[ 'name' ] ) )
5966
                    $field[ 'pod' ] = $pod[ 'name' ];
5967
                elseif ( isset( $_field[ 'pod' ] ) )
5968
                    $field[ 'pod' ] = $_field[ 'pod' ];
5969
5970
                $field[ 'options' ] = get_post_meta( $field[ 'id' ] );
5971
5972
                $options_ignore = array(
5973
                    'method',
5974
                    'table_info',
5975
                    'attributes',
5976
                    'group',
5977
                    'grouped',
5978
                    'developer_mode',
5979
                    'dependency',
5980
                    'depends-on',
5981
                    'excludes-on'
5982
                );
5983
5984
                foreach ( $options_ignore as $ignore ) {
5985
                    if ( isset( $field[ 'options' ][ $ignore ] ) )
5986
                        unset( $field[ 'options' ][ $ignore ] );
5987
                }
5988
5989 View Code Duplication
                foreach ( $field[ 'options' ] as $option => $value ) {
5990
                    if ( is_array( $value ) ) {
5991
                        foreach ( $value as $k => $v ) {
5992
                            if ( !is_array( $v ) )
5993
                                $value[ $k ] = maybe_unserialize( $v );
5994
                        }
5995
5996
                        if ( 1 == count( $value ) )
5997
                            $value = current( $value );
5998
                    }
5999
                    else
6000
                        $value = maybe_unserialize( $value );
6001
6002
                    $field[ 'options' ][ $option ] = $value;
6003
                }
6004
6005
                $field[ 'options' ] = array_merge( $defaults, $field[ 'options' ] );
6006
6007
                $field[ 'type' ] = $field[ 'options' ][ 'type' ];
6008
6009
                unset( $field[ 'options' ][ 'type' ] );
6010
6011 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_object' ] ) ) {
6012
                    $field[ 'pick_object' ] = $field[ 'options' ][ 'pick_object' ];
6013
6014
                    unset( $field[ 'options' ][ 'pick_object' ] );
6015
                }
6016
6017 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_val' ] ) ) {
6018
                    $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_val' ];
6019
6020
                    unset( $field[ 'options' ][ 'pick_val' ] );
6021
                }
6022
6023 View Code Duplication
                if ( isset( $field[ 'options' ][ 'sister_id' ] ) ) {
6024
                    $field[ 'sister_id' ] = $field[ 'options' ][ 'sister_id' ];
6025
6026
                    unset( $field[ 'options' ][ 'sister_id' ] );
6027
                }
6028
6029
                if ( isset( $field[ 'options' ][ 'sister_field_id' ] ) )
6030
                    unset( $field[ 'options' ][ 'sister_field_id' ] );
6031
6032 View Code Duplication
                if ( pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6033
                    pods_transient_set( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $field[ 'name' ], $field );
6034
            }
6035
        }
6036
6037
        $field[ 'table_info' ] = array();
6038
6039
        if ( 'pick' == $field[ 'type' ] && $params->table_info )
6040
            $field[ 'table_info' ] = $this->get_table_info( $field[ 'pick_object' ], $field[ 'pick_val' ], null, null, $field );
6041
6042
        return $field;
6043
    }
6044
6045
    /**
6046
     * Load fields by Pod, ID, Name, and/or Type
6047
     *
6048
     * $params['pod_id'] int The Pod ID
6049
     * $params['pod'] string The Pod name
6050
     * $params['id'] array The field IDs
6051
     * $params['name'] array The field names
6052
     * $params['type'] array The field types
6053
     * $params['options'] array Field Option(s) key=>value array to filter by
6054
     * $params['where'] string WHERE clause of query
6055
     *
6056
     * @param array $params An associative array of parameters
6057
     * @param bool $strict  Whether to require a field exist or not when loading the info
6058
     *
6059
     * @return array Array of field data.
6060
     *
6061
     * @since 1.7.9
6062
     */
6063
    public function load_fields ( $params, $strict = false ) {
6064
		// @todo Get away from using md5/serialize, I'm sure we can cache specific parts
6065
	    $cache_key = md5( serialize( $params  ) );
6066
	    if ( isset( $this->fields_cache[ $cache_key ] ) ) {
6067
		    return $this->fields_cache[ $cache_key ];
6068
	    }
6069
6070
        $params = (object) pods_sanitize( $params );
6071
6072
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6073
            $params->pod = '';
6074
6075
        if ( !isset( $params->pod_id ) || empty( $params->pod_id ) )
6076
            $params->pod_id = 0;
6077
6078 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
6079
            $params->name = array();
6080
        else
6081
            $params->name = (array) $params->name;
6082
6083
        if ( !isset( $params->id ) || empty( $params->id ) )
6084
            $params->id = array();
6085
        else {
6086
            $params->id = (array) $params->id;
6087
6088
            foreach ( $params->id as &$id ) {
6089
                $id = pods_absint( $id );
6090
            }
6091
        }
6092
6093 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6094
            $params->type = array();
6095
        else
6096
            $params->type = (array) $params->type;
6097
6098
        $fields = array();
6099
6100
        if ( !empty( $params->pod ) || !empty( $params->pod_id ) ) {
6101
            $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => true ), false );
6102
6103
            if ( false === $pod ) {
6104
                if ( $strict )
6105
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
6106
6107
                return $fields;
6108
            }
6109
6110
			$pod[ 'fields' ] = array_merge( pods_var_raw( 'object_fields', $pod, array() ), $pod[ 'fields' ] );
6111
6112
            foreach ( $pod[ 'fields' ] as $field ) {
6113
                if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6114
                    $fields[ $field[ 'name' ] ] = $field;
6115
				elseif ( in_array( $fields[ 'name' ], $params->name ) || in_array( $fields[ 'id' ], $params->id ) || in_array( $fields[ 'type' ], $params->type ) )
6116
                    $fields[ $field[ 'name' ] ] = $field;
6117
            }
6118
        }
6119
        elseif ( ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) || ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) ) ) {
6120
            $order = 'ASC';
6121
            $orderby = 'menu_order title';
6122
            $limit = -1;
6123
            $ids = false;
6124
6125
            $meta_query = array();
6126
6127 View Code Duplication
            if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6128
                foreach ( $params->options as $option => $value ) {
6129
                    if ( !is_array( $value ) )
6130
                        $value = array( $value );
6131
6132
                    $value = pods_trim( $value );
6133
6134
                    sort( $value );
6135
6136
                    $meta_query[] = array(
6137
                        'key' => $option,
6138
                        'value' => pods_sanitize( $value ),
6139
                        'compare' => 'IN'
6140
                    );
6141
                }
6142
            }
6143
6144
            if ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) )
6145
                $meta_query = array_merge( $meta_query, (array) $params->where );
6146
6147
			$args = array(
6148
				'post_type' => '_pods_field',
6149
				'nopaging' => true,
6150
				'posts_per_page' => $limit,
6151
				'order' => $order,
6152
				'orderby' => $orderby,
6153
				'meta_query' => $meta_query,
6154
			);
6155
6156
			// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6157
			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...
6158
				$args[ 'post__in' ] = $ids;
6159
			}
6160
6161
            $fields = array();
6162
6163
            $_fields = get_posts( $args );
6164
6165
            foreach ( $_fields as $field ) {
6166
                $field = $this->load_field( $field, false );
6167
6168
                if ( !empty( $field ) )
6169
                    $fields[ $field[ 'id' ] ] = $field;
6170
            }
6171
        }
6172
        else {
6173 View Code Duplication
            if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6174
                return pods_error( __( 'Either Field Name / Field ID / Field Type, or Pod Name / Pod ID are required', 'pods' ), $this );
6175
6176
            $lookup = array();
6177
6178 View Code Duplication
            if ( !empty( $params->name ) ) {
6179
                $fields = implode( "', '", $params->name );
6180
6181
                $lookup[] = "`post_name` IN ( '{$fields}' )";
6182
            }
6183
6184 View Code Duplication
            if ( !empty( $params->id ) ) {
6185
                $fields = implode( ", ", $params->id );
6186
6187
                $lookup[] = "`ID` IN ( {$fields} )";
6188
            }
6189
6190
            $lookup = implode( ' AND ', $lookup );
6191
6192
            $result = pods_query( "SELECT `ID`, `post_name`, `post_parent` FROM `@wp_posts` WHERE `post_type` = '_pods_field' AND ( {$lookup} )" );
6193
6194
            $fields = array();
6195
6196
            if ( !empty( $result ) ) {
6197
                foreach ( $result as $field ) {
6198
					$field = $this->load_field( array(
6199
                        'id' => $field->ID,
6200
                        'name' => $field->post_name,
6201
                        'pod_id' => $field->post_parent
6202
                    ), false );
6203
6204
                    if ( !empty( $field ) && ( empty( $params->type ) || in_array( $field[ 'type' ], $params->type ) ) )
6205
                        $fields[ $field[ 'id' ] ] = $field;
6206
                }
6207
            }
6208
        }
6209
	    if ( isset( $cache_key ) ) {
6210
		    $this->fields_cache[ $cache_key ] = $fields;
6211
	    }
6212
        return $fields;
6213
    }
6214
6215
    /**
6216
     * Load a Pods Object
6217
     *
6218
     * $params['id'] int The Object ID
6219
     * $params['name'] string The Object name
6220
     * $params['type'] string The Object type
6221
     *
6222
     * @param array|object $params An associative array of parameters
6223
     * @param bool $strict
6224
     *
6225
     * @return array|bool
6226
     * @since 2.0
6227
     */
6228
    public function load_object ( $params, $strict = false ) {
6229
        if ( is_object( $params ) && isset( $params->post_title ) )
6230
            $_object = get_object_vars( $params );
6231
        else {
6232
            $params = (object) pods_sanitize( $params );
6233
6234 View Code Duplication
            if ( !isset( $params->type ) || empty( $params->type ) )
6235
                return pods_error( __( 'Object type is required', 'pods' ), $this );
6236
6237 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) )
6238
                return pods_error( __( 'Either Object ID or Name are required', 'pods' ), $this );
6239
6240
            /**
6241
             * @var $wpdb wpdb
6242
             */
6243
            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...
6244
6245
            if ( isset( $params->name ) )
6246
                $_object = pods_by_title( $params->name, ARRAY_A, '_pods_' . $params->type, 'publish' );
6247
            else {
6248
                $object = $params->id;
6249
6250
                $_object = get_post( $object, ARRAY_A );
6251
            }
6252
6253
            if ( empty( $_object ) ) {
6254
                if ( $strict )
6255
                    return pods_error( __( 'Object not found', 'pods' ), $this );
6256
6257
                return false;
6258
            }
6259
        }
6260
6261
        $object = array(
6262
            'id' => $_object[ 'ID' ],
6263
            'name' => $_object[ 'post_title' ],
6264
            'code' => $_object[ 'post_content' ],
6265
            'type' => str_replace( '_pods_', '', $_object[ 'post_type' ] ),
6266
            'slug' => $_object[ 'post_name' ]
6267
        );
6268
6269
        $object[ 'options' ] = get_post_meta( $object[ 'id' ] );
6270
6271
        foreach ( $object[ 'options' ] as $option => &$value ) {
6272
            if ( is_array( $value ) && 1 == count( $value ) )
6273
                $value = current( $value );
6274
        }
6275
6276
        return $object;
6277
    }
6278
6279
    /**
6280
     * Load Multiple Pods Objects
6281
     *
6282
     * $params['type'] string The Object type
6283
     * $params['options'] array Pod Option(s) key=>value array to filter by
6284
     * $params['orderby'] string ORDER BY clause of query
6285
     * $params['limit'] string Number of objects to return
6286
     * $params['where'] string WHERE clause of query
6287
     * $params['ids'] string|array IDs of Objects
6288
     *
6289
     * @param array|object $params An associative array of parameters
6290
     *
6291
     * @return array
6292
     * @since 2.0
6293
     */
6294
    public function load_objects ( $params ) {
6295
        $params = (object) pods_sanitize( $params );
6296
6297 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6298
            return pods_error( __( 'Pods Object type is required', 'pods' ), $this );
6299
6300
        $order = 'ASC';
6301
        $orderby = 'menu_order';
6302
        $limit = -1;
6303
        $ids = false;
6304
6305
        $meta_query = array();
6306
        $cache_key = '';
6307
6308 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6309
            foreach ( $params->options as $option => $value ) {
6310
                if ( !is_array( $value ) )
6311
                    $value = array( $value );
6312
6313
                $value = pods_trim( $value );
6314
6315
                sort( $value );
6316
6317
                $meta_query[] = array(
6318
                    'key' => $option,
6319
                    'value' => pods_sanitize( $value ),
6320
                    'compare' => 'IN'
6321
                );
6322
            }
6323
        }
6324
6325
        if ( isset( $params->where ) && is_array( $params->where ) )
6326
            $meta_query = array_merge( $meta_query, (array) $params->where );
6327
6328 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
6329
            $order = strtoupper( $params->order );
6330
6331
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
6332
            $orderby = strtoupper( $params->orderby );
6333
6334
        if ( isset( $params->limit ) && !empty( $params->limit ) )
6335
            $limit = pods_absint( $params->limit );
6336
6337
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
6338
            $ids = $params->ids;
6339
6340
            if ( !is_array( $ids ) )
6341
                $ids = explode( ',', $ids );
6342
        }
6343
6344
        if ( empty( $ids ) )
6345
            $ids = false;
6346
6347
        if ( pods_api_cache() && empty( $meta_query ) && empty( $limit ) && ( empty( $orderby ) || 'menu_order' == $orderby ) && empty( $ids ) ) {
6348
            $cache_key = 'pods_objects_' . $params->type;
6349
6350
            $the_objects = pods_transient_get( $cache_key );
6351
6352
            if ( false !== $the_objects )
6353
                return $the_objects;
6354
        }
6355
6356
        $the_objects = array();
6357
6358
		$args = array(
6359
			'post_type' => '_pods_' . $params->type,
6360
			'nopaging' => true,
6361
			'posts_per_page' => $limit,
6362
			'order' => $order,
6363
			'orderby' => $orderby,
6364
			'meta_query' => $meta_query,
6365
		);
6366
6367
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6368
		if ( false != $ids ) {
6369
			$args[ 'post__in' ] = $ids;
6370
		}
6371
6372
		$objects = get_posts( $args );
6373
6374
        foreach ( $objects as $object ) {
6375
            $object = $this->load_object( $object );
6376
6377
            $the_objects[ $object[ 'name' ] ] = $object;
6378
        }
6379
6380
        if ( pods_api_cache() && !empty( $cache_key ) )
6381
            pods_transient_set( $cache_key, $the_objects );
6382
6383
        return $the_objects;
6384
    }
6385
6386
    /**
6387
     * @see PodsAPI::load_object
6388
     *
6389
     * Load a Pod Template
6390
     *
6391
     * $params['id'] int The template ID
6392
     * $params['name'] string The template name
6393
     *
6394
     * @param array $params An associative array of parameters
6395
     *
6396
     * @return array|bool
6397
     * @since 1.7.9
6398
     */
6399
    public function load_template ( $params ) {
6400
        if ( !class_exists( 'Pods_Templates' ) )
6401
            return false;
6402
6403
        $params = (object) $params;
6404
        $params->type = 'template';
6405
        return $this->load_object( $params );
6406
    }
6407
6408
    /**
6409
     * @see PodsAPI::load_objects
6410
     *
6411
     * Load Multiple Pod Templates
6412
     *
6413
     * $params['where'] string The WHERE clause of query
6414
     * $params['options'] array Pod Option(s) key=>value array to filter by
6415
     * $params['orderby'] string ORDER BY clause of query
6416
     * $params['limit'] string Number of templates to return
6417
     *
6418
     * @param array $params (optional) An associative array of parameters
6419
     *
6420
     * @return array
6421
     *
6422
     * @since 2.0
6423
     */
6424
    public function load_templates ( $params = null ) {
6425
        if ( !class_exists( 'Pods_Templates' ) )
6426
            return array();
6427
6428
        $params = (object) $params;
6429
        $params->type = 'template';
6430
        return $this->load_objects( $params );
6431
    }
6432
6433
    /**
6434
     * @see PodsAPI::load_object
6435
     *
6436
     * Load a Pod Page
6437
     *
6438
     * $params['id'] int The page ID
6439
     * $params['name'] string The page URI
6440
     *
6441
     * @param array $params An associative array of parameters
6442
     *
6443
     * @return array|bool
6444
     *
6445
     * @since 1.7.9
6446
     */
6447
    public function load_page ( $params ) {
6448
        if ( !class_exists( 'Pods_Pages' ) )
6449
            return false;
6450
6451
        $params = (object) $params;
6452 View Code Duplication
        if ( !isset( $params->name ) && isset( $params->uri ) ) {
6453
            $params->name = $params->uri;
6454
            unset( $params->uri );
6455
        }
6456
        $params->type = 'page';
6457
        return $this->load_object( $params );
6458
    }
6459
6460
    /**
6461
     * @see PodsAPI::load_objects
6462
     *
6463
     * Load Multiple Pod Pages
6464
     *
6465
     * $params['where'] string The WHERE clause of query
6466
     * $params['options'] array Pod Option(s) key=>value array to filter by
6467
     * $params['orderby'] string ORDER BY clause of query
6468
     * $params['limit'] string Number of pages to return
6469
     *
6470
     * @param array $params (optional) An associative array of parameters
6471
     *
6472
     * @return array
6473
     *
6474
     * @since 2.0
6475
     */
6476
    public function load_pages ( $params = null ) {
6477
        if ( !class_exists( 'Pods_Pages' ) )
6478
            return array();
6479
6480
        $params = (object) $params;
6481
        $params->type = 'page';
6482
        return $this->load_objects( $params );
6483
    }
6484
6485
    /**
6486
     * @see PodsAPI::load_object
6487
     *
6488
     * Load a Pod Helper
6489
     *
6490
     * $params['id'] int The helper ID
6491
     * $params['name'] string The helper name
6492
     *
6493
     * @param array $params An associative array of parameters
6494
     *
6495
     * @return array|bool
6496
     *
6497
     * @since 1.7.9
6498
     */
6499 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...
6500
        if ( !class_exists( 'Pods_Helpers' ) )
6501
            return false;
6502
6503
        $params = (object) $params;
6504
        $params->type = 'helper';
6505
        return $this->load_object( $params );
6506
    }
6507
6508
    /**
6509
     * @see PodsAPI::load_objects
6510
     *
6511
     * Load Multiple Pod Helpers
6512
     *
6513
     * $params['where'] string The WHERE clause of query
6514
     * $params['options'] array Pod Option(s) key=>value array to filter by
6515
     * $params['orderby'] string ORDER BY clause of query
6516
     * $params['limit'] string Number of pages to return
6517
     *
6518
     * @param array $params (optional) An associative array of parameters
6519
     *
6520
     * @return array
6521
     *
6522
     * @since 2.0
6523
     */
6524 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...
6525
        if ( !class_exists( 'Pods_Helpers' ) )
6526
            return array();
6527
6528
        $params = (object) $params;
6529
        $params->type = 'helper';
6530
        return $this->load_objects( $params );
6531
    }
6532
6533
    /**
6534
     * Load the pod item object
6535
     *
6536
     * $params['pod'] string The datatype name
6537
     * $params['id'] int (optional) The item's ID
6538
     *
6539
     * @param array $params An associative array of parameters
6540
     *
6541
     * @return bool|\Pods
6542
     *
6543
     * @uses pods()
6544
     *
6545
     * @since 2.0
6546
     */
6547
    public function load_pod_item ( $params ) {
6548
        $params = (object) pods_sanitize( $params );
6549
6550 View Code Duplication
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6551
            return pods_error( __( 'Pod name required', 'pods' ), $this );
6552 View Code Duplication
        if ( !isset( $params->id ) || empty( $params->id ) )
6553
            return pods_error( __( 'Item ID required', 'pods' ), $this );
6554
6555
        $pod = false;
6556
6557
        if ( pods_api_cache() )
6558
            $pod = pods_cache_get( $params->id, 'pods_item_object_' . $params->pod );
6559
6560
        if ( false !== $pod )
6561
            return $pod;
6562
6563
        $pod = pods( $params->pod, $params->id );
6564
6565
        if ( pods_api_cache() )
6566
            pods_cache_set( $params->id, $pod, 'pods_item_object_' . $params->pod );
6567
6568
        return $pod;
6569
    }
6570
6571
    /**
6572
     * Load potential sister fields for a specific field
6573
     *
6574
     * $params['pod'] int The Pod name
6575
     * $params['related_pod'] string The related Pod name
6576
     *
6577
     * @param array $params An associative array of parameters
6578
     * @param array $pod (optional) Array of Pod data to use (to avoid lookup)
6579
     *
6580
     * @return array|bool
6581
     *
6582
     * @since 1.7.9
6583
     *
6584
     * @uses PodsAPI::load_pod
6585
     */
6586
    public function load_sister_fields ( $params, $pod = null ) {
6587
        $params = (object) pods_sanitize( $params );
6588
6589 View Code Duplication
        if ( empty( $pod ) ) {
6590
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ), false );
6591
6592
            if ( false === $pod )
6593
                return pods_error( __( 'Pod not found', 'pods' ), $this );
6594
        }
6595
6596
        $params->pod_id = $pod[ 'id' ];
6597
        $params->pod = $pod[ 'name' ];
6598
6599
        $type = false;
6600
6601
        if ( 0 === strpos( $params->related_pod, 'pod-' ) ) {
6602
            $params->related_pod = pods_str_replace( 'pod-', '', $params->related_pod, 1 );
6603
            $type = 'pod';
6604
        }
6605 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'post_type-' ) ) {
6606
            $params->related_pod = pods_str_replace( 'post_type-', '', $params->related_pod, 1 );
6607
            $type = 'post_type';
6608
        }
6609 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'taxonomy-' ) ) {
6610
            $params->related_pod = pods_str_replace( 'taxonomy-', '', $params->related_pod, 1 );
6611
            $type = 'taxonomy';
6612
        }
6613
6614
        $related_pod = $this->load_pod( array( 'name' => $params->related_pod, 'table_info' => false ), false );
6615
6616
        if ( false === $related_pod || ( false !== $type && 'pod' != $type && $type != $related_pod[ 'type' ] ) )
6617
            return pods_error( __( 'Related Pod not found', 'pods' ), $this );
6618
6619
        $params->related_pod_id = $related_pod[ 'id' ];
6620
        $params->related_pod = $related_pod[ 'name' ];
6621
6622
        $sister_fields = array();
6623
6624
        foreach ( $related_pod[ 'fields' ] as $field ) {
6625
            if ( 'pick' == $field[ 'type' ] && in_array( $field[ 'pick_object' ], array( $pod[ 'type' ], 'pod' ) ) && ( $params->pod == $field[ 'pick_object' ] || $params->pod == $field[ 'pick_val' ] ) )
6626
                $sister_fields[ $field[ 'id' ] ] = esc_html( $field[ 'label' ] . ' (' . $field[ 'name' ] . ')' );
6627
        }
6628
6629
        return $sister_fields;
6630
    }
6631
6632
    /**
6633
     * Takes a sql field such as tinyint and returns the pods field type, such as num.
6634
     *
6635
     * @param string $sql_field The SQL field to look for
6636
     *
6637
     * @return string The field type
6638
     *
6639
     * @since 2.0
6640
     */
6641
    public static function detect_pod_field_from_sql_data_type ( $sql_field ) {
6642
        $sql_field = strtolower( $sql_field );
6643
6644
        $field_to_field_map = array(
6645
            'tinyint' => 'number',
6646
            'smallint' => 'number',
6647
            'mediumint' => 'number',
6648
            'int' => 'number',
6649
            'bigint' => 'number',
6650
            'float' => 'number',
6651
            'double' => 'number',
6652
            'decimal' => 'number',
6653
            'date' => 'date',
6654
            'datetime' => 'datetime',
6655
            'timestamp' => 'datetime',
6656
            'time' => 'time',
6657
            'year' => 'date',
6658
            'varchar' => 'text',
6659
            'text' => 'paragraph',
6660
            'mediumtext' => 'paragraph',
6661
            'longtext' => 'paragraph'
6662
        );
6663
6664
        return ( array_key_exists( $sql_field, $field_to_field_map ) ) ? $field_to_field_map[ $sql_field ] : 'paragraph';
6665
    }
6666
6667
    /**
6668
     * Gets all field types
6669
     *
6670
     * @return array Array of field types
6671
     *
6672
     * @uses PodsForm::field_loader
6673
     *
6674
     * @since 2.0
6675
     * @deprecated
6676
     */
6677
    public function get_field_types () {
6678
        return PodsForm::field_types();
6679
    }
6680
6681
    /**
6682
     * Gets the schema definition of a field.
6683
     *
6684
     * @param string $type Field type to look for
6685
     * @param array $options (optional) Options of the field to pass to the schema function.
6686
     *
6687
     * @return array|bool|mixed|null
6688
     *
6689
     * @since 2.0
6690
     */
6691
    private function get_field_definition ( $type, $options = null ) {
6692
        $definition = PodsForm::field_method( $type, 'schema', $options );
6693
6694
        return $this->do_hook( 'field_definition', $definition, $type, $options );
6695
    }
6696
6697
    /**
6698
     * @see PodsForm:validate
6699
     *
6700
     * Validates the value of a field.
6701
     *
6702
     * @param mixed $value The value to validate
6703
     * @param string $field Field to use for validation
6704
     * @param array $object_fields Fields of the object we're validating
6705
     * @param array $fields Array of all fields data
6706
     * @param array|Pods $pod Array of pod data (or Pods object)
6707
     * @param array|object $params Extra parameters to pass to the validation function of the field.
6708
     *
6709
     * @return array|bool
6710
     *
6711
     * @uses PodsForm::validate
6712
     *
6713
     * @since 2.0
6714
     */
6715
    public function handle_field_validation ( &$value, $field, $object_fields, $fields, $pod, $params ) {
6716
        $tableless_field_types = PodsForm::tableless_field_types();
6717
6718
        $fields = array_merge( $fields, $object_fields );
6719
6720
        $options = $fields[ $field ];
6721
6722
        $id = ( is_object( $params ) ? $params->id : ( is_object( $pod ) ? $pod->id() : 0 ) );
6723
6724
        if ( is_object( $pod ) )
6725
            $pod = $pod->pod_data;
6726
6727
        $type = $options[ 'type' ];
6728
        $label = $options[ 'label' ];
6729
        $label = empty( $label ) ? $field : $label;
6730
6731
        // Verify required fields
6732
        if ( 1 == pods_var( 'required', $options[ 'options' ], 0 ) && 'slug' != $type ) {
6733
            if ( '' == $value || null === $value || array() === $value )
6734
                return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this );
6735
6736
            if ( 'multi' == pods_var( 'pick_format_type', $options[ 'options' ] ) && 'autocomplete' != pods_var( 'pick_format_multi', $options[ 'options' ] ) ) {
6737
                $has_value = false;
6738
6739
                $check_value = (array) $value;
6740
6741
                foreach ( $check_value as $val ) {
6742
                    if ( '' != $val && null !== $val && 0 !== $val && '0' !== $val ) {
6743
                        $has_value = true;
6744
6745
                        continue;
6746
                    }
6747
                }
6748
6749
                if ( !$has_value )
6750
                    return pods_error( sprintf( __( '%s is required', 'pods' ), $label ), $this );
6751
            }
6752
6753
        }
6754
6755
        // @todo move this to after pre-save preparations
6756
        // Verify unique fields
6757
        if ( 1 == pods_var( 'unique', $options[ 'options' ], 0 ) && '' !== $value && null !== $value && array() !== $value ) {
6758
            if ( empty( $pod ) )
6759
                return false;
6760
6761
            if ( !in_array( $type, $tableless_field_types ) ) {
6762
                $exclude = '';
6763
6764
                if ( !empty( $id ) )
6765
                    $exclude = "AND `id` != {$id}";
6766
6767
                $check = false;
6768
6769
                $check_value = pods_sanitize( $value );
6770
6771
                // @todo handle meta-based fields
6772
                // Trigger an error if not unique
6773
                if ( 'table' == $pod[ 'storage' ] )
6774
                    $check = pods_query( "SELECT `id` FROM `@wp_pods_" . $pod[ 'name' ] . "` WHERE `{$field}` = '{$check_value}' {$exclude} LIMIT 1", $this );
6775
6776
                if ( !empty( $check ) )
6777
                    return pods_error( sprintf( __( '%s needs to be unique', 'pods' ), $label ), $this );
6778
            }
6779
            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...
6780
                // @todo handle tableless check
6781
            }
6782
        }
6783
6784
        $validate = PodsForm::validate( $options[ 'type' ], $value, $field, array_merge( $options, pods_var( 'options', $options, array() ) ), $fields, $pod, $id, $params );
6785
6786
        $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params );
6787
6788
        return $validate;
6789
    }
6790
6791
    /**
6792
     * Find items related to a parent field
6793
     *
6794
     * @param int $field_id The Field ID
6795
     * @param int $pod_id The Pod ID
6796
     * @param mixed $ids A comma-separated string (or array) of item IDs
6797
     * @param array $field Field data array
6798
     * @param array $pod Pod data array
6799
     *
6800
     * @return array
6801
     *
6802
     * @since 2.0
6803
     *
6804
     * @uses pods_query()
6805
     */
6806
    public function lookup_related_items ( $field_id, $pod_id, $ids, $field = null, $pod = null ) {
6807
        $related_ids = array();
6808
6809
        if ( !is_array( $ids ) )
6810
            $ids = explode( ',', $ids );
6811
6812
        foreach ( $ids as $k => $id ) {
6813
            $ids[ $k ] = (int) $id;
6814
        }
6815
6816
        $ids = array_unique( array_filter( $ids ) );
6817
6818
	    $idstring = implode( ',', $ids );
6819
	    if ( 0 != $pod_id && 0 != $field_id && isset( self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] ) ) {
6820
		    // Check cache first, no point in running the same query multiple times
6821
		    return self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ];
6822
	    }
6823
6824
        $tableless_field_types = PodsForm::tableless_field_types();
6825
6826
		$field_type = pods_v( 'type', $field );
6827
6828
        if ( empty( $ids ) || !in_array( $field_type, $tableless_field_types ) )
6829
            return array();
6830
6831
        $related_pick_limit = 0;
6832
6833
		if ( empty( $field ) ) {
6834
			$field = $this->load_field( array( 'id' => $field_id ) );
6835
		}
6836
6837
        if ( !empty( $field ) ) {
6838
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
6839
6840
            $related_pick_limit = (int) pods_v( $field_type . '_limit', $options, 0 );
6841
6842
            if ( 'single' == pods_var_raw( $field_type . '_format_type', $options ) )
6843
                $related_pick_limit = 1;
6844
6845
            // Temporary hack until there's some better handling here
6846
            $related_pick_limit = $related_pick_limit * count( $ids );
6847
        }
6848
6849
		if ( 'taxonomy' == $field_type ) {
6850
			$related = wp_get_object_terms( $ids, pods_v( 'name', $field ), array( 'fields' => 'ids' ) );
6851
6852
			if ( !is_wp_error( $related ) ) {
6853
				$related_ids = $related;
6854
			}
6855
		}
6856
		elseif ( !pods_tableless() ) {
6857
            $ids = implode( ', ', $ids );
6858
6859
            $field_id = (int) $field_id;
6860
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
6861
6862
            $related_where = "
6863
                `field_id` = {$field_id}
6864
                AND `item_id` IN ( {$ids} )
6865
            ";
6866
6867
            $sql = "
6868
                SELECT item_id, related_item_id, related_field_id
6869
                FROM `@wp_podsrel`
6870
                WHERE
6871
                    {$related_where}
6872
                ORDER BY `weight`
6873
            ";
6874
6875
            $relationships = pods_query( $sql );
6876
6877
            if ( !empty( $relationships ) ) {
6878
                foreach ( $relationships as $relation ) {
6879
                    if ( !in_array( $relation->related_item_id, $related_ids ) )
6880
                        $related_ids[] = (int) $relation->related_item_id;
6881
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->item_id, $related_ids ) )
6882
                        $related_ids[] = (int) $relation->item_id;
6883
                }
6884
            }
6885
        }
6886 View Code Duplication
        else {
6887
            if ( !is_array( $pod ) )
6888
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
6889
6890
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
6891
                $meta_type = $pod[ 'type' ];
6892
6893
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
6894
                    $meta_type = 'post';
6895
                elseif ( 'taxonomy' == $meta_type )
6896
                    $meta_type = 'term';
6897
6898
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
6899
6900
                if ( !$no_conflict )
6901
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
6902
6903
                foreach ( $ids as $id ) {
6904
                    if ( 'settings' == $meta_type ) {
6905
                        $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
6906
6907
                        if ( empty( $related_id ) )
6908
                            $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
6909
6910
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
6911
                            foreach ( $related_id as $related ) {
6912
                                if ( is_array( $related ) && !empty( $related ) ) {
6913
                                    if ( isset( $related[ 'id' ] ) )
6914
                                        $related_ids[] = (int) $related[ 'id' ];
6915
                                    else {
6916
                                        foreach ( $related as $r ) {
6917
                                            $related_ids[] = (int) $r;
6918
                                        }
6919
                                    }
6920
                                }
6921
                                else
6922
                                    $related_ids[] = (int) $related;
6923
                            }
6924
                        }
6925
                    }
6926
                    else {
6927
                        $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
6928
6929
                        if ( empty( $related_id ) )
6930
                            $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
6931
6932
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
6933
                            foreach ( $related_id as $related ) {
6934
                                if ( is_array( $related ) && !empty( $related ) ) {
6935
                                    if ( isset( $related[ 'id' ] ) )
6936
                                        $related_ids[] = (int) $related[ 'id' ];
6937
                                    else {
6938
                                        foreach ( $related as $r ) {
6939
                                            if ( isset( $related[ 'id' ] ) )
6940
                                                $related_ids[] = (int) $r[ 'id' ];
6941
                                            else
6942
                                                $related_ids[] = (int) $r;
6943
                                        }
6944
                                    }
6945
                                }
6946
                                else
6947
                                    $related_ids[] = (int) $related;
6948
                            }
6949
                        }
6950
                    }
6951
                }
6952
6953
                if ( !$no_conflict )
6954
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
6955
            }
6956
        }
6957
6958
        if ( is_array( $related_ids ) ) {
6959
            $related_ids = array_unique( array_filter( $related_ids ) );
6960
6961
            if ( 0 < $related_pick_limit && !empty( $related_ids ) )
6962
                $related_ids = array_slice( $related_ids, 0, $related_pick_limit );
6963
        }
6964
	    if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) {
6965
                    // Only cache if $pod_id and $field_id were passed
6966
		    self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] = $related_ids;
6967
	    }
6968
6969
        return $related_ids;
6970
    }
6971
6972
    /**
6973
     * Find related items related to an item
6974
     *
6975
     * @param int $field_id The Field ID
6976
     * @param int $pod_id The Pod ID
6977
     * @param int $id Item ID to get related IDs from
6978
     * @param array $field Field data array
6979
     * @param array $pod Pod data array
6980
     *
6981
     * @return array|bool
6982
     *
6983
     * @since 2.3
6984
     *
6985
     * @uses pods_query()
6986
     */
6987
    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...
6988
        $related_ids = false;
6989
6990
        $id = (int) $id;
6991
6992
        $tableless_field_types = PodsForm::tableless_field_types();
6993
6994
        if ( empty( $id ) || !in_array( pods_v( 'type', $field ), $tableless_field_types ) )
6995
            return false;
6996
6997
        $related_pick_limit = 0;
6998
6999
        if ( !empty( $field ) ) {
7000
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7001
7002
            $related_pick_limit = (int) pods_v( 'pick_limit', $options, 0 );
7003
7004
            if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
7005
                $related_pick_limit = 1;
7006
        }
7007
7008
        if ( !pods_tableless() ) {
7009
            $field_id = (int) $field_id;
7010
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7011
7012
            $related_where = "
7013
                `field_id` = {$field_id}
7014
                AND `related_item_id` = {$id}
7015
            ";
7016
7017
            $sql = "
7018
                SELECT *
7019
                FROM `@wp_podsrel`
7020
                WHERE
7021
                    {$related_where}
7022
                ORDER BY `weight`
7023
            ";
7024
7025
            $relationships = pods_query( $sql );
7026
7027
            if ( !empty( $relationships ) ) {
7028
                $related_ids = array();
7029
7030
                foreach ( $relationships as $relation ) {
7031
                    if ( $field_id == $relation->field_id && !in_array( $relation->item_id, $related_ids ) )
7032
                        $related_ids[] = (int) $relation->item_id;
7033
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->related_item_id, $related_ids ) )
7034
                        $related_ids[] = (int) $relation->related_item_id;
7035
                }
7036
            }
7037
        }
7038 View Code Duplication
        else {
7039
            // @todo handle meta-based lookups
7040
            return false;
7041
7042
            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...
7043
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7044
7045
            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...
7046
                $related_ids = array();
7047
7048
                $meta_type = $pod[ 'type' ];
7049
7050
                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...
7051
                    $meta_type = 'post';
7052
                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...
7053
                    $meta_type = 'term';
7054
7055
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7056
7057
                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...
7058
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7059
7060
                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...
7061
                    $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7062
7063
                    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...
7064
                        $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7065
7066
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7067
                        foreach ( $related_id as $related ) {
7068
                            if ( is_array( $related ) && !empty( $related ) ) {
7069
                                if ( isset( $related[ 'id' ] ) )
7070
                                    $related_ids[] = (int) $related[ 'id' ];
7071
                                else {
7072
                                    foreach ( $related as $r ) {
7073
                                        $related_ids[] = (int) $r;
7074
                                    }
7075
                                }
7076
                            }
7077
                            else
7078
                                $related_ids[] = (int) $related;
7079
                        }
7080
                    }
7081
                }
7082
                else {
7083
                    $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7084
7085
                    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...
7086
                        $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7087
7088
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7089
                        foreach ( $related_id as $related ) {
7090
                            if ( is_array( $related ) && !empty( $related ) ) {
7091
                                if ( isset( $related[ 'id' ] ) )
7092
                                    $related_ids[] = (int) $related[ 'id' ];
7093
                                else {
7094
                                    foreach ( $related as $r ) {
7095
                                        if ( isset( $related[ 'id' ] ) )
7096
                                            $related_ids[] = (int) $r[ 'id' ];
7097
                                        else
7098
                                            $related_ids[] = (int) $r;
7099
                                    }
7100
                                }
7101
                            }
7102
                            else
7103
                                $related_ids[] = (int) $related;
7104
                        }
7105
                    }
7106
                }
7107
7108
                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...
7109
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7110
            }
7111
        }
7112
7113
        if ( is_array( $related_ids ) )
7114
            $related_ids = array_unique( array_filter( $related_ids ) );
7115
7116
        return $related_ids;
7117
    }
7118
7119
	/**
7120
	 *
7121
	 * Load the information about an objects MySQL table
7122
	 *
7123
	 * @param $object_type
7124
	 * @param string $object The object to look for
7125
	 * @param null $name (optional) Name of the pod to load
7126
	 * @param array $pod (optional) Array with pod information
7127
	 *
7128
	 * @return array
7129
	 *
7130
	 * @since 2.5
7131
	 */
7132
	public function get_table_info_load ( $object_type, $object, $name = null, $pod = null ) {
7133
7134
		$info = array();
7135
7136
		if ( 'pod' == $object_type && null === $pod ) {
7137 View Code Duplication
			if ( empty( $name ) ) {
7138
				$prefix = 'pod-';
7139
7140
				// Make sure we actually have the prefix before trying anything with the name
7141
				if ( 0 === strpos( $object_type, $prefix ) )
7142
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7143
			}
7144
7145
			if ( empty( $name ) && !empty( $object ) )
7146
				$name = $object;
7147
7148
			$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7149
7150
			if ( !empty( $pod ) ) {
7151
				$object_type = $pod[ 'type' ];
7152
				$name = $pod[ 'name' ];
7153
				$object = $pod[ 'object' ];
7154
7155
				$info[ 'pod' ] = $pod;
7156
			}
7157
		}
7158
		elseif ( null === $pod ) {
7159
			if ( empty( $name ) ) {
7160
				$prefix = $object_type . '-';
7161
7162
				// Make sure we actually have the prefix before trying anything with the name
7163
				if ( 0 === strpos( $object_type, $prefix ) )
7164
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7165
			}
7166
7167
			if ( empty( $name ) && !empty( $object ) )
7168
				$name = $object;
7169
7170
			if ( !empty( $name ) ) {
7171
				$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7172
7173
				if ( !empty( $pod ) && ( null === $object_type || $object_type == $pod[ 'type' ] ) ) {
7174
					$object_type = $pod[ 'type' ];
7175
					$name = $pod[ 'name' ];
7176
					$object = $pod[ 'object' ];
7177
7178
					$info[ 'pod' ] = $pod;
7179
				}
7180
			}
7181
		}
7182
		elseif ( !empty( $pod ) )
7183
			$info[ 'pod' ] = $pod;
7184
7185
		if ( 0 === strpos( $object_type, 'pod' ) ) {
7186 View Code Duplication
			if ( empty( $name ) ) {
7187
				$prefix = 'pod-';
7188
7189
				// Make sure we actually have the prefix before trying anything with the name
7190
				if ( 0 === strpos( $object_type, $prefix ) )
7191
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7192
			}
7193
7194
			$info[ 'type' ] = 'pod';
7195
			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...
7196
7197
			$info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object );
7198
7199
			if ( is_array( $info[ 'pod' ] ) && 'pod' == pods_v( 'type', $info[ 'pod' ] ) ) {
7200
				$info[ 'pod_field_index' ] = $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_v( 'pod_index', $info[ 'pod' ][ 'options' ], 'id', true );
7201
7202
				$slug_field = get_posts( array(
7203
					'post_type' => '_pods_field',
7204
					'posts_per_page' => 1,
7205
					'nopaging' => true,
7206
					'post_parent' => $info[ 'pod' ][ 'id' ],
7207
					'orderby' => 'menu_order',
7208
					'order' => 'ASC',
7209
					'meta_query' => array(
7210
						array(
7211
							'key' => 'type',
7212
							'value' => 'slug',
7213
						)
7214
					)
7215
				) );
7216
7217
				if ( !empty( $slug_field ) ) {
7218
					$slug_field = $slug_field[ 0 ];
7219
7220
					$info[ 'field_slug' ] = $info[ 'pod_field_slug' ] = $slug_field->post_name;
7221
				}
7222
7223
				if ( 1 == pods_v( 'hierarchical', $info[ 'pod' ][ 'options' ], 0 ) ) {
7224
					$parent_field = pods_v( 'pod_parent', $info[ 'pod' ][ 'options' ], 'id', true );
7225
7226
					if ( !empty( $parent_field ) && isset( $info[ 'pod' ][ 'fields' ][ $parent_field ] ) ) {
7227
						$info[ 'object_hierarchical' ] = true;
7228
7229
						$info[ 'pod_field_parent' ] = $info[ 'field_parent' ] = $parent_field . '_select';
7230
						$info[ 'field_parent_select' ] = '`' . $parent_field . '`.`id` AS `' . $info[ 'field_parent' ] . '`';
7231
					}
7232
				}
7233
			}
7234
		}
7235
		return $info;
7236
	}
7237
7238
    /**
7239
     * Get information about an objects MySQL table
7240
     *
7241
     * @param string $object_type
7242
     * @param string $object The object to look for
7243
     * @param null $name (optional) Name of the pod to load
7244
     * @param array $pod (optional) Array with pod information
7245
     * @param array $field (optional) Array with field information
7246
     *
7247
     * @return array|bool
7248
     *
7249
     * @since 2.0
7250
     */
7251
    public function get_table_info ( $object_type, $object, $name = null, $pod = null, $field = null ) {
7252
7253
	    /**
7254
	     * @var $wpdb                         wpdb
7255
	     * @var $sitepress                    SitePress
7256
	     * @var $icl_adjust_id_url_filter_off boolean
7257
	     * @var $polylang                     object
7258
	     */
7259
        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...
7260
7261
		// @todo Handle $object arrays for Post Types, Taxonomies, Comments (table pulled from first object in array)
7262
7263
        $info = array(
7264
            //'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...
7265
            'object_type' => $object_type,
7266
            'type' => null,
7267
            'object_name' => $object,
7268
            'object_hierarchical' => false,
7269
7270
            'table' => $object,
7271
            'meta_table' => $object,
7272
            'pod_table' => $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object ),
7273
7274
            'field_id' => 'id',
7275
            'field_index' => 'name',
7276
            'field_slug' => null,
7277
            'field_type' => null,
7278
            'field_parent' => null,
7279
            'field_parent_select' => null,
7280
7281
            'meta_field_id' => 'id',
7282
            'meta_field_index' => 'name',
7283
            'meta_field_value' => 'name',
7284
7285
            'pod_field_id' => 'id',
7286
            'pod_field_index' => 'name',
7287
            'pod_field_slug' => null,
7288
            'pod_field_parent' => null,
7289
7290
            'join' => array(),
7291
7292
            'where' => null,
7293
            'where_default' => null,
7294
7295
            'orderby' => null,
7296
7297
            'pod' => null,
7298
            'recurse' => false
7299
        );
7300
7301
        if ( empty( $object_type ) ) {
7302
            $object_type = 'post_type';
7303
            $object = 'post';
7304
        }
7305
	    elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ) ) ) {
7306
		    $object = $object_type;
7307
	    }
7308
7309
        $pod_name = $pod;
7310
7311 View Code Duplication
        if ( is_array( $pod_name ) )
7312
            $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...
7313
	    else {
7314
		    $pod_name = $object;
7315
	    }
7316
7317
        $field_name = $field;
7318
7319 View Code Duplication
        if ( is_array( $field_name ) )
7320
            $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...
7321
7322
        $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7323
7324
        $current_language = false;
7325
        $current_language_t_id = $current_language_tt_id = 0;
7326
7327
	    // Get current language data
7328
		$lang_data = self::get_current_language();
7329
7330
	    if ( $lang_data ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $lang_data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
7331
		    if ( ! empty( $lang_data['language'] ) ) {
7332
			    $current_language = $lang_data['language'];
7333
		    }
7334
7335
		    if ( ! empty( $lang_data['t_id'] ) ) {
7336
			    $current_language_t_id = $lang_data['t_id'];
7337
		    }
7338
7339
		    if ( ! empty( $lang_data['t_id'] ) ) {
7340
			    $current_language_tt_id = $lang_data['tt_id'];
7341
		    }
7342
	    }
7343
7344
        if ( !empty( $current_language ) )
7345
            $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7346
7347
        $_info = false;
7348
7349
	    if ( isset( self::$table_info_cache[ $transient ] ) ) {
7350
		    // Prefer info from the object internal cache
7351
		    $_info = self::$table_info_cache[ $transient ];
7352
	    } elseif ( pods_api_cache() ) {
7353
		    $_info = pods_transient_get( $transient );
7354
		    if ( false === $_info && ! did_action( 'init' ) ) {
7355
			    $_info = pods_transient_get( $transient . '_pre_init' );
7356
		    }
7357
	    }
7358
7359
	    if ( false !== $_info ) {
7360
		    // Data was cached, use that
7361
		    $info = $_info;
7362
	    } else {
7363
	        // Data not cached, load it up
7364
		    $_info = $this->get_table_info_load( $object_type, $object, $name, $pod );
7365
		    if ( isset( $_info[ 'type' ] ) ) {
7366
			    // Allow function to override $object_type
7367
			    $object_type = $_info[ 'type' ];
7368
		    }
7369
		    $info = array_merge( $info, $_info );
7370
	    }
7371
7372
	    if ( 0 === strpos( $object_type, 'post_type' ) || 'media' == $object_type || in_array( pods_var_raw( 'type', $info[ 'pod' ] ), array( 'post_type', 'media' ) ) ) {
7373
		    $info[ 'table' ] = $wpdb->posts;
7374
		    $info[ 'meta_table' ] = $wpdb->postmeta;
7375
7376
		    $info[ 'field_id' ] = 'ID';
7377
		    $info[ 'field_index' ] = 'post_title';
7378
		    $info[ 'field_slug' ] = 'post_name';
7379
		    $info[ 'field_type' ] = 'post_type';
7380
		    $info[ 'field_parent' ] = 'post_parent';
7381
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7382
7383
		    $info[ 'meta_field_id' ] = 'post_id';
7384
		    $info[ 'meta_field_index' ] = 'meta_key';
7385
		    $info[ 'meta_field_value' ] = 'meta_value';
7386
7387
		    if ( 'media' == $object_type )
7388
			    $object = 'attachment';
7389
7390
		    if ( empty( $name ) ) {
7391
			    $prefix = 'post_type-';
7392
7393
			    // Make sure we actually have the prefix before trying anything with the name
7394
			    if ( 0 === strpos( $object_type, $prefix ) )
7395
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7396
		    }
7397
7398
		    if ( 'media' != $object_type )
7399
			    $object_type = 'post_type';
7400
7401
		    $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7402
7403
		    if ( 'attachment' == $post_type || 'media' == $object_type )
7404
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_media';
7405
		    else
7406
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $post_type, true, false );
7407
7408
		    $post_type_object = get_post_type_object( $post_type );
7409
7410
		    if ( is_object( $post_type_object ) && $post_type_object->hierarchical )
7411
			    $info[ 'object_hierarchical' ] = true;
7412
7413
		    /**
7414
		     * Default Post Status to query for.
7415
		     *
7416
		     * Use to change "default" post status from publish to any other status or statuses.
7417
		     *
7418
		     * @param  array $post_status List of post statuses. Default is 'publish'
7419
		     * @param  string $post_type Post type of current object
7420
		     * @param  array $info Array of information about the object.
7421
		     * @param  string $object	Type of object
7422
		     * @param  string $name Name of pod to load
7423
		     * @param  array $pod Array with Pod information. Result of PodsAPI::load_pod()
7424
		     * @param  array $field		Array with field information
7425
		     *
7426
		     * @since unknown
7427
		     */
7428
		    $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', array( 'publish' ), $post_type, $info, $object_type, $object, $name, $pod, $field );
7429
7430
		    $info[ 'where' ] = array(
7431
			    //'post_status' => '`t`.`post_status` IN ( "inherit", "publish" )', // @todo Figure out what statuses Attachments can be
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
7432
			    'post_type' => '`t`.`' . $info[ 'field_type' ] . '` = "' . $post_type . '"'
7433
		    );
7434
7435
		    if ( 'post_type' == $object_type )
7436
			    $info[ 'where_default' ] = '`t`.`post_status` IN ( "' . implode( '", "', $post_status ) . '" )';
7437
7438
		    $info[ 'orderby' ] = '`t`.`menu_order`, `t`.`' . $info[ 'field_index' ] . '`, `t`.`post_date`';
7439
7440
		    // WPML support
7441 View Code Duplication
		    if ( is_object( $sitepress ) && !empty( $current_language ) && $sitepress->is_translated_post_type( $post_type ) && !$icl_adjust_id_url_filter_off ) {
7442
			    $info[ 'join' ][ 'wpml_translations' ] = "
7443
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7444
                            ON `wpml_translations`.`element_id` = `t`.`ID`
7445
                                AND `wpml_translations`.`element_type` = 'post_{$post_type}'
7446
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7447
                    ";
7448
7449
			    $info[ 'join' ][ 'wpml_languages' ] = "
7450
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7451
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7452
                    ";
7453
7454
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7455
		    }
7456
		    // Polylang support
7457
		    elseif( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && !empty( $current_language ) && function_exists( 'pll_is_translated_post_type' ) && pll_is_translated_post_type( $post_type ) ) {
7458
			    $info[ 'join' ][ 'polylang_languages' ] = "
7459
                        LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7460
                            ON `polylang_languages`.`object_id` = `t`.`ID`
7461
                                AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id}
7462
                    ";
7463
7464
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7465
		    }
7466
7467
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7468
	    }
7469
	    elseif ( 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, array( 'nav_menu', 'post_format' ) ) || 'taxonomy' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7470
		    $info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->terms;
7471
7472
		    $info[ 'join' ][ 'tt' ] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`";
7473
		    $info[ 'join' ][ 'tr' ] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`";
7474
		    $info[ 'field_id' ] = $info[ 'meta_field_id' ] = 'term_id';
7475
		    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = 'name';
7476
		    $info[ 'field_slug' ] = 'slug';
7477
		    $info[ 'field_type' ] = 'taxonomy';
7478
		    $info[ 'field_parent' ] = 'parent';
7479
		    $info[ 'field_parent_select' ] = '`tt`.`' . $info[ 'field_parent' ] . '`';
7480
7481
            if ( ! empty( $wpdb->termmeta ) ) {
7482
                $info[ 'meta_table' ] = $wpdb->termmeta;
7483
7484
                $info[ 'meta_field_id' ] = 'term_id';
7485
                $info[ 'meta_field_index' ] = 'meta_key';
7486
                $info[ 'meta_field_value' ] = 'meta_value';
7487
            }
7488
7489
		    if ( 'nav_menu' == $object_type )
7490
			    $object = 'nav_menu';
7491
		    elseif ( 'post_format' == $object_type )
7492
			    $object = 'post_format';
7493
7494
		    if ( empty( $name ) ) {
7495
			    $prefix = 'taxonomy-';
7496
7497
			    // Make sure we actually have the prefix before trying anything with the name
7498
			    if ( 0 === strpos( $object_type, $prefix ) )
7499
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7500
		    }
7501
7502
		    if ( !in_array( $object_type, array( 'nav_menu', 'post_format' ) ) )
7503
			    $object_type = 'taxonomy';
7504
7505
		    $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7506
7507
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $taxonomy, true, false );
7508
7509
		    $taxonomy_object = get_taxonomy( $taxonomy );
7510
7511
		    if ( is_object( $taxonomy_object ) && $taxonomy_object->hierarchical )
7512
			    $info[ 'object_hierarchical' ] = true;
7513
7514
		    $info[ 'where' ] = array(
7515
			    'tt.taxonomy' => '`tt`.`' . $info[ 'field_type' ] . '` = "' . $taxonomy . '"'
7516
		    );
7517
7518
		    // WPML Support
7519 View Code Duplication
		    if ( is_object( $sitepress ) && !empty( $current_language ) && $sitepress->is_translated_taxonomy( $taxonomy ) && !$icl_adjust_id_url_filter_off ) {
7520
			    $info[ 'join' ][ 'wpml_translations' ] = "
7521
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7522
                            ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id`
7523
                                AND `wpml_translations`.`element_type` = 'tax_{$taxonomy}'
7524
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7525
                    ";
7526
7527
			    $info[ 'join' ][ 'wpml_languages' ] = "
7528
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7529
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7530
                    ";
7531
7532
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7533
		    }
7534
		    // Polylang support
7535
		    elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && !empty( $current_language ) && function_exists( 'pll_is_translated_taxonomy' ) && pll_is_translated_taxonomy( $taxonomy ) ) {
7536
			    $info[ 'join' ][ 'polylang_languages' ] = "
7537
                        LEFT JOIN `{$wpdb->termmeta}` AS `polylang_languages`
7538
                            ON `polylang_languages`.`term_id` = `t`.`term_id`
7539
                                AND `polylang_languages`.`meta_value` = {$current_language_t_id}
7540
                    ";
7541
7542
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`term_id` IS NOT NULL";
7543
		    }
7544
7545
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7546
	    }
7547
	    elseif ( 'user' == $object_type || 'user' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7548
		    $info[ 'table' ] = $wpdb->users;
7549
		    $info[ 'meta_table' ] = $wpdb->usermeta;
7550
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_user';
7551
7552
		    $info[ 'field_id' ] = 'ID';
7553
		    $info[ 'field_index' ] = 'display_name';
7554
		    $info[ 'field_slug' ] = 'user_nicename';
7555
7556
		    $info[ 'meta_field_id' ] = 'user_id';
7557
		    $info[ 'meta_field_index' ] = 'meta_key';
7558
		    $info[ 'meta_field_value' ] = 'meta_value';
7559
7560
		    $info[ 'where' ] = array(
7561
			    'user_status' => '`t`.`user_status` = 0'
7562
		    );
7563
7564
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7565
	    }
7566
	    elseif ( 'comment' == $object_type || 'comment' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7567
		    //$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...
7568
7569
		    $info[ 'table' ] = $wpdb->comments;
7570
		    $info[ 'meta_table' ] = $wpdb->commentmeta;
7571
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_comment';
7572
7573
		    $info[ 'field_id' ] = 'comment_ID';
7574
		    $info[ 'field_index' ] = 'comment_date';
7575
		    $info[ 'field_type' ] = 'comment_type';
7576
		    $info[ 'field_parent' ] = 'comment_parent';
7577
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7578
7579
		    $info[ 'meta_field_id' ] = 'comment_id';
7580
		    $info[ 'meta_field_index' ] = 'meta_key';
7581
		    $info[ 'meta_field_value' ] = 'meta_value';
7582
7583
		    $object = 'comment';
7584
7585
		    $comment_type = ( empty( $object ) ? $name : $object );
7586
7587
		    $comment_type_clause = '`t`.`' . $info[ 'field_type' ] . '` = "' . $comment_type . '"';
7588
7589
		    if ( 'comment' == $comment_type ) {
7590
			    $comment_type_clause = '( ' . $comment_type_clause . ' OR `t`.`' . $info[ 'field_type' ] . '` = "" )';
7591
		    }
7592
7593
		    $info[ 'where' ] = array(
7594
			    'comment_approved' => '`t`.`comment_approved` = 1',
7595
			    'comment_type' => $comment_type_clause
7596
		    );
7597
7598
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` DESC, `t`.`' . $info[ 'field_id' ] . '`';
7599
	    }
7600 View Code Duplication
	    elseif ( in_array( $object_type, array( 'option', 'settings' ) ) || 'settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7601
		    $info[ 'table' ] = $wpdb->options;
7602
		    $info[ 'meta_table' ] = $wpdb->options;
7603
7604
		    $info[ 'field_id' ] = 'option_id';
7605
		    $info[ 'field_index' ] = 'option_name';
7606
7607
		    $info[ 'meta_field_id' ] = 'option_id';
7608
		    $info[ 'meta_field_index' ] = 'option_name';
7609
		    $info[ 'meta_field_value' ] = 'option_value';
7610
7611
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7612
	    }
7613 View Code Duplication
	    elseif ( is_multisite() && ( in_array( $object_type, array( 'site_option', 'site_settings' ) ) || 'site_settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) ) {
7614
		    $info[ 'table' ] = $wpdb->sitemeta;
7615
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7616
7617
		    $info[ 'field_id' ] = 'site_id';
7618
		    $info[ 'field_index' ] = 'meta_key';
7619
7620
		    $info[ 'meta_field_id' ] = 'site_id';
7621
		    $info[ 'meta_field_index' ] = 'meta_key';
7622
		    $info[ 'meta_field_value' ] = 'meta_value';
7623
7624
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7625
	    }
7626
	    elseif ( is_multisite() && 'network' == $object_type ) { // Network = Site
7627
		    $info[ 'table' ] = $wpdb->site;
7628
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7629
7630
		    $info[ 'field_id' ] = 'id';
7631
		    $info[ 'field_index' ] = 'domain';
7632
7633
		    $info[ 'meta_field_id' ] = 'site_id';
7634
		    $info[ 'meta_field_index' ] = 'meta_key';
7635
		    $info[ 'meta_field_value' ] = 'meta_value';
7636
7637
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7638
	    }
7639
	    elseif ( is_multisite() && 'site' == $object_type ) { // Site = Blog
7640
		    $info[ 'table' ] = $wpdb->blogs;
7641
7642
		    $info[ 'field_id' ] = 'blog_id';
7643
		    $info[ 'field_index' ] = 'domain';
7644
		    $info[ 'field_type' ] = 'site_id';
7645
7646
		    $info[ 'where' ] = array(
7647
			    'archived' => '`t`.`archived` = 0',
7648
			    'spam' => '`t`.`spam` = 0',
7649
			    'deleted' => '`t`.`deleted` = 0',
7650
			    'site_id' => '`t`.`' . $info[ 'field_type' ] . '` = ' . (int) get_current_site()->id
7651
		    );
7652
7653
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7654
	    }
7655
	    elseif ( 'table' == $object_type || 'table' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7656
		    $info[ 'table' ] = ( empty( $object ) ? $name : $object );
7657
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . $info[ 'table' ];
7658
7659
		    if ( !empty( $field ) && is_array( $field ) ) {
7660
			    $info[ 'table' ] = pods_var_raw( 'pick_table', pods_var_raw( 'options', $field, $field ) );
7661
			    $info[ 'field_id' ] = pods_var_raw( 'pick_table_id', pods_var_raw( 'options', $field, $field ) );
7662
			    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_var_raw( 'pick_table_index', pods_var_raw( 'options', $field, $field ) );
7663
		    }
7664
	    }
7665
7666
	    $info[ 'table' ] = pods_clean_name( $info[ 'table' ], false, false );
7667
	    $info[ 'meta_table' ] = pods_clean_name( $info[ 'meta_table' ], false, false );
7668
	    $info[ 'pod_table' ] = pods_clean_name( $info[ 'pod_table' ], false, false );
7669
7670
	    $info[ 'field_id' ] = pods_clean_name( $info[ 'field_id' ], false, false );
7671
	    $info[ 'field_index' ] = pods_clean_name( $info[ 'field_index' ], false, false );
7672
	    $info[ 'field_slug' ] = pods_clean_name( $info[ 'field_slug' ], false, false );
7673
7674
	    $info[ 'meta_field_id' ] = pods_clean_name( $info[ 'meta_field_id' ], false, false );
7675
	    $info[ 'meta_field_index' ] = pods_clean_name( $info[ 'meta_field_index' ], false, false );
7676
	    $info[ 'meta_field_value' ] = pods_clean_name( $info[ 'meta_field_value' ], false, false );
7677
7678 View Code Duplication
	    if ( empty( $info[ 'orderby' ] ) )
7679
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '`, `t`.`' . $info[ 'field_id' ] . '`';
7680
7681
	    if ( 'table' == pods_var_raw( 'storage', $info[ 'pod' ] ) && !in_array( $object_type, array( 'pod', 'table' ) ) ) {
7682
		    $info[ 'join' ][ 'd' ] = 'LEFT JOIN `' . $info[ 'pod_table' ] . '` AS `d` ON `d`.`id` = `t`.`' . $info[ 'field_id' ] . '`';
7683
		    //$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...
7684
	    }
7685
7686
	    if ( !empty( $info[ 'pod' ] ) && is_array( $info[ 'pod' ] ) )
7687
		    $info[ 'recurse' ] = true;
7688
7689
	    $info[ 'type' ] = $object_type;
7690
	    $info[ 'object_name' ] = $object;
7691
7692
	    if ( pods_api_cache() ) {
7693
		    if ( ! did_action( 'init' ) ) {
7694
			    $transient .= '_pre_init';
7695
		    }
7696
		    pods_transient_set( $transient, $info );
7697
	    }
7698
7699
7700
	    self::$table_info_cache[ $transient ] = apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
7701
7702
        return self::$table_info_cache[ $transient ];
7703
    }
7704
7705
    /**
7706
     * Export a package
7707
     *
7708
     * $params['pod'] string Pod Type IDs to export
7709
     * $params['template'] string Template IDs to export
7710
     * $params['podpage'] string Pod Page IDs to export
7711
     * $params['helper'] string Helper IDs to export
7712
     *
7713
     * @param array $params An associative array of parameters
7714
     *
7715
     * @return array|bool
7716
     *
7717
     * @since 1.9.0
7718
     * @deprecated 2.0
7719
     */
7720
    public function export_package ( $params ) {
7721
        if ( class_exists( 'Pods_Migrate_Packages' ) )
7722
            return Pods_Migrate_Packages::export( $params );
7723
7724
        return false;
7725
    }
7726
7727
    /**
7728
     * Replace an existing package
7729
     *
7730
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
7731
     *
7732
     * @return bool
7733
     *
7734
     * @since 1.9.8
7735
     * @deprecated 2.0
7736
     */
7737
    public function replace_package ( $data = false ) {
7738
        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...
7739
    }
7740
7741
    /**
7742
     * Import a package
7743
     *
7744
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
7745
     * @param bool $replace (optional) Replace existing items when found
7746
     *
7747
     * @return bool
7748
     *
7749
     * @since 1.9.0
7750
     * @deprecated 2.0
7751
     */
7752
    public function import_package ( $data = false, $replace = false ) {
7753
        if ( class_exists( 'Pods_Migrate_Packages' ) )
7754
            return Pods_Migrate_Packages::import( $data, $replace );
7755
7756
        return false;
7757
    }
7758
7759
    /**
7760
     * Validate a package
7761
     *
7762
     * @param array|string $data (optional) An associative array containing a package, or the json encoded package
7763
     * @param bool $output (optional)
7764
     *
7765
     * @return array|bool
7766
     *
7767
     * @since 1.9.0
7768
     * @deprecated 2.0
7769
     */
7770
    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...
7771
        return true;
7772
    }
7773
7774
    /**
7775
     * Import data from an array or a CSV file.
7776
     *
7777
     * @param mixed $import_data PHP associative array or CSV input
7778
     * @param bool $numeric_mode Use IDs instead of the name field when matching
7779
     * @param string $format Format of import data, options are php or csv
7780
     *
7781
     * @return array IDs of imported items
7782
     *
7783
     * @since 1.7.1
7784
     * @todo This needs some love and use of table_info etc for relationships
7785
     */
7786
    public function import ( $import_data, $numeric_mode = false, $format = null ) {
7787
        /**
7788
         * @var $wpdb wpdb
7789
         */
7790
        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...
7791
7792
        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...
7793
            $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...
7794
7795
        if ( 'csv' == $format && !is_array( $import_data ) ) {
7796
            $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...
7797
7798
            $import_data = $data[ 'items' ];
7799
        }
7800
7801
        pods_query( "SET NAMES utf8" );
7802
        pods_query( "SET CHARACTER SET utf8" );
7803
7804
        // Loop through the array of items
7805
        $ids = array();
7806
7807
        // Test to see if it's an array of arrays
7808
        if ( !is_array( @current( $import_data ) ) )
7809
            $import_data = array( $import_data );
7810
7811
        $pod = $this->load_pod( array( 'name' => $this->pod ) );
7812
7813
        if ( false === $pod )
7814
            return pods_error( __( 'Pod not found', 'pods' ), $this );
7815
7816
        $fields = array_merge( $pod[ 'fields' ], $pod[ 'object_fields' ] );
7817
7818
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
7819
7820
        foreach ( $import_data as $key => $data_row ) {
7821
            $data = array();
7822
7823
            // Loop through each field (use $fields so only valid fields get parsed)
7824
            foreach ( $fields as $field_name => $field_data ) {
7825
                if ( !isset( $data_row[ $field_name ] ) && !isset( $data_row[ $field_data[ 'label' ] ] ) )
7826
                    continue;
7827
7828
                $field_id = $field_data[ 'id' ];
7829
                $type = $field_data[ 'type' ];
7830
                $pick_object = isset( $field_data[ 'pick_object' ] ) ? $field_data[ 'pick_object' ] : '';
7831
                $pick_val = isset( $field_data[ 'pick_val' ] ) ?  $field_data[ 'pick_val' ] : '';
7832
7833
                if ( isset( $data_row[ $field_name] ) )
7834
                    $field_value = $data_row[ $field_name ];
7835
                else
7836
                    $field_value = $data_row[ $field_data[ 'label' ] ];
7837
7838
                if ( null !== $field_value && false !== $field_value && '' !== $field_value ) {
7839
                    if ( 'pick' == $type || in_array( $type, PodsForm::file_field_types() ) ) {
7840
                        $field_values = is_array( $field_value ) ? $field_value : array( $field_value );
7841
                        $pick_values = array();
7842
7843
                        foreach ( $field_values as $pick_value ) {
7844
                            if ( in_array( $type, PodsForm::file_field_types() ) || 'media' == $pick_object ) {
7845
                                $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'";
7846
7847 View Code Duplication
                                if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7848
                                    $where = "`ID` = " . pods_absint( $pick_value );
7849
7850
                                $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = 'attachment' AND {$where} ORDER BY `ID`", $this );
7851
7852
                                if ( !empty( $result ) )
7853
                                    $pick_values[] = $result[ 0 ]->id;
7854
                            }
7855
                            // @todo This could and should be abstracted better and simplified
7856
                            elseif ( 'pick' == $type ) {
7857
                                $related_pod = false;
7858
7859
                                if ( 'pod' == $pick_object )
7860
                                    $related_pod = $this->load_pod( array( 'name' => $pick_val, 'table_info' => true ), false );
7861
7862
                                if ( empty( $related_pod ) ) {
7863
                                    $related_pod = array(
7864
                                        'id' => 0,
7865
                                        'type' => $pick_object
7866
                                    );
7867
                                }
7868
7869
                                if ( in_array( 'taxonomy', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
7870
                                    $where = "`t`.`name` = '" . pods_sanitize( $pick_value ) . "'";
7871
7872 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7873
                                        $where = "`tt`.`term_id` = " . pods_absint( $pick_value );
7874
7875
                                    $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 );
7876
7877
                                    if ( !empty( $result ) )
7878
                                        $pick_values[] = $result[ 0 ]->id;
7879
                                }
7880
                                elseif ( in_array( 'post_type', array( $pick_object, $related_pod[ 'type' ] ) ) || in_array( 'media', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
7881
                                    $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'";
7882
7883 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7884
                                        $where = "`ID` = " . pods_absint( $pick_value );
7885
7886
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = '{$pick_val}' AND {$where} ORDER BY `ID`", $this );
7887
7888
                                    if ( !empty( $result ) )
7889
                                        $pick_values[] = $result[ 0 ]->id;
7890
                                }
7891
                                elseif ( in_array( 'user', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
7892
                                    $where = "`user_login` = '" . pods_sanitize( $pick_value ) . "'";
7893
7894 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7895
                                        $where = "`ID` = " . pods_absint( $pick_value );
7896
7897
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->users}` WHERE {$where} ORDER BY `ID`", $this );
7898
7899
                                    if ( !empty( $result ) )
7900
                                        $pick_values[] = $result[ 0 ]->id;
7901
                                }
7902
                                elseif ( in_array( 'comment', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
7903
                                    $where = "`comment_ID` = " . pods_absint( $pick_value );
7904
7905
                                    $result = pods_query( "SELECT `comment_ID` AS `id` FROM `{$wpdb->comments}` WHERE {$where} ORDER BY `ID`", $this );
7906
7907
                                    if ( !empty( $result ) )
7908
                                        $pick_values[] = $result[ 0 ]->id;
7909
                                }
7910
                                elseif ( in_array( $pick_object, $simple_tableless_objects ) )
7911
                                    $pick_values[] = $pick_value;
7912
                                elseif ( !empty( $related_pod[ 'id' ] ) ) {
7913
                                    $where = "`" . $related_pod[ 'field_index' ] . "` = '" . pods_sanitize( $pick_value ) . "'";
7914
7915
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
7916
                                        $where = "`" . $related_pod[ 'field_id' ] . "` = " . pods_absint( $pick_value );
7917
7918
                                    $result = pods_query( "SELECT `" . $related_pod[ 'field_id' ] . "` AS `id` FROM `" . $related_pod[ 'table' ] . "` WHERE {$where} ORDER BY `" . $related_pod[ 'field_id' ] . "`", $this );
7919
7920
                                    if ( !empty( $result ) )
7921
                                        $pick_values[] = $result[ 0 ]->id;
7922
                                }
7923
                            }
7924
                        }
7925
7926
                        $field_value = implode( ',', $pick_values );
7927
                    }
7928
7929
                    $data[ $field_name ] = $field_value;
7930
                }
7931
            }
7932
7933
            if ( !empty( $data ) ) {
7934
                $params = array(
7935
                    'pod' => $this->pod,
7936
                    'data' => $data
7937
                );
7938
7939
                $ids[] = $this->save_pod_item( $params );
7940
            }
7941
        }
7942
7943
        return $ids;
7944
    }
7945
7946
    /**
7947
     * Export data from a Pod
7948
     *
7949
     * @param string|object $pod The pod name or Pods object
7950
     * @param array $params An associative array of parameters
7951
     *
7952
     * @return array Data arrays of all exported pod items
7953
     * @since 1.7.1
7954
     */
7955
    public function export ( $pod = null, $params = null ) {
7956
7957
        if ( empty( $pod ) ) {
7958
            $pod = $this->pod;
7959
        }
7960
7961
        $find = array(
7962
            'limit' => -1,
7963
            'search' => false,
7964
            'pagination' => false
7965
        );
7966
7967
        if ( !empty( $params ) && isset( $params[ 'params' ] ) ) {
7968
            $find = array_merge( $find, (array) $params[ 'params' ] );
7969
7970
            unset( $params[ 'params' ] );
7971
7972
            $pod = pods( $pod, $find );
7973
        }
7974
        elseif ( !is_object( $pod ) ) {
7975
            $pod = pods( $pod, $find );
7976
        }
7977
7978
        $data = array();
7979
7980
        while ( $pod->fetch() ) {
7981
            $data[ $pod->id() ] = $this->export_pod_item( $params, $pod );
7982
        }
7983
7984
        $data = $this->do_hook( 'export', $data, $pod->pod, $pod );
7985
7986
        return $data;
7987
    }
7988
7989
    /**
7990
     * Convert CSV to a PHP array
7991
     *
7992
     * @param string $data The CSV input
7993
     *
7994
     * @return array
7995
     * @since 1.7.1
7996
     *
7997
     * @deprecated 2.3.5
7998
     */
7999
    public function csv_to_php ( $data, $delimiter = ',' ) {
8000
        pods_deprecated( "PodsAPI->csv_to_php", '2.3.5' );
8001
8002
        $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...
8003
8004
        return $data[ 'items' ];
8005
    }
8006
8007
    /**
8008
     * Clear Pod-related cache
8009
     *
8010
     * @param array $pod
8011
     *
8012
     * @return void
8013
     *
8014
     * @since 2.0
8015
     */
8016
    public function cache_flush_pods ( $pod = null ) {
8017
        /**
8018
         * @var $wpdb wpdb
8019
         */
8020
        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...
8021
8022
        pods_transient_clear( 'pods' );
8023
        pods_transient_clear( 'pods_components' );
8024
8025
        if ( null !== $pod && is_array( $pod ) ) {
8026
            pods_transient_clear( 'pods_pod_' . $pod[ 'name' ] );
8027
            pods_cache_clear( $pod[ 'name' ], 'pods-class' );
8028
8029
            foreach ( $pod[ 'fields' ] as $field ) {
8030
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
8031
            }
8032
8033
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) )
8034
                pods_transient_clear( 'pods_wp_cpt_ct' );
8035
        }
8036
        else
8037
            pods_transient_clear( 'pods_wp_cpt_ct' );
8038
8039
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" );
8040
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" );
8041
8042
        pods_cache_clear( true );
8043
8044
        pods_transient_set( 'pods_flush_rewrites', 1 );
8045
    }
8046
8047
    /**
8048
     * Process a Pod-based form
8049
     *
8050
     * @param mixed $params
8051
     * @param object $obj Pod object
8052
     * @param array $fields Fields being submitted in form ( key => settings )
8053
     * @param string $thank_you URL to send to upon success
8054
     *
8055
     * @return mixed
8056
     *
8057
     * @since 2.0
8058
     */
8059
    public function process_form ( $params, $obj = null, $fields = null, $thank_you = null ) {
8060
        $this->display_errors = false;
8061
8062
        $form = null;
8063
8064
        $nonce = pods_var( '_pods_nonce', $params );
8065
        $pod = pods_var( '_pods_pod', $params );
8066
        $id = pods_var( '_pods_id', $params );
8067
        $uri = pods_var( '_pods_uri', $params );
8068
        $form = pods_var( '_pods_form', $params );
8069
        $location = pods_var( '_pods_location', $params );
8070
8071
        if ( is_object( $obj ) ) {
8072
            $pod = $obj->pod;
8073
            $id = $obj->id();
8074
        }
8075
8076
        if ( !empty( $fields ) ) {
8077
            $fields = array_keys( $fields );
8078
            $form = implode( ',', $fields );
8079
        }
8080
        else
8081
            $fields = explode( ',', $form );
8082
8083
        if ( empty( $nonce ) || empty( $pod ) || empty( $uri ) || empty( $fields ) )
8084
            return pods_error( __( 'Invalid submission', 'pods' ), $this );
8085
8086
        $uid = @session_id();
8087
8088
        if ( is_user_logged_in() )
8089
            $uid = 'user_' . get_current_user_id();
8090
8091
		$field_hash = wp_create_nonce( 'pods_fields_' . $form );
8092
8093
        $action = 'pods_form_' . $pod . '_' . $uid . '_' . $id . '_' . $uri . '_' . $field_hash;
8094
8095
        if ( empty( $uid ) )
8096
            return pods_error( __( 'Access denied for your session, please refresh and try again.', 'pods' ), $this );
8097
8098
        if ( false === wp_verify_nonce( $nonce, $action ) )
8099
            return pods_error( __( 'Access denied, please refresh and try again.', 'pods' ), $this );
8100
8101
        $data = array();
8102
8103
        foreach ( $fields as $field ) {
8104
            $data[ $field ] = pods_var_raw( 'pods_field_' . $field, $params, '' );
8105
        }
8106
8107
        $params = array(
8108
            'pod' => $pod,
8109
            'id' => $id,
8110
            'data' => $data,
8111
            'from' => 'process_form',
8112
			'location' => $location
8113
        );
8114
8115
        $id = $this->save_pod_item( $params );
8116
8117
        if ( 0 < $id && !empty( $thank_you ) ) {
8118
            $thank_you = str_replace( 'X_ID_X', $id, $thank_you );
8119
8120
            pods_redirect( $thank_you );
8121
        }
8122
8123
        return $id;
8124
    }
8125
8126
	/**
8127
	 * Get current language information from Multilingual plugins
8128
	 *
8129
	 * @since 2.6.6
8130
	 * 
8131
	 * @return array
8132
	 */
8133
	public static function get_current_language() {
8134
8135
		/**
8136
		 * @var $sitepress                    SitePress object
8137
		 * @var $icl_adjust_id_url_filter_off boolean
8138
		 * @var $polylang                     object
8139
		 */
8140
		global $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...
8141
8142
		$lang_data        = false;
8143
		$translator       = false;
8144
		$current_language = false;
8145
8146
		// Multilingual support
8147
		if ( is_object( $sitepress ) && ! $icl_adjust_id_url_filter_off && defined( 'ICL_LANGUAGE_CODE' ) ) {
8148
			// WPML support
8149
			$translator = 'WPML';
8150
8151
			// Get the global current language (if set)
8152
			$current_language = ( ICL_LANGUAGE_CODE != 'all' ) ? ICL_LANGUAGE_CODE : '';
8153
8154
		} elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && function_exists( 'pll_current_language' ) ) {
8155
			// Polylang support
8156
			$translator = 'PLL';
8157
8158
			// Get the global current language (if set)
8159
			$current_language = pll_current_language( 'slug' );
8160
		}
8161
8162
		/**
8163
		 * Admin functions that overwrite the current language
8164
		 * 
8165
		 * @since 2.6.6
8166
		 */
8167
		if ( is_admin() && ! empty( $translator ) ) {
8168
			if ( $translator == 'PLL' ) {
8169
				/**
8170
				 * Polylang support
8171
				 * Get the current user's perferred language.
8172
				 * This is a user meta setting that will overwrite the language returned from pll_current_language()
8173
				 * @see polylang/admin/admin-base.php -> init_user()
8174
				 */
8175
				$current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true );
8176
			}
8177
8178
			// Get current language based on the object language if available
8179
			if ( function_exists( 'get_current_screen' ) ) {
8180
				$current_screen = get_current_screen();
8181
8182
				/**
8183
				 * Overwrite the current language if needed for post types
8184
				 */
8185
				if ( isset( $current_screen->base ) && ( $current_screen->base == 'post' || $current_screen->base == 'edit' ) ) {
8186 View Code Duplication
					if ( ! empty( $_GET['post'] ) ) {
8187
						/**
8188
						 * WPML support
8189
						 * In WPML the current language is always set to default on an edit screen
8190
						 * We need to overwrite this when the current object is not-translatable to enable relationships with different languages
8191
						 */
8192
						if (   $translator == 'WPML' 
8193
							&& method_exists( $sitepress, 'is_translated_post_type') 
8194
							&& ! $sitepress->is_translated_post_type( get_post_type( $_GET['post'] ) ) 
8195
						) {
8196
							// Overwrite the current language to nothing if this is a NOT-translatable post_type
8197
							$current_language = '';
8198
						}
8199
8200
						/**
8201
						 * Polylang support (1.5.4+)
8202
						 * In polylang the preferred language could be anything. 
8203
						 * We only want the related objects if they are not translatable OR the same language as the current object
8204
						 */
8205
						if (   $translator == 'PLL' 
8206
							&& function_exists( 'pll_get_post_language' ) 
8207
							&& pll_is_translated_post_type( get_post_type( $_GET['post'] ) ) 
8208
						) {
8209
							// Overwrite the current language if this is a translateable post_type
8210
							$current_language = pll_get_post_language( (int) $_GET['post'] );
8211
						}
8212
					}
8213
8214
					/**
8215
					 * Polylang support (1.0.1+)
8216
					 * In polylang the preferred language could be anything. 
8217
					 * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language
8218
					 */
8219 View Code Duplication
					if (   $translator == 'PLL' 
8220
						&& ! empty( $_GET['new_lang'] ) 
8221
						&& ! empty( $_GET['post_type'] ) 
8222
						&& pll_is_translated_post_type( sanitize_text_field( $_GET['post_type'] ) ) 
8223
					) {
8224
						$current_language = $_GET['new_lang'];
8225
					}
8226
8227
				/**
8228
				 * Overwrite the current language if needed for taxonomies
8229
				 */
8230
				} elseif ( isset( $current_screen->base ) && ( $current_screen->base == 'term' || $current_screen->base == 'edit-tags' ) ) {
8231
					// @todo MAYBE: Similar function like get_post_type for taxonomies so we don't need to check for $_GET['taxonomy']
8232 View Code Duplication
					if ( ! empty( $_GET['taxonomy'] ) ) {
8233
						/**
8234
						 * WPML support
8235
						 * In WPML the current language is always set to default on an edit screen
8236
						 * We need to overwrite this when the current object is not-translatable to enable relationships with different languages
8237
						 */
8238
						if (   $translator == 'WPML' 
8239
							&& method_exists( $sitepress, 'is_translated_taxonomy') 
8240
							&& ! $sitepress->is_translated_taxonomy( $_GET['taxonomy'] ) 
8241
						) {
8242
							// Overwrite the current language to nothing if this is a NOT-translatable taxonomy
8243
							$current_language = '';
8244
						}
8245
8246
						/**
8247
						 * Polylang support (1.5.4+)
8248
						 * In polylang the preferred language could be anything. 
8249
						 * We only want the related objects if they are not translatable OR the same language as the current object
8250
						 */
8251
						if (   $translator == 'PLL' 
8252
							&& ! empty( $_GET['tag_ID'] ) 
8253
							&& function_exists( 'pll_get_term_language' ) 
8254
							&& pll_is_translated_taxonomy( sanitize_text_field( $_GET['taxonomy'] ) ) 
8255
						) {
8256
							// Overwrite the current language if this is a translatable taxonomy
8257
							$current_language = pll_get_term_language( (int) $_GET['tag_ID'] );
8258
						}
8259
					}
8260
8261
					/**
8262
					 * Polylang support (1.0.1+)
8263
					 * In polylang the preferred language could be anything. 
8264
					 * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language
8265
					 */
8266 View Code Duplication
					if (   $translator == 'PLL' 
8267
						&& ! empty( $_GET['new_lang'] ) 
8268
						&& ! empty( $_GET['taxonomy'] ) 
8269
						&& pll_is_translated_taxonomy( sanitize_text_field( $_GET['taxonomy'] ) ) 
8270
					) {
8271
						$current_language = $_GET['new_lang'];
8272
					}
8273
				}
8274
			}
8275
		}
8276
8277
		$current_language = pods_sanitize( sanitize_text_field( $current_language ) );
8278
8279
		if ( ! empty( $current_language ) ) {
8280
			// We need to return language data
8281
			$lang_data = array(
8282
				'language' => $current_language,
8283
				't_id'     => 0,
8284
				'tt_id'    => 0,
8285
				'term'     => null,
8286
			);
8287
8288
			/**
8289
			 * Polylang support
8290
			 * Get the language taxonomy object for the current language
8291
			 */
8292
			if ( $translator == 'PLL' ) {
8293
				$current_language_t = false;
8294
8295
				// Get the language term object
8296
				if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) {
8297
					// Polylang 1.8 and newer
8298
					$current_language_t = PLL()->model->get_language( $current_language );
8299
				} elseif ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) {
8300
					// Polylang 1.2 - 1.7.x
8301
					$current_language_t = $polylang->model->get_language( $current_language );
8302
				} elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) {
8303
					// Polylang 1.1.x and older
8304
					$current_language_t = $polylang->get_language( $current_language );
8305
				}
8306
8307
				// If the language object exists, add it!
8308
				if ( $current_language_t && ! empty( $current_language_t->term_id ) ) {
8309
					$lang_data['t_id']  = (int) $current_language_t->term_id;
8310
					$lang_data['tt_id'] = (int) $current_language_t->term_taxonomy_id;
8311
					$lang_data['term']  = $current_language_t;
8312
				}
8313
			}
8314
		}
8315
8316
		/**
8317
		 * Override language data used by Pods.
8318
		 *
8319
		 * @since 2.6.6
8320
		 *
8321
		 * @param array|false    $lang_data {
8322
		 *      Language data
8323
		 *
8324
		 *      @type string       $language  Language slug
8325
		 *      @type int          $t_id      Language term_id
8326
		 *      @type int          $tt_id     Language term_taxonomy_id
8327
		 *      @type WP_Term      $term      Language term object
8328
		 * }
8329
		 * @param string|boolean $translator Language plugin used
8330
		 */
8331
		$lang_data = apply_filters( 'pods_get_current_language', $lang_data, $translator );
8332
8333
		return $lang_data;
8334
8335
	}
8336
8337
    /**
8338
     * Handle filters / actions for the class
8339
     *
8340
     * @since 2.0
8341
     */
8342 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...
8343
        $args = func_get_args();
8344
        if ( empty( $args ) )
8345
            return false;
8346
        $name = array_shift( $args );
8347
        return pods_do_hook( "api", $name, $args, $this );
8348
    }
8349
8350
    /**
8351
     * Handle variables that have been deprecated
8352
     *
8353
     * @since 2.0
8354
     */
8355
    public function __get ( $name ) {
8356
        $name = (string) $name;
8357
8358 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8359
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8360
            $this->deprecated = new PodsAPI_Deprecated( $this );
8361
        }
8362
8363
        $var = null;
8364
8365
        if ( isset( $this->deprecated->{$name} ) ) {
8366
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8367
8368
            $var = $this->deprecated->{$name};
8369
        }
8370
        else
8371
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8372
8373
        return $var;
8374
    }
8375
8376
    /**
8377
     * Handle methods that have been deprecated
8378
     *
8379
     * @since 2.0
8380
     */
8381
    public function __call ( $name, $args ) {
8382
        $name = (string) $name;
8383
8384 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8385
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8386
            $this->deprecated = new PodsAPI_Deprecated( $this );
8387
        }
8388
8389
        if ( method_exists( $this->deprecated, $name ) )
8390
            return call_user_func_array( array( $this->deprecated, $name ), $args );
8391
        else
8392
            pods_deprecated( "PodsAPI::{$name}", '2.0' );
8393
    }
8394
}
8395