Completed
Pull Request — 2.x (#4370)
by
unknown
05:02
created

PodsAPI::get_changed_fields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package Pods
4
 */
5
class PodsAPI {
6
7
    /**
8
     * @var PodsAPI
9
     */
10
    static $instance = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $instance.

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

class A {
    var $property;
}

the property is implicitly global.

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

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

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

class A {
    var $property;
}

the property is implicitly global.

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

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

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

Please refer to the PHP core documentation on constructors.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
814
815
        if ( 'post_type' == $object_type )
816
            $object_type = 'post';
817
818
        if ( 'post' == $object_type ) {
819
            pods_query( "UPDATE `{$wpdb->posts}` SET `post_type` = %s WHERE `post_type` = %s", array(
820
                $new_name,
821
                $old_name
822
            ) );
823
        }
824
        elseif ( 'taxonomy' == $object_type ) {
825
            pods_query( "UPDATE `{$wpdb->term_taxonomy}` SET `taxonomy` = %s WHERE `taxonomy` = %s", array(
826
                $new_name,
827
                $old_name
828
            ) );
829
        }
830
        elseif ( 'comment' == $object_type ) {
831
            pods_query( "UPDATE `{$wpdb->comments}` SET `comment_type` = %s WHERE `comment_type` = %s", array(
832
                $new_name,
833
                $old_name
834
            ) );
835
        }
836
        elseif ( 'settings' == $object_type ) {
837
            pods_query( "UPDATE `{$wpdb->options}` SET `option_name` = REPLACE( `option_name`, %s, %s ) WHERE `option_name` LIKE '" . pods_sanitize_like( $old_name ) . "_%'", array(
838
                $new_name . '_',
839
                $old_name . '_'
840
            ) );
841
        }
842
843
        return true;
844
    }
845
846
    /**
847
     * Get a list of core WP object fields for a specific object
848
     *
849
     * @param string $object The pod type to look for, possible values: post_type, user, comment, taxonomy
850
     * @param array $pod Array of Pod data
851
     * @param boolean $refresh Whether to force refresh the information
852
     *
853
     * @return array Array of fields
854
     *
855
     * @since 2.0
856
     */
857
    public function get_wp_object_fields ( $object = 'post_type', $pod = null, $refresh = false ) {
858
        $pod_name = pods_var_raw( 'name', $pod, $object, null, true );
859
860
		if ( 'media' == $pod_name ) {
861
			$object = 'post_type';
862
			$pod_name = 'attachment';
863
		}
864
865
        $fields = false;
866
867
        if ( pods_api_cache() )
868
            $fields = pods_transient_get( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ) );
869
870
        if ( false !== $fields && !$refresh )
871
            return $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
872
873
        $fields = array();
874
875
        if ( 'post_type' == $object ) {
876
            $fields = array(
877
	            'ID' => array(
878
		            'name' => 'ID',
879
		            'label' => 'ID',
880
		            'type' => 'number',
881
		            'alias' => array( 'id' ),
882
	                'options' => array(
883
                        'number_format' => '9999.99'
884
	                )
885
	            ),
886
                'post_title' => array(
887
                    'name' => 'post_title',
888
                    'label' => 'Title',
889
                    'type' => 'text',
890
                    'alias' => array( 'title', 'name' ),
891
                    'options' => array(
892
                        'display_filter' => 'the_title',
893
                        'display_filter_args' => array( 'post_ID' )
894
                    )
895
                ),
896
                'post_content' => array(
897
                    'name' => 'post_content',
898
                    'label' => 'Content',
899
                    'type' => 'wysiwyg',
900
                    'alias' => array( 'content' ),
901
                    'options' => array(
902
                        'wysiwyg_allowed_html_tags' => '',
903
                        'display_filter' => 'the_content',
904
                        'pre_save' => 0
905
                    )
906
                ),
907
                'post_excerpt' => array(
908
                    'name' => 'post_excerpt',
909
                    'label' => 'Excerpt',
910
                    'type' => 'paragraph',
911
                    'alias' => array( 'excerpt' ),
912
                    'options' => array(
913
                        'paragraph_allow_html' => 1,
914
                        'paragraph_allowed_html_tags' => '',
915
                        'display_filter' => 'the_excerpt',
916
                        'pre_save' => 0
917
                    )
918
                ),
919
                'post_author' => array(
920
                    'name' => 'post_author',
921
                    'label' => 'Author',
922
                    'type' => 'pick',
923
                    'alias' => array( 'author' ),
924
                    'pick_object' => 'user',
925
                    'options' => array(
926
                        'pick_format_type' => 'single',
927
                        'pick_format_single' => 'autocomplete',
928
                        'default_value' => '{@user.ID}'
929
                    )
930
                ),
931
                'post_date' => array(
932
                    'name' => 'post_date',
933
                    'label' => 'Publish Date',
934
                    'type' => 'datetime',
935
                    'alias' => array( 'created', 'date' )
936
                ),
937
                'post_date_gmt' => array(
938
                    'name' => 'post_date_gmt',
939
                    'label' => 'Publish Date (GMT)',
940
                    'type' => 'datetime',
941
                    'alias' => array(),
942
                    'hidden' => true
943
                ),
944
                'post_status' => array(
945
                    'name' => 'post_status',
946
                    'label' => 'Status',
947
                    'type' => 'pick',
948
                    'pick_object' => 'post-status',
949
                    'default' => $this->do_hook( 'default_status_' . $pod_name, pods_var( 'default_status', pods_var_raw( 'options', $pod ), 'draft', null, true ), $pod ),
950
                    'alias' => array( 'status' )
951
                ),
952
                'comment_status' => array(
953
                    'name' => 'comment_status',
954
                    'label' => 'Comment Status',
955
                    'type' => 'text',
956
                    'default' => get_option( 'default_comment_status', 'open' ),
957
                    'alias' => array(),
958
                    'data' => array(
959
                        'open' => __( 'Open', 'pods' ),
960
                        'closed' => __( 'Closed', 'pods' )
961
                    )
962
                ),
963
                'ping_status' => array(
964
                    'name' => 'ping_status',
965
                    'label' => 'Ping Status',
966
                    'default' => get_option( 'default_ping_status', 'open' ),
967
                    'type' => 'text',
968
                    'alias' => array(),
969
                    'data' => array(
970
                        'open' => __( 'Open', 'pods' ),
971
                        'closed' => __( 'Closed', 'pods' )
972
                    )
973
                ),
974
                'post_password' => array(
975
                    'name' => 'post_password',
976
                    'label' => 'Password',
977
                    'type' => 'text',
978
                    'alias' => array()
979
                ),
980
                'post_name' => array(
981
                    'name' => 'post_name',
982
                    'label' => 'Permalink',
983
                    'type' => 'slug',
984
                    'alias' => array( 'slug', 'permalink' )
985
                ),
986
                'to_ping' => array(
987
                    'name' => 'to_ping',
988
                    'label' => 'To Ping',
989
                    'type' => 'text',
990
                    'alias' => array(),
991
                    'hidden' => true
992
                ),
993
                'pinged' => array(
994
                    'name' => 'pinged',
995
                    'label' => 'Pinged',
996
                    'type' => 'text',
997
                    'alias' => array(),
998
                    'hidden' => true
999
                ),
1000
                'post_modified' => array(
1001
                    'name' => 'post_modified',
1002
                    'label' => 'Last Modified Date',
1003
                    'type' => 'datetime',
1004
                    'alias' => array( 'modified' ),
1005
                    'hidden' => true
1006
                ),
1007
                'post_modified_gmt' => array(
1008
                    'name' => 'post_modified_gmt',
1009
                    'label' => 'Last Modified Date (GMT)',
1010
                    'type' => 'datetime',
1011
                    'alias' => array(),
1012
                    'hidden' => true
1013
                ),
1014
                'post_content_filtered' => array(
1015
                    'name' => 'post_content_filtered',
1016
                    'label' => 'Content (filtered)',
1017
                    'type' => 'paragraph',
1018
                    'alias' => array(),
1019
                    'hidden' => true,
1020
                    'options' => array(
1021
                        'paragraph_allow_html' => 1,
1022
                        'paragraph_oembed' => 1,
1023
                        'paragraph_wptexturize' => 1,
1024
                        'paragraph_convert_chars' => 1,
1025
                        'paragraph_wpautop' => 1,
1026
                        'paragraph_allow_shortcode' => 1,
1027
                        'paragraph_allowed_html_tags' => ''
1028
                    )
1029
                ),
1030
                'post_parent' => array(
1031
                    'name' => 'post_parent',
1032
                    'label' => 'Parent',
1033
                    'type' => 'pick',
1034
                    'pick_object' => 'post_type',
1035
                    'pick_val' => '__current__',
1036
                    'alias' => array( 'parent' ),
1037
                    'data' => array(),
1038
                    'hidden' => true
1039
                ),
1040
                'guid' => array(
1041
                    'name' => 'guid',
1042
                    'label' => 'GUID',
1043
                    'type' => 'text',
1044
                    'alias' => array(),
1045
                    'hidden' => true
1046
                ),
1047
                'menu_order' => array(
1048
                    'name' => 'menu_order',
1049
                    'label' => 'Menu Order',
1050
                    'type' => 'number',
1051
                    'alias' => array(),
1052
	                'options' => array(
1053
                        'number_format' => '9999.99'
1054
	                )
1055
                ),
1056
                'post_type' => array(
1057
                    'name' => 'post_type',
1058
                    'label' => 'Type',
1059
                    'type' => 'text',
1060
                    'alias' => array( 'type' ),
1061
                    'hidden' => true
1062
                ),
1063
                'post_mime_type' => array(
1064
                    'name' => 'post_mime_type',
1065
                    'label' => 'Mime Type',
1066
                    'type' => 'text',
1067
                    'alias' => array(),
1068
                    'hidden' => true
1069
                ),
1070
                'comment_count' => array(
1071
                    'name' => 'comment_count',
1072
                    'label' => 'Comment Count',
1073
                    'type' => 'number',
1074
                    'alias' => array(),
1075
                    'hidden' => true
1076
                ),
1077
                'comments' => array(
1078
                    'name' => 'comments',
1079
                    'label' => 'Comments',
1080
                    'type' => 'comment',
1081
					'pick_object' => 'comment',
1082
					'pick_val' => 'comment',
1083
                    'alias' => array(),
1084
                    'hidden' => true,
1085
					'options' => array(
1086
						'comment_format_type' => 'multi'
1087
					)
1088
                )
1089
            );
1090
1091
            if ( !empty( $pod ) ) {
1092
                $taxonomies = get_object_taxonomies( $pod_name, 'objects' );
1093
1094
                foreach ( $taxonomies as $taxonomy ) {
1095
                    $fields[ $taxonomy->name ] = array(
1096
                        'name' => $taxonomy->name,
1097
                        'label' => $taxonomy->labels->name,
1098
                        'type' => 'taxonomy',
1099
						'pick_object' => 'taxonomy',
1100
						'pick_val' => $taxonomy->name,
1101
                        'alias' => array(),
1102
                        'hidden' => true,
1103
						'options' => array(
1104
							'taxonomy_format_type' => 'multi'
1105
						)
1106
                    );
1107
                }
1108
            }
1109
        }
1110
        elseif ( 'user' == $object ) {
1111
            $fields = array(
1112
	            'ID' => array(
1113
		            'name' => 'ID',
1114
		            'label' => 'ID',
1115
		            'type' => 'number',
1116
		            'alias' => array( 'id' ),
1117
	                'options' => array(
1118
                        'number_format' => '9999.99'
1119
	                )
1120
	            ),
1121
                'user_login' => array(
1122
                    'name' => 'user_login',
1123
                    'label' => 'Title',
1124
                    'type' => 'text',
1125
                    'alias' => array( 'login' ),
1126
                    'options' => array(
1127
                        'required' => 1
1128
                    )
1129
                ),
1130
                'user_nicename' => array(
1131
                    'name' => 'user_nicename',
1132
                    'label' => 'Permalink',
1133
                    'type' => 'slug',
1134
                    'alias' => array( 'nicename', 'slug', 'permalink' )
1135
                ),
1136
                'display_name' => array(
1137
                    'name' => 'display_name',
1138
                    'label' => 'Display Name',
1139
                    'type' => 'text',
1140
                    'alias' => array( 'title', 'name' )
1141
                ),
1142
                'user_pass' => array(
1143
                    'name' => 'user_pass',
1144
                    'label' => 'Password',
1145
                    'type' => 'text',
1146
                    'alias' => array( 'password', 'pass' ),
1147
                    'options' => array(
1148
                        'required' => 1,
1149
                        'text_format_type' => 'password'
1150
                    )
1151
                ),
1152
                'user_email' => array(
1153
                    'name' => 'user_email',
1154
                    'label' => 'E-mail',
1155
                    'type' => 'text',
1156
                    'alias' => array( 'email' ),
1157
                    'options' => array(
1158
                        'required' => 1,
1159
                        'text_format_type' => 'email'
1160
                    )
1161
                ),
1162
                'user_url' => array(
1163
                    'name' => 'user_url',
1164
                    'label' => 'URL',
1165
                    'type' => 'text',
1166
                    'alias' => array( 'url', 'website' ),
1167
                    'options' => array(
1168
                        'required' => 0,
1169
                        'text_format_type' => 'website',
1170
                        'text_format_website' => 'normal'
1171
                    )
1172
                ),
1173
                'user_registered' => array(
1174
                    'name' => 'user_registered',
1175
                    'label' => 'Registration Date',
1176
                    'type' => 'date',
1177
                    'alias' => array( 'created', 'date', 'registered' ),
1178
                    'options' => array(
1179
                        'date_format_type' => 'datetime'
1180
                    )
1181
                )
1182
            );
1183
        }
1184
        elseif ( 'comment' == $object ) {
1185
            $fields = array(
1186
	            'comment_ID' => array(
1187
		            'name' => 'comment_ID',
1188
		            'label' => 'ID',
1189
		            'type' => 'number',
1190
		            'alias' => array( 'id', 'ID', 'comment_id' ),
1191
	                'options' => array(
1192
                        'number_format' => '9999.99'
1193
	                )
1194
	            ),
1195
                'comment_content' => array(
1196
                    'name' => 'comment_content',
1197
                    'label' => 'Content',
1198
                    'type' => 'wysiwyg',
1199
                    'alias' => array( 'content' )
1200
                ),
1201
                'comment_approved' => array(
1202
                    'name' => 'comment_approved',
1203
                    'label' => 'Approved',
1204
                    'type' => 'number',
1205
                    'alias' => array( 'approved' ),
1206
	                'options' => array(
1207
                        'number_format' => '9999.99'
1208
	                )
1209
                ),
1210
                'comment_post_ID' => array(
1211
                    'name' => 'comment_post_ID',
1212
                    'label' => 'Post',
1213
                    'type' => 'pick',
1214
                    'alias' => array( 'post', 'post_id' ),
1215
                    'data' => array()
1216
                ),
1217
                'user_id' => array(
1218
                    'name' => 'user_id',
1219
                    'label' => 'Author',
1220
                    'type' => 'pick',
1221
                    'alias' => array( 'author' ),
1222
                    'pick_object' => 'user',
1223
                    'data' => array()
1224
                ),
1225
                'comment_date' => array(
1226
                    'name' => 'comment_date',
1227
                    'label' => 'Date',
1228
                    'type' => 'date',
1229
                    'alias' => array( 'created', 'date' ),
1230
                    'options' => array(
1231
                        'date_format_type' => 'datetime'
1232
                    )
1233
                ),
1234
                'comment_author' => array(
1235
                    'name' => 'comment_author',
1236
                    'label' => 'Author',
1237
                    'type' => 'text',
1238
                    'alias' => array( 'author' )
1239
                ),
1240
                'comment_author_email' => array(
1241
                    'name' => 'comment_author_email',
1242
                    'label' => 'Author E-mail',
1243
                    'type' => 'email',
1244
                    'alias' => array( 'author_email' )
1245
                ),
1246
                'comment_author_url' => array(
1247
                    'name' => 'comment_author_url',
1248
                    'label' => 'Author URL',
1249
                    'type' => 'text',
1250
                    'alias' => array( 'author_url' )
1251
                ),
1252
                'comment_author_IP' => array(
1253
                    'name' => 'comment_author_IP',
1254
                    'label' => 'Author IP',
1255
                    'type' => 'text',
1256
                    'alias' => array( 'author_IP' )
1257
                ),
1258
                'comment_type' => array(
1259
                    'name' => 'comment_type',
1260
                    'label' => 'Type',
1261
                    'type' => 'text',
1262
                    'alias' => array( 'type' ),
1263
                    'hidden' => true
1264
                ),
1265
                'comment_parent' => array(
1266
                    'name' => 'comment_parent',
1267
                    'label' => 'Parent',
1268
                    'type' => 'pick',
1269
                    'pick_object' => 'comment',
1270
                    'pick_val' => '__current__',
1271
                    'alias' => array( 'parent' ),
1272
                    'data' => array(),
1273
                    'hidden' => true
1274
                )
1275
            );
1276
        }
1277
        elseif ( 'taxonomy' == $object ) {
1278
            $fields = array(
1279
	            'term_id' => array(
1280
		            'name' => 'term_id',
1281
		            'label' => 'ID',
1282
		            'type' => 'number',
1283
		            'alias' => array( 'id', 'ID' ),
1284
	                'options' => array(
1285
                        'number_format' => '9999.99'
1286
	                )
1287
	            ),
1288
                'name' => array(
1289
                    'name' => 'name',
1290
                    'label' => 'Title',
1291
                    'type' => 'text',
1292
                    'alias' => array( 'title' )
1293
                ),
1294
                'slug' => array(
1295
                    'name' => 'slug',
1296
                    'label' => 'Permalink',
1297
                    'type' => 'slug',
1298
                    'alias' => array( 'permalink' )
1299
                ),
1300
                'description' => array(
1301
                    'name' => 'description',
1302
                    'label' => 'Description',
1303
                    'type' => 'wysiwyg',
1304
                    'alias' => array( 'content' )
1305
                ),
1306
                'taxonomy' => array(
1307
                    'name' => 'taxonomy',
1308
                    'label' => 'Taxonomy',
1309
                    'type' => 'text',
1310
                    'alias' => array()
1311
                ),
1312
                'parent' => array(
1313
                    'name' => 'parent',
1314
                    'label' => 'Parent',
1315
                    'type' => 'pick',
1316
                    'pick_object' => 'taxonomy',
1317
                    'pick_val' => '__current__',
1318
                    'alias' => array( 'parent' ),
1319
                    'data' => array(),
1320
                    'hidden' => true
1321
                ),
1322
                'term_taxonomy_id' => array(
1323
                    'name' => 'term_taxonomy_id',
1324
                    'label' => 'Term Taxonomy ID',
1325
                    'type' => 'number',
1326
                    'alias' => array(),
1327
                    'hidden' => true,
1328
	                'options' => array(
1329
                        'number_format' => '9999.99'
1330
	                )
1331
                ),
1332
                'term_group' => array(
1333
                    'name' => 'term_group',
1334
                    'label' => 'Term Group',
1335
                    'type' => 'number',
1336
                    'alias' => array( 'group' ),
1337
                    'hidden' => true,
1338
	                'options' => array(
1339
                        'number_format' => '9999.99'
1340
	                )
1341
                ),
1342
                'count' => array(
1343
                    'name' => 'count',
1344
                    'label' => 'Count',
1345
                    'type' => 'number',
1346
                    'alias' => array(),
1347
                    'hidden' => true,
1348
	                'options' => array(
1349
                        'number_format' => '9999.99'
1350
	                )
1351
                )
1352
            );
1353
        }
1354
1355
        $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
1356
1357
        foreach ( $fields as $field => $options ) {
1358
            if ( !isset( $options[ 'alias' ] ) )
1359
                $options[ 'alias' ] = array();
1360
            else
1361
                $options[ 'alias' ] = (array) $options[ 'alias' ];
1362
1363
            if ( !isset( $options[ 'name' ] ) )
1364
                $options[ 'name' ] = $field;
1365
1366
            $fields[ $field ] = $options;
1367
        }
1368
1369
        $fields = PodsForm::fields_setup( $fields );
1370
1371 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
1372
            pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields );
1373
1374
        return $fields;
1375
    }
1376
1377
    /**
1378
     *
1379
     * @see PodsAPI::save_pod
1380
     *
1381
     * Add a Pod via the Wizard
1382
     *
1383
     * $params['create_extend'] string Create or Extend a Content Type
1384
     * $params['create_pod_type'] string Pod Type (for Creating)
1385
     * $params['create_name'] string Pod Name (for Creating)
1386
     * $params['create_label_plural'] string Plural Label (for Creating)
1387
     * $params['create_label_singular'] string Singular Label (for Creating)
1388
     * $params['create_storage'] string Storage Type (for Creating Post Types)
1389
     * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies)
1390
     * $params['extend_pod_type'] string Pod Type (for Extending)
1391
     * $params['extend_post_type'] string Post Type (for Extending Post Types)
1392
     * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies)
1393
     * $params['extend_storage'] string Storage Type (for Extending Post Types / Users / Comments)
1394
     *
1395
     * @param array $params An associative array of parameters
1396
     *
1397
     * @return bool|int Pod ID
1398
     * @since 2.0
1399
     */
1400
    public function add_pod ( $params ) {
1401
        $defaults = array(
1402
            'create_extend' => 'create',
1403
            'create_pod_type' => 'post_type',
1404
1405
            'create_name' => '',
1406
            'create_label_singular' => '',
1407
            'create_label_plural' => '',
1408
            'create_storage' => 'meta',
1409
            'create_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' ),
1410
1411
            'create_setting_name' => '',
1412
            'create_label_title' => '',
1413
            'create_label_menu' => '',
1414
            'create_menu_location' => 'settings',
1415
1416
            'extend_pod_type' => 'post_type',
1417
            'extend_post_type' => 'post',
1418
            'extend_taxonomy' => 'category',
1419
            'extend_table' => '',
1420
            'extend_storage' => 'meta',
1421
            'extend_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'table' ),
1422
        );
1423
1424
        $params = (object) array_merge( $defaults, (array) $params );
1425
1426
        if ( empty( $params->create_extend ) || !in_array( $params->create_extend, array( 'create', 'extend' ) ) )
1427
            return pods_error( __( 'Please choose whether to Create or Extend a Content Type', 'pods' ), $this );
1428
1429
        $pod_params = array(
1430
            'name' => '',
1431
            'label' => '',
1432
            'type' => '',
1433
            'storage' => 'table',
1434
            'object' => '',
1435
            'options' => array()
1436
        );
1437
1438
        if ( 'create' == $params->create_extend ) {
1439
            $label = ucwords( str_replace( '_', ' ', $params->create_name ) );
1440
1441
            if ( !empty( $params->create_label_singular ) )
1442
                $label = $params->create_label_singular;
1443
1444
            $pod_params[ 'name' ] = $params->create_name;
1445
            $pod_params[ 'label' ] = ( !empty( $params->create_label_plural ) ? $params->create_label_plural : $label );
1446
            $pod_params[ 'type' ] = $params->create_pod_type;
1447
            $pod_params[ 'options' ] = array(
1448
                'label_singular' => ( !empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params[ 'label' ] ),
1449
                'public' => 1,
1450
                'show_ui' => 1
1451
            );
1452
1453
            // Auto-generate name if not provided
1454
            if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'options' ][ 'label_singular' ] ) )
1455
                $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'options' ][ 'label_singular' ] );
1456
1457
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1458
                if ( empty(  $pod_params[ 'name' ] ) )
1459
                    return pods_error( 'Please enter a Name for this Pod', $this );
1460
1461
                $pod_params[ 'storage' ] = $params->create_storage;
1462
1463
                if ( pods_tableless() )
1464
                    $pod_params[ 'storage' ] = 'meta';
1465
            }
1466
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1467
                if ( empty(  $pod_params[ 'name' ] ) )
1468
                    return pods_error( 'Please enter a Name for this Pod', $this );
1469
1470
                $pod_params[ 'storage' ] = $params->create_storage_taxonomy;
1471
1472
                if ( pods_tableless() )
1473
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1474
1475
				$pod_params['options']['hierarchical'] = 1;
1476
            }
1477
            elseif ( 'pod' == $pod_params[ 'type' ] ) {
1478
                if ( empty(  $pod_params[ 'name' ] ) )
1479
                    return pods_error( 'Please enter a Name for this Pod', $this );
1480
1481
                if ( pods_tableless() ) {
1482
                    $pod_params[ 'type' ] = 'post_type';
1483
                    $pod_params[ 'storage' ] = 'meta';
1484
                }
1485
            }
1486
            elseif ( 'settings' == $pod_params[ 'type' ] ) {
1487
                $pod_params[ 'name' ] = $params->create_setting_name;
1488
                $pod_params[ 'label' ] = ( !empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) );
1489
                $pod_params[ 'options' ] = array(
1490
                    'menu_name' => ( !empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params[ 'label' ] ),
1491
                    'menu_location' => $params->create_menu_location
1492
                );
1493
                $pod_params[ 'storage' ] = 'none';
1494
1495
                // Auto-generate name if not provided
1496
                if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'label' ] ) )
1497
                    $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'label' ] );
1498
1499
                if ( empty( $pod_params[ 'name' ] ) )
1500
                    return pods_error( 'Please enter a Name for this Pod', $this );
1501
            }
1502
        }
1503
        elseif ( 'extend' == $params->create_extend ) {
1504
            $pod_params[ 'type' ] = $params->extend_pod_type;
1505
1506
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1507
                $pod_params[ 'storage' ] = $params->extend_storage;
1508
1509
                if ( pods_tableless() )
1510
                    $pod_params[ 'storage' ] = 'meta';
1511
1512
                $pod_params[ 'name' ] = $params->extend_post_type;
1513
            }
1514
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1515
                $pod_params[ 'storage' ] = $params->extend_storage_taxonomy;
1516
1517
                if ( pods_tableless() )
1518
                    $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1519
1520
                $pod_params[ 'name' ] = $params->extend_taxonomy;
1521
            }
1522
            elseif ( 'table' == $pod_params[ 'type' ] ) {
1523
                $pod_params[ 'storage' ] = 'table';
1524
                $pod_params[ 'name' ] = $params->extend_table;
1525
            }
1526
            else {
1527
                $pod_params[ 'storage' ] = $params->extend_storage;
1528
1529
                if ( pods_tableless() )
1530
                    $pod_params[ 'storage' ] = 'meta';
1531
1532
                $pod_params[ 'name' ] = $params->extend_pod_type;
1533
            }
1534
1535
            $pod_params[ 'label' ] = ucwords( str_replace( '_', ' ', $pod_params[ 'name' ] ) );
1536
            $pod_params[ 'object' ] = $pod_params[ 'name' ];
1537
        }
1538
1539
        if ( empty( $pod_params[ 'object' ] ) ) {
1540
            if ( 'post_type' == $pod_params[ 'type' ] ) {
1541
                $check = get_post_type_object( $pod_params[ 'name' ] );
1542
1543 View Code Duplication
                if ( !empty( $check ) )
1544
                    return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1545
1546
                $pod_params[ 'options' ][ 'supports_title' ] = 1;
1547
                $pod_params[ 'options' ][ 'supports_editor' ] = 1;
1548
            }
1549
            elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1550
                $check = get_taxonomy( $pod_params[ 'name' ] );
1551
1552 View Code Duplication
                if ( !empty( $check ) )
1553
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1554
            }
1555
        }
1556
1557
        if ( !empty( $pod_params ) )
1558
            return $this->save_pod( $pod_params );
1559
1560
        return false;
1561
    }
1562
1563
    /**
1564
     * Add or edit a Pod
1565
     *
1566
     * $params['id'] int The Pod ID
1567
     * $params['name'] string The Pod name
1568
     * $params['label'] string The Pod label
1569
     * $params['type'] string The Pod type
1570
     * $params['object'] string The object being extended (if any)
1571
     * $params['storage'] string The Pod storage
1572
     * $params['options'] array Options
1573
     *
1574
     * @param array $params An associative array of parameters
1575
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
1576
     * @param bool|int $db (optional) Whether to save into the DB or just return Pod array.
1577
     *
1578
     * @return int Pod ID
1579
     * @since 1.7.9
1580
     */
1581
    public function save_pod ( $params, $sanitized = false, $db = true ) {
1582
        $tableless_field_types = PodsForm::tableless_field_types();
1583
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
1584
1585
        $load_params = (object) $params;
1586
1587
        if ( isset( $load_params->id ) && isset( $load_params->name ) )
1588
            unset( $load_params->name );
1589
1590
        if ( isset( $load_params->old_name ) )
1591
            $load_params->name = $load_params->old_name;
1592
1593
        $load_params->table_info = true;
1594
1595
        $pod = $this->load_pod( $load_params, false );
1596
1597
        $params = (object) $params;
1598
1599
        if ( false === $sanitized )
1600
            $params = pods_sanitize( $params );
1601
1602
        $old_id = $old_name = $old_storage = null;
1603
1604
        $old_fields = $old_options = array();
1605
1606
		if ( isset( $params->name ) && ! isset( $params->object ) ) {
1607
			$params->name = pods_clean_name( $params->name );
1608
		}
1609
1610
        if ( !empty( $pod ) ) {
1611
            if ( isset( $params->id ) && 0 < $params->id )
1612
                $old_id = $params->id;
1613
1614
            $params->id = $pod[ 'id' ];
1615
1616
            $old_name = $pod[ 'name' ];
1617
            $old_storage = $pod[ 'storage' ];
1618
            $old_fields = $pod[ 'fields' ];
1619
            $old_options = $pod[ 'options' ];
1620
1621
            if ( !isset( $params->name ) && empty( $params->name ) )
1622
                $params->name = $pod[ 'name' ];
1623
1624
            if ( $old_name != $params->name && false !== $this->pod_exists( array( 'name' => $params->name ) ) )
1625
                return pods_error( sprintf( __( 'Pod %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1626
1627
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'user', 'comment', 'media' ) ) && in_array( $pod[ 'object' ], array( 'user', 'comment', 'media' ) ) )
1628
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1629
1630
            if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && !empty( $pod[ 'object' ] ) && $pod[ 'object' ] == $old_name )
1631
                return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1632
1633
            if ( $old_id != $params->id ) {
1634
                if ( $params->type == $pod[ 'type' ] && isset( $params->object ) && $params->object == $pod[ 'object' ] )
1635
                    return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this );
1636
                else
1637
                    return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this );
1638
            }
1639
        }
1640
		elseif ( in_array( $params->name, array( 'order','orderby','post_type' ) ) && 'post_type' == pods_var( 'type', $params ) ) {
1641
			return pods_error( sprintf( 'There are certain names that a Custom Post Types cannot be named and unfortunately, %s is one of them.', $params->name ), $this );
1642
		}
1643
        else {
1644
            $pod = array(
1645
                'id' => 0,
1646
                'name' => $params->name,
1647
                'label' => $params->name,
1648
                'description' => '',
1649
                'type' => 'pod',
1650
                'storage' => 'table',
1651
                'object' => '',
1652
                'alias' => '',
1653
                'options' => array(),
1654
                'fields' => array()
1655
            );
1656
        }
1657
1658
        // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite)
1659
        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1660
            $pod[ 'fields' ] = array();
1661
            $pod[ 'options' ] = array();
1662
        }
1663
1664
        // Setup options
1665
        $options = get_object_vars( $params );
1666
1667
        if ( isset( $options[ 'method' ] ) )
1668
            unset( $options[ 'method' ] );
1669
1670
        $options_ignore = array(
1671
            'object_type',
1672
            'object_name',
1673
            'table',
1674
            'meta_table',
1675
            'pod_table',
1676
            'field_id',
1677
            'field_index',
1678
            'field_slug',
1679
            'field_type',
1680
            'field_parent',
1681
            'field_parent_select',
1682
            'meta_field_id',
1683
            'meta_field_index',
1684
            'meta_field_value',
1685
            'pod_field_id',
1686
            'pod_field_index',
1687
            'object_fields',
1688
            'join',
1689
            'where',
1690
            'where_default',
1691
            'orderby',
1692
            'pod',
1693
            'recurse',
1694
            'table_info',
1695
            'attributes',
1696
            'group',
1697
            'grouped',
1698
            'developer_mode',
1699
            'dependency',
1700
            'depends-on',
1701
            'excludes-on'
1702
        );
1703
1704
        foreach ( $options_ignore as $ignore ) {
1705
            if ( isset( $options[ $ignore ] ) )
1706
                unset( $options[ $ignore ] );
1707
        }
1708
1709
        $exclude = array(
1710
            'id',
1711
            'name',
1712
            'label',
1713
            'description',
1714
            'type',
1715
            'storage',
1716
            'object',
1717
            'alias',
1718
            'options',
1719
            'fields'
1720
        );
1721
1722 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
1723
            $aliases = array( $exclude_field );
1724
1725
            if ( is_array( $exclude_field ) ) {
1726
                $aliases = array_merge( array( $k ), $exclude_field );
1727
                $exclude_field = $k;
1728
            }
1729
1730
            foreach ( $aliases as $alias ) {
1731
                if ( isset( $options[ $alias ] ) ) {
1732
                    $pod[ $exclude_field ] = pods_trim( $options[ $alias ] );
1733
1734
                    unset( $options[ $alias ] );
1735
                }
1736
            }
1737
        }
1738
1739
        if ( pods_tableless() && !in_array( $pod[ 'type' ], array( 'settings', 'table' ) ) ) {
1740
            if ( 'pod' == $pod[ 'type' ] )
1741
                $pod[ 'type' ] = 'post_type';
1742
1743 View Code Duplication
            if ( 'table' == $pod[ 'storage' ] ) {
1744
                if ( 'taxonomy' == $pod[ 'type' ] && ! function_exists( 'get_term_meta' ) )
1745
                    $pod[ 'storage' ] = 'none';
1746
                else
1747
                    $pod[ 'storage' ] = 'meta';
1748
            }
1749
        }
1750
1751
        $pod[ 'options' ][ 'type' ] = $pod[ 'type' ];
1752
        $pod[ 'options' ][ 'storage' ] = $pod[ 'storage' ];
1753
        $pod[ 'options' ][ 'object' ] = $pod[ 'object' ];
1754
        $pod[ 'options' ][ 'alias' ] = $pod[ 'alias' ];
1755
1756
        $pod[ 'options' ] = array_merge( $pod[ 'options' ], $options );
1757
1758
		/**
1759
		 * @var WP_Query
1760
		 */
1761
		global $wp_query;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1762
1763
		$reserved_query_vars = array(
1764
			'post_type',
1765
			'taxonomy',
1766
			'output'
1767
		);
1768
1769
		if ( is_object( $wp_query ) ) {
1770
			$reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
1771
		}
1772
1773 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var_string' ] ) ) {
1774
			if ( in_array( $pod[ 'options' ][ 'query_var_string' ], $reserved_query_vars ) ) {
1775
				$pod[ 'options' ][ 'query_var_string' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var_string' ];
1776
			}
1777
		}
1778
1779 View Code Duplication
		if ( isset( $pod[ 'options' ][ 'query_var' ] ) ) {
1780
			if ( in_array( $pod[ 'options' ][ 'query_var' ], $reserved_query_vars ) ) {
1781
				$pod[ 'options' ][ 'query_var' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var' ];
1782
			}
1783
		}
1784
1785
        if ( strlen( $pod[ 'label' ] ) < 1 )
1786
            $pod[ 'label' ] = $pod[ 'name' ];
1787
1788
        if ( 'post_type' == $pod[ 'type' ] ) {
1789
            // Max length for post types are 20 characters
1790
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 20 );
1791
        }
1792
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1793
            // Max length for taxonomies are 32 characters
1794
            $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 32 );
1795
        }
1796
1797
        $params->id = $pod[ 'id' ];
1798
        $params->name = $pod[ 'name' ];
1799
1800
        if ( null !== $old_name && $old_name != $params->name && empty( $pod[ 'object' ] ) ) {
1801
            if ( 'post_type' == $pod[ 'type' ] ) {
1802
                $check = get_post_type_object( $params->name );
1803
1804 View Code Duplication
                if ( !empty( $check ) )
1805
                    return pods_error( sprintf( __( 'Post Type %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1806
            }
1807
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1808
                $check = get_taxonomy( $params->name );
1809
1810 View Code Duplication
                if ( !empty( $check ) )
1811
                    return pods_error( sprintf( __( 'Taxonomy %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1812
            }
1813
        }
1814
1815
        $field_table_operation = true;
1816
1817
        // Add new pod
1818
        if ( empty( $params->id ) ) {
1819
            if ( strlen( $params->name ) < 1 )
1820
                return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this );
1821
1822
            $post_data = array(
1823
                'post_name' => $pod[ 'name' ],
1824
                'post_title' => $pod[ 'label' ],
1825
                'post_content' => $pod[ 'description' ],
1826
                'post_type' => '_pods_pod',
1827
                'post_status' => 'publish'
1828
            );
1829
1830
            if ( 'pod' == $pod[ 'type' ] && ( !is_array( $pod[ 'fields' ] ) || empty( $pod[ 'fields' ] ) ) ) {
1831
                $pod[ 'fields' ] = array();
1832
1833
                $pod[ 'fields' ][ 'name' ] = array(
1834
                    'name' => 'name',
1835
                    'label' => 'Name',
1836
                    'type' => 'text',
1837
                    'options' => array(
1838
                        'required' => '1'
1839
                    )
1840
                );
1841
1842
                $pod[ 'fields' ][ 'created' ] = array(
1843
                    'name' => 'created',
1844
                    'label' => 'Date Created',
1845
                    'type' => 'datetime',
1846
                    'options' => array(
1847
                        'datetime_format' => 'ymd_slash',
1848
                        'datetime_time_type' => '12',
1849
                        'datetime_time_format' => 'h_mm_ss_A'
1850
                    )
1851
                );
1852
1853
                $pod[ 'fields' ][ 'modified' ] = array(
1854
                    'name' => 'modified',
1855
                    'label' => 'Date Modified',
1856
                    'type' => 'datetime',
1857
                    'options' => array(
1858
                        'datetime_format' => 'ymd_slash',
1859
                        'datetime_time_type' => '12',
1860
                        'datetime_time_format' => 'h_mm_ss_A'
1861
                    )
1862
                );
1863
1864
                $pod[ 'fields' ][ 'author' ] = array(
1865
                    'name' => 'author',
1866
                    'label' => 'Author',
1867
                    'type' => 'pick',
1868
                    'pick_object' => 'user',
1869
                    'options' => array(
1870
                        'pick_format_type' => 'single',
1871
                        'pick_format_single' => 'autocomplete',
1872
                        'default_value' => '{@user.ID}'
1873
                    )
1874
                );
1875
1876
                $pod[ 'fields' ][ 'permalink' ] = array(
1877
                    'name' => 'permalink',
1878
                    'label' => 'Permalink',
1879
                    'type' => 'slug',
1880
                    'description' => 'Leave blank to auto-generate from Name'
1881
                );
1882
1883
                if ( !isset( $pod[ 'options' ][ 'pod_index' ] ) )
1884
                    $pod[ 'options' ][ 'pod_index' ] = 'name';
1885
            }
1886
1887
            $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db );
1888
1889
            $field_table_operation = false;
1890
        }
1891
        else {
1892
            $post_data = array(
1893
                'ID' => $pod[ 'id' ],
1894
                'post_name' => $pod[ 'name' ],
1895
                'post_title' => $pod[ 'label' ],
1896
                'post_content' => $pod[ 'description' ],
1897
                'post_status' => 'publish'
1898
            );
1899
        }
1900
1901
        if ( true === $db ) {
1902
            if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
1903
                add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
1904
1905
            $conflicted = false;
1906
1907
            // Headway compatibility fix
1908
            if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
1909
                remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1910
1911
                $conflicted = true;
1912
            }
1913
1914
            $params->id = $this->save_wp_object( 'post', $post_data, $pod[ 'options' ], true, true );
1915
1916
            if ( $conflicted )
1917
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1918
1919
            if ( false === $params->id )
1920
                return pods_error( __( 'Cannot save Pod', 'pods' ), $this );
1921
        }
1922
        elseif ( empty( $params->id ) )
1923
            $params->id = (int) $db;
1924
1925
        $pod[ 'id' ] = $params->id;
1926
1927
        // Setup / update tables
1928
        if ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $old_storage != $pod[ 'storage' ] && $db ) {
1929
            $definitions = array( "`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY" );
1930
1931
            $defined_fields = array();
1932
1933
            foreach ( $pod[ 'fields' ] as $field ) {
1934
                if ( !is_array( $field ) || !isset( $field[ 'name' ] ) || in_array( $field[ 'name' ], $defined_fields ) )
1935
                    continue;
1936
1937
                $defined_fields[] = $field[ 'name' ];
1938
1939
                if ( !in_array( $field[ 'type' ], $tableless_field_types ) || ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) ) {
1940
                    $definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, pods_var_raw( 'options', $field, array() ) ) );
1941
1942
                    if ( 0 < strlen( $definition ) )
1943
                        $definitions[] = "`{$field['name']}` " . $definition;
1944
                }
1945
            }
1946
1947
            pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`" );
1948
1949
            $result = pods_query( "CREATE TABLE `@wp_pods_{$params->name}` (" . implode( ', ', $definitions ) . ") DEFAULT CHARSET utf8", $this );
1950
1951
            if ( empty( $result ) )
1952
                return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this );
1953
1954
        }
1955
        elseif ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $pod[ 'storage' ] == $old_storage && null !== $old_name && $old_name != $params->name && $db ) {
1956
            $result = pods_query( "ALTER TABLE `@wp_pods_{$old_name}` RENAME `@wp_pods_{$params->name}`", $this );
1957
1958
            if ( empty( $result ) )
1959
                return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this );
1960
        }
1961
1962
        /**
1963
         * @var $wpdb wpdb
1964
         */
1965
        global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
1966
1967
		if ( null !== $old_name && $old_name != $params->name && $db ) {
1968
        	// Rename items in the DB pointed at the old WP Object names
1969
			if ( 'post_type' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1970
				$this->rename_wp_object_type( 'post', $old_name, $params->name );
1971
			}
1972 View Code Duplication
			elseif ( 'taxonomy' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1973
				$this->rename_wp_object_type( 'taxonomy', $old_name, $params->name );
1974
			}
1975 View Code Duplication
			elseif ( 'comment' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1976
				$this->rename_wp_object_type( 'comment', $old_name, $params->name );
1977
			}
1978
			elseif ( 'settings' == $pod[ 'type' ] ) {
1979
				$this->rename_wp_object_type( 'settings', $old_name, $params->name );
1980
			}
1981
1982
        	// Sync any related fields if the name has changed
1983
            $fields = pods_query( "
1984
                SELECT `p`.`ID`
1985
                FROM `{$wpdb->posts}` AS `p`
1986
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1987
                LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID`
1988
                WHERE
1989
                    `p`.`post_type` = '_pods_field'
1990
                    AND `pm`.`meta_key` = 'pick_object'
1991
                    AND (
1992
                    	`pm`.`meta_value` = 'pod'
1993
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "'
1994
					)
1995
                    AND `pm2`.`meta_key` = 'pick_val'
1996
                    AND `pm2`.`meta_value` = '{$old_name}'
1997
            " );
1998
1999 View Code Duplication
            if ( !empty( $fields ) ) {
2000
                foreach ( $fields as $field ) {
2001
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
2002
                    update_post_meta( $field->ID, 'pick_val', $params->name );
2003
                }
2004
            }
2005
2006
            $fields = pods_query( "
2007
                SELECT `p`.`ID`
2008
                FROM `{$wpdb->posts}` AS `p`
2009
                LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
2010
                WHERE
2011
                    `p`.`post_type` = '_pods_field'
2012
                    AND `pm`.`meta_key` = 'pick_object'
2013
                    AND (
2014
                    	`pm`.`meta_value` = 'pod-{$old_name}'
2015
                    	OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "-{$old_name}'
2016
					)
2017
            " );
2018
2019 View Code Duplication
            if ( !empty( $fields ) ) {
2020
                foreach ( $fields as $field ) {
2021
                    update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
2022
                    update_post_meta( $field->ID, 'pick_val', $params->name );
2023
                }
2024
            }
2025
        }
2026
2027
        // Sync built-in options for post types and taxonomies
2028
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) && $db ) {
2029
            // Build list of 'built_in' for later
2030
            $built_in = array();
2031
2032
            foreach ( $pod[ 'options' ] as $key => $val ) {
2033
                if ( false === strpos( $key, 'built_in_' ) )
2034
                    continue;
2035
                elseif ( false !== strpos( $key, 'built_in_post_types_' ) )
2036
                    $built_in_type = 'post_type';
2037
                elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) )
2038
                    $built_in_type = 'taxonomy';
2039
                else
2040
                    continue;
2041
2042
                if ( $built_in_type == $pod[ 'type' ] )
2043
                    continue;
2044
2045
                if ( !isset( $built_in[ $built_in_type ] ) )
2046
                    $built_in[ $built_in_type ] = array();
2047
2048
                $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key );
2049
2050
                $built_in[ $built_in_type ][ $built_in_object ] = (int) $val;
2051
            }
2052
2053
            $lookup_option = $lookup_built_in = false;
2054
2055
            $lookup_name = $pod[ 'name' ];
2056
2057
            if ( 'post_type' == $pod[ 'type' ] ) {
2058
                $lookup_option = 'built_in_post_types_' . $lookup_name;
2059
                $lookup_built_in = 'taxonomy';
2060
            }
2061
            elseif ( 'taxonomy' == $pod[ 'type' ] ) {
2062
                $lookup_option = 'built_in_taxonomies_' . $lookup_name;
2063
                $lookup_built_in = 'post_type';
2064
            }
2065
2066
            if ( !empty( $lookup_option ) && !empty( $lookup_built_in ) && isset( $built_in[ $lookup_built_in ] ) ) {
2067
                foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) {
2068
                    $search_val = 1;
2069
2070
                    if ( 1 == $val )
2071
                        $search_val = 0;
2072
2073
                    $query = "SELECT p.ID FROM {$wpdb->posts} AS p
2074
                                LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}'
2075
                                LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}'
2076
                                LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = ''
2077
                                WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}'
2078
                                    AND pm2.meta_id IS NOT NULL
2079
                                    AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )";
2080
2081
                    $results = pods_query( $query );
2082
2083
                    if ( !empty( $results ) ) {
2084
                        foreach ( $results as $the_pod ) {
2085
                            delete_post_meta( $the_pod->ID, $lookup_option );
2086
2087
                            add_post_meta( $the_pod->ID, $lookup_option, $val );
2088
                        }
2089
                    }
2090
                }
2091
            }
2092
        }
2093
2094
        $saved = array();
2095
        $errors = array();
2096
2097
        $field_index_change = false;
2098
        $field_index_id = 0;
2099
2100
        $id_required = false;
2101
2102
        $field_index = pods_var( 'pod_index', $pod[ 'options' ], 'id', null, true );
2103
2104
        if ( 'pod' == $pod[ 'type' ] && !empty( $pod[ 'fields' ] ) && isset( $pod[ 'fields' ][ $field_index ] ) )
2105
            $field_index_id = $pod[ 'fields' ][ $field_index ];
2106
2107
        if ( isset( $params->fields ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
2108
            $fields = array();
2109
2110
            if ( isset( $params->fields ) ) {
2111
                $params->fields = (array) $params->fields;
2112
2113
                $weight = 0;
2114
2115
                foreach ( $params->fields as $field ) {
2116
                    if ( !is_array( $field ) || !isset( $field[ 'name' ] ) )
2117
                        continue;
2118
2119
                    if ( !isset( $field[ 'weight' ] ) ) {
2120
                        $field[ 'weight' ] = $weight;
2121
2122
                        $weight++;
2123
                    }
2124
2125
                    $fields[ $field[ 'name' ] ] = $field;
2126
                }
2127
            }
2128
2129
            $weight = 0;
2130
2131
            $saved_field_ids = array();
2132
2133
            foreach ( $pod[ 'fields' ] as $k => $field ) {
2134
                if ( !empty( $old_id ) && ( !is_array( $field ) || !isset( $field[ 'name' ] ) || !isset( $fields[ $field[ 'name' ] ] ) ) ) {
2135
                    // Iterative change handling for setup-edit.php
2136
                    if ( !is_array( $field ) && isset( $old_fields[ $k ] ) )
2137
                        $saved[ $old_fields[ $k ][ 'name' ] ] = true;
2138
2139
                    continue;
2140
                }
2141
2142
                if ( !empty( $old_id ) )
2143
                    $field = array_merge( $field, $fields[ $field[ 'name' ] ] );
2144
2145
                $field[ 'pod' ] = $pod;
2146
2147
                if ( !isset( $field[ 'weight' ] ) ) {
2148
                    $field[ 'weight' ] = $weight;
2149
2150
                    $weight++;
2151
                }
2152
2153
                if ( 0 < $field_index_id && pods_var( 'id', $field ) == $field_index_id )
2154
                    $field_index_change = $field[ 'name' ];
2155
2156
                if ( 0 < pods_var( 'id', $field ) )
2157
                    $id_required = true;
2158
2159
                if ( $id_required )
2160
                    $field[ 'id_required' ] = true;
2161
2162
                $field_data = $field;
2163
2164
                $field = $this->save_field( $field_data, $field_table_operation, true, $db );
2165
2166
                if ( true !== $db ) {
2167
                    $pod[ 'fields' ][ $k ] = $field;
2168
                    $saved_field_ids[] = $field[ 'id' ];
2169
                }
2170
                else {
2171
                    if ( !empty( $field ) && 0 < $field ) {
2172
                        $saved[ $field_data[ 'name' ] ] = true;
2173
                        $saved_field_ids[] = $field;
2174
                    }
2175
                    else
2176
                        $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data[ 'name' ] );
2177
                }
2178
            }
2179
2180
            if ( true === $db ) {
2181
                foreach ( $old_fields as $field ) {
2182
                    if ( isset( $pod[ 'fields' ][ $field[ 'name' ] ] ) || isset( $saved[ $field[ 'name' ] ] ) || in_array( $field[ 'id' ], $saved_field_ids ) )
2183
                        continue;
2184
2185
                    if ( $field[ 'id' ] == $field_index_id )
2186
                        $field_index_change = 'id';
2187
                    elseif ( $field[ 'name' ] == $field_index )
2188
                        $field_index_change = 'id';
2189
2190
                    $this->delete_field( array(
2191
                        'id' => (int) $field[ 'id' ],
2192
                        'name' => $field[ 'name' ],
2193
                        'pod' => $pod
2194
                    ), $field_table_operation );
2195
                }
2196
            }
2197
2198
            // Update field index if the name has changed or the field has been removed
2199
            if ( false !== $field_index_change && true === $db )
2200
                update_post_meta( $pod[ 'id' ], 'pod_index', $field_index_change );
2201
        }
2202
2203
        if ( !empty( $errors ) )
2204
            return pods_error( $errors, $this );
2205
2206
        $this->cache_flush_pods( $pod );
2207
2208
		$refresh_pod = $this->load_pod( array( 'name' => $pod['name'] ), false );
2209
2210
		if ( $refresh_pod ) {
2211
			$pod = $refresh_pod;
2212
		}
2213
2214
		if ( 'post_type' == $pod['type'] ) {
2215
			PodsMeta::$post_types[ $pod['id'] ] = $pod;
2216
		} elseif ( 'taxonomy' == $pod['type'] ) {
2217
			PodsMeta::$taxonomies[ $pod['id'] ] = $pod;
2218
		} elseif ( 'media' == $pod['type'] ) {
2219
			PodsMeta::$media[ $pod['id'] ] = $pod;
2220
		} elseif ( 'user' == $pod['type'] ) {
2221
			PodsMeta::$user[ $pod['id'] ] = $pod;
2222
		} elseif ( 'comment' == $pod['type'] ) {
2223
			PodsMeta::$comment[ $pod['id'] ] = $pod;
2224
		}
2225
2226
        // Register Post Types / Taxonomies post-registration from PodsInit
2227
        if ( !empty( PodsInit::$content_types_registered ) && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) ) {
0 ignored issues
show
Bug introduced by
The property content_types_registered cannot be accessed from this context as it is declared private in class PodsInit.

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

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

Loading history...
2228
            global $pods_init;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
2229
2230
            $pods_init->setup_content_types( true );
2231
        }
2232
2233
        if ( true === $db )
2234
            return $pod[ 'id' ];
2235
        else
2236
            return $pod;
2237
    }
2238
2239
    /**
2240
     * Add or edit a field within a Pod
2241
     *
2242
     * $params['id'] int Field ID (id OR pod_id+pod+name required)
2243
     * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
2244
     * $params['pod'] string Pod name (id OR pod_id+pod+name required)
2245
     * $params['name'] string Field name (id OR pod_id+pod+name required)
2246
     * $params['label'] string (optional) Field label
2247
     * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email, file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg)
2248
     * $params['pick_object'] string (optional) Related Object (for relationships)
2249
     * $params['pick_val'] string (optional) Related Object name (for relationships)
2250
     * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
2251
     * $params['weight'] int (optional) Order in which the field appears
2252
     * $params['options'] array (optional) Options
2253
     *
2254
     * @param array $params An associative array of parameters
2255
     * @param bool $table_operation (optional) Whether or not to handle table operations
2256
     * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2257
     * @param bool|int $db (optional) Whether to save into the DB or just return field array.
2258
     *
2259
     * @return int|array The field ID or field array (if !$db)
2260
     * @since 1.7.9
2261
     */
2262
    public function save_field ( $params, $table_operation = true, $sanitized = false, $db = true ) {
2263
        /**
2264
         * @var $wpdb wpdb
2265
         */
2266
        global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

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

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

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

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

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
2604
	            $field['options']['old_name'] = $old_name;
2605
            }
2606
2607
            $params->id = $this->save_wp_object( 'post', $post_data, $field[ 'options' ], true, true );
2608
2609
            if ( $conflicted )
2610
                add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2611
2612
            if ( false === $params->id )
2613
                return pods_error( __( 'Cannot save Field', 'pods' ), $this );
2614
        }
2615
        else
2616
            $params->id = $field[ 'name' ];
2617
2618
        $field[ 'id' ] = $params->id;
2619
2620
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field[ 'options' ] ), $simple_tableless_objects ) );
2621
2622
        $definition = false;
2623
2624
        if ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) {
2625
            $field_definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, $field[ 'options' ] ) );
2626
2627
            if ( 0 < strlen( $field_definition ) )
2628
                $definition = '`' . $field[ 'name' ] . '` ' . $field_definition;
2629
        }
2630
2631
        $sister_id = (int) pods_var( 'sister_id', $field[ 'options' ], 0 );
2632
2633
        if ( $table_operation && 'table' == $pod[ 'storage' ] && !pods_tableless() ) {
2634
            if ( !empty( $old_id ) ) {
2635
                if ( ( $field[ 'type' ] != $old_type || $old_simple != $simple ) && empty( $definition ) )
2636
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false );
2637
                elseif ( 0 < strlen( $definition ) ) {
2638
                    if ( $old_name != $field[ 'name' ] || $old_simple != $simple ) {
2639
                        $test = false;
2640
2641 View Code Duplication
                        if ( 0 < strlen( $old_definition ) )
2642
                            $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2643
2644
                        // If the old field doesn't exist, continue to add a new field
2645
                        if ( false === $test )
2646
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2647
                    }
2648
                    elseif ( null !== $old_definition && $definition != $old_definition ) {
2649
                        $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2650
2651
                        // If the old field doesn't exist, continue to add a new field
2652
                        if ( false === $test )
2653
                            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2654
                    }
2655
                }
2656
            }
2657
            elseif ( 0 < strlen( $definition ) ) {
2658
                $test = false;
2659
2660 View Code Duplication
                if ( 0 < strlen( $old_definition ) )
2661
                    $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `" . $field[ 'name' ] . "` {$definition}", false );
2662
2663
                // If the old field doesn't exist, continue to add a new field
2664
                if ( false === $test )
2665
                    pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2666
            }
2667
        }
2668
2669
        if ( !empty( $old_id ) && 'meta' == $pod[ 'storage' ] && $old_name != $field[ 'name' ] && $pod[ 'meta_table' ] != $pod[ 'table' ] ) {
2670
            $prepare = array(
2671
                $field[ 'name' ],
2672
                $old_name
2673
            );
2674
2675
            // Users don't have a type
2676
            if ( !empty( $pod[ 'field_type' ] ) )
2677
                $prepare[] = $pod[ 'name' ];
2678
2679
            pods_query( "
2680
                UPDATE `{$pod[ 'meta_table' ]}` AS `m`
2681
                LEFT JOIN `{$pod[ 'table' ]}` AS `t`
2682
                    ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}`
2683
                SET
2684
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2685
                WHERE
2686
                    `m`.`{$pod[ 'meta_field_index' ]}` = %s
2687
            " . ( !empty( $pod[ 'field_type' ] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ),
2688
                $prepare
2689
            );
2690
        }
2691
2692
        if ( $field[ 'type' ] != $old_type && in_array( $old_type, $tableless_field_types ) ) {
2693
            delete_post_meta( $old_sister_id, 'sister_id' );
2694
2695
            if ( true === $db ) {
2696
                pods_query( "
2697
                        DELETE pm
2698
                        FROM {$wpdb->postmeta} AS pm
2699
                        LEFT JOIN {$wpdb->posts} AS p
2700
                            ON p.post_type = '_pods_field'
2701
                            AND p.ID = pm.post_id
2702
                        WHERE
2703
                            p.ID IS NOT NULL
2704
                            AND pm.meta_key = 'sister_id'
2705
                            AND pm.meta_value = %d
2706
                    ", array(
2707
                        $params->id
2708
                    )
2709
                );
2710
2711
                if ( !pods_tableless() ) {
2712
                    pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false );
2713
2714
                    pods_query( "
2715
                            UPDATE `@wp_podsrel`
2716
                            SET `related_field_id` = 0
2717
                            WHERE `field_id` = %d
2718
                        ", array(
2719
                            $old_sister_id
2720
                        )
2721
                    );
2722
                }
2723
            }
2724
        }
2725 View Code Duplication
        elseif ( 0 < $sister_id ) {
2726
            update_post_meta( $sister_id, 'sister_id', $params->id );
2727
2728
            if ( true === $db && ( !pods_tableless() ) ) {
2729
                pods_query( "
2730
                        UPDATE `@wp_podsrel`
2731
                        SET `related_field_id` = %d
2732
                        WHERE `field_id` = %d
2733
                    ",
2734
                    array(
2735
                        $params->id,
2736
                        $sister_id
2737
                    )
2738
                );
2739
            }
2740
        }
2741 View Code Duplication
        elseif ( 0 < $old_sister_id ) {
2742
            delete_post_meta( $old_sister_id, 'sister_id' );
2743
2744
            if ( true === $db && ( !pods_tableless() ) ) {
2745
                pods_query( "
2746
                        UPDATE `@wp_podsrel`
2747
                        SET `related_field_id` = 0
2748
                        WHERE `field_id` = %d
2749
                    ", array(
2750
                        $old_sister_id
2751
                    )
2752
                );
2753
            }
2754
        }
2755
2756
        if ( !empty( $old_id ) && $old_name != $field[ 'name' ] && true === $db ) {
2757
            pods_query( "
2758
                    UPDATE `@wp_postmeta`
2759
                    SET `meta_value` = %s
2760
                    WHERE
2761
                        `post_id` = %d
2762
                        AND `meta_key` = 'pod_index'
2763
                        AND `meta_value` = %s
2764
                ", array(
2765
                    $field[ 'name' ],
2766
                    $pod[ 'id' ],
2767
                    $old_name
2768
                )
2769
            );
2770
        }
2771
2772
        if ( !$save_pod )
2773
            $this->cache_flush_pods( $pod );
2774
        else {
2775
            pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
2776
2777
            if ( !empty( $old_id ) && $old_name != $field[ 'name' ] )
2778
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $old_name );
2779
        }
2780
2781
        if ( true === $db )
2782
            return $params->id;
2783
        else
2784
            return $field;
2785
    }
2786
2787
    /**
2788
     * Fix Pod / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name)
2789
     *
2790
     * @param string $slug Unique slug value
2791
     * @param int $post_ID Post ID
2792
     * @param string $post_status Post Status
2793
     * @param string $post_type Post Type
2794
     * @param int $post_parent Post Parent ID
2795
     * @param string $original_slug Original slug value
2796
     *
2797
     * @return string Final slug value
2798
     *
2799
     * @since 2.3.3
2800
     */
2801
    public function save_slug_fix ( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) {
2802
        if ( in_array( $post_type, array( '_pods_field', '_pods_pod' ) ) && false !== strpos( $slug, '-' ) )
2803
            $slug = $original_slug;
2804
2805
        return $slug;
2806
    }
2807
2808
    /**
2809
     * Add or Edit a Pods Object
2810
     *
2811
     * $params['id'] int The Object ID
2812
     * $params['name'] string The Object name
2813
     * $params['type'] string The Object type
2814
     * $params['options'] Associative array of Object options
2815
     *
2816
     * @param array|object $params An associative array of parameters
2817
     * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
2818
     *
2819
     * @return int The Object ID
2820
     * @since 2.0
2821
     */
2822
    public function save_object ( $params, $sanitized = false ) {
2823
        $params = (object) $params;
2824
2825
        if ( false === $sanitized )
2826
            $params = pods_sanitize( $params );
2827
2828 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
2829
            return pods_error( __( 'Name must be given to save an Object', 'pods' ), $this );
2830
2831 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
2832
            return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this );
2833
2834
        $object = array(
2835
            'id' => 0,
2836
            'name' => $params->name,
2837
            'type' => $params->type,
2838
            'code' => '',
2839
            'options' => array()
2840
        );
2841
2842
        // Setup options
2843
        $options = get_object_vars( $params );
2844
2845
        if ( isset( $options[ 'method' ] ) )
2846
            unset( $options[ 'method' ] );
2847
2848
        $exclude = array(
2849
            'id',
2850
            'name',
2851
            'helper_type',
2852
            'code',
2853
            'options',
2854
            'status'
2855
        );
2856
2857 View Code Duplication
        foreach ( $exclude as $k => $exclude_field ) {
2858
            $aliases = array( $exclude_field );
2859
2860
            if ( is_array( $exclude_field ) ) {
2861
                $aliases = array_merge( array( $k ), $exclude_field );
2862
                $exclude_field = $k;
2863
            }
2864
2865
            foreach ( $aliases as $alias ) {
2866
                if ( isset( $options[ $alias ] ) ) {
2867
                    $object[ $exclude_field ] = pods_trim( $options[ $alias ] );
2868
2869
                    unset( $options[ $alias ] );
2870
                }
2871
            }
2872
        }
2873
2874
        if ( 'helper' == $object[ 'type' ] )
2875
            $object[ 'options' ][ 'helper_type' ] = $object[ 'helper_type' ];
2876
2877
        if ( isset( $object[ 'options' ][ 'code' ] ) )
2878
            unset( $object[ 'options' ][ 'code' ] );
2879
2880
        $object[ 'options' ] = array_merge( $object[ 'options' ], $options );
2881
2882
        $post_data = array(
2883
            'post_name' => pods_clean_name( $object[ 'name' ], true),
2884
            'post_title' => $object[ 'name' ],
2885
            'post_content' => $object[ 'code' ],
2886
            'post_type' => '_pods_' . $object[ 'type' ],
2887
            'post_status' => 'publish'
2888
        );
2889
2890
        if ( !empty( $object[ 'id' ] ) )
2891
            $post_data[ 'ID' ] = $object[ 'id' ];
2892
2893
        if ( null !== pods_var( 'status', $object, null, null, true ) )
2894
            $post_data[ 'post_status' ] = pods_var( 'status', $object, null, null, true );
2895
2896
        remove_filter( 'content_save_pre', 'balanceTags', 50 );
2897
2898
        $post_data = pods_sanitize( $post_data );
2899
2900
        $params->id = $this->save_post( $post_data, $object[ 'options' ], true, true );
2901
2902
        pods_transient_clear( 'pods_objects_' . $params->type );
2903
        pods_transient_clear( 'pods_objects_' . $params->type . '_get' );
2904
2905
        return $params->id;
2906
    }
2907
2908
    /**
2909
     * @see PodsAPI::save_object
2910
     *
2911
     * Add or edit a Pod Template
2912
     *
2913
     * $params['id'] int The template ID
2914
     * $params['name'] string The template name
2915
     * $params['code'] string The template code
2916
     *
2917
     * @param array|object $params An associative array of parameters
2918
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2919
     *
2920
     * @return int The Template ID
2921
     *
2922
     * @since 1.7.9
2923
     */
2924
    public function save_template ( $params, $sanitized = false ) {
2925
        $params = (object) $params;
2926
2927
        $params->type = 'template';
2928
2929
        return $this->save_object( $params, $sanitized );
2930
    }
2931
2932
    /**
2933
     * @see PodsAPI::save_object
2934
     *
2935
     * Add or edit a Pod Page
2936
     *
2937
     * $params['id'] int The page ID
2938
     * $params['name'] string The page URI
2939
     * $params['code'] string The page code
2940
     *
2941
     * @param array|object $params An associative array of parameters
2942
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2943
     *
2944
     * @return int The page ID
2945
     * @since 1.7.9
2946
     */
2947
    public function save_page ( $params, $sanitized = false ) {
2948
        $params = (object) $params;
2949
2950
        if ( !isset( $params->name ) ) {
2951
            $params->name = $params->uri;
2952
            unset( $params->uri );
2953
        }
2954
2955
        if ( isset( $params->phpcode ) ) {
2956
            $params->code = $params->phpcode;
2957
            unset( $params->phpcode );
2958
        }
2959
2960
        $params->name = trim( $params->name, '/' );
2961
        $params->type = 'page';
2962
2963
        return $this->save_object( $params, $sanitized );
2964
    }
2965
2966
    /**
2967
     * @see PodsAPI::save_object
2968
     *
2969
     * Add or edit a Pod Helper
2970
     *
2971
     * $params['id'] int The helper ID
2972
     * $params['name'] string The helper name
2973
     * $params['helper_type'] string The helper type ("pre_save", "display", etc)
2974
     * $params['code'] string The helper code
2975
     *
2976
     * @param array $params An associative array of parameters
2977
     * @param bool $sanitized  (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2978
     *
2979
     * @return int The helper ID
2980
     * @since 1.7.9
2981
     */
2982
    public function save_helper ( $params, $sanitized = false ) {
2983
        $params = (object) $params;
2984
2985
        if ( isset( $params->phpcode ) ) {
2986
            $params->code = $params->phpcode;
2987
            unset( $params->phpcode );
2988
        }
2989
2990
        if ( isset( $params->type ) ) {
2991
            $params->helper_type = $params->type;
2992
            unset( $params->type );
2993
        }
2994
2995
        $params->type = 'helper';
2996
2997
        return $this->save_object( $params, $sanitized );
2998
    }
2999
3000
    /**
3001
     * Add or edit a single pod item
3002
     *
3003
     * $params['pod'] string The Pod name (pod or pod_id is required)
3004
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
3005
     * $params['id'] int|array The item ID, or an array of item IDs to save data for
3006
     * $params['data'] array (optional) Associative array of field names + values
3007
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
3008
	 * $params['track_changed_fields'] bool Set to true to enable tracking of saved fields via PodsAPI::get_changed_fields()
3009
	 * $params['error_mode'] string Throw an 'exception', 'exit' with the message, return 'false', or return 'wp_error'
3010
     *
3011
     * @param array|object $params An associative array of parameters
3012
     *
3013
     * @return int|array The item ID, or an array of item IDs (if `id` is an array if IDs)
3014
     *
3015
     * @since 1.7.9
3016
     */
3017
    public function save_pod_item ( $params ) {
3018
3019
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
3020
3021
        $params = (object) pods_str_replace( '@wp_', '{prefix}', $params );
3022
3023
        $tableless_field_types = PodsForm::tableless_field_types();
3024
        $repeatable_field_types = PodsForm::repeatable_field_types();
3025
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
3026
3027
	    $error_mode = $this->display_errors;
3028
3029
	    if ( ! empty( $params->error_mode ) ) {
3030
		    $error_mode = $params->error_mode;
3031
	    }
3032
3033
        // @deprecated 2.0
3034
        if ( isset( $params->datatype ) ) {
3035
            pods_deprecated( '$params->pod instead of $params->datatype', '2.0' );
3036
3037
            $params->pod = $params->datatype;
3038
3039
            unset( $params->datatype );
3040
3041
            if ( isset( $params->pod_id ) ) {
3042
                pods_deprecated( '$params->id instead of $params->pod_id', '2.0' );
3043
3044
                $params->id = $params->pod_id;
3045
3046
                unset( $params->pod_id );
3047
            }
3048
3049
            if ( isset( $params->data ) && !empty( $params->data ) && is_array( $params->data ) ) {
3050
                $check = current( $params->data );
3051
3052
                if ( is_array( $check ) ) {
3053
                    pods_deprecated( 'PodsAPI::save_pod_items', '2.0' );
3054
3055
                    return $this->save_pod_items( $params, $params->data );
3056
                }
3057
            }
3058
        }
3059
3060
        // @deprecated 2.0
3061
        if ( isset( $params->tbl_row_id ) ) {
3062
            pods_deprecated( '$params->id instead of $params->tbl_row_id', '2.0' );
3063
3064
            $params->id = $params->tbl_row_id;
3065
3066
            unset( $params->tbl_row_id );
3067
        }
3068
3069
        // @deprecated 2.0
3070
        if ( isset( $params->columns ) ) {
3071
            pods_deprecated( '$params->data instead of $params->columns', '2.0' );
3072
3073
            $params->data = $params->columns;
3074
3075
            unset( $params->columns );
3076
        }
3077
3078
        if ( !isset( $params->pod ) )
3079
            $params->pod = false;
3080 View Code Duplication
        if ( isset( $params->pod_id ) )
3081
            $params->pod_id = pods_absint( $params->pod_id );
3082
        else
3083
            $params->pod_id = 0;
3084
3085 View Code Duplication
        if ( isset( $params->id ) )
3086
            $params->id = pods_absint( $params->id );
3087
        else
3088
            $params->id = 0;
3089
3090
        if ( !isset( $params->from ) )
3091
            $params->from = 'save';
3092
3093
        if ( !isset( $params->location ) )
3094
            $params->location = null;
3095
3096
        if ( !isset( $params->track_changed_fields ) )
3097
            $params->track_changed_fields = false;
3098
3099
		/**
3100
		 * Override $params['track_changed_fields']
3101
		 *
3102
		 * Use for globally setting field change tracking.
3103
		 *
3104
		 * @param bool
3105
		 *
3106
		 * @since 2.3.19
3107
		 */
3108
		$track_changed_fields = apply_filters( 'pods_api_save_pod_item_track_changed_fields_' . $params->pod, (boolean) $params->track_changed_fields, $params );
3109
3110
		$changed_fields = array();
3111
3112
		if ( !isset( $params->clear_slug_cache ) ) {
3113
			$params->clear_slug_cache = true;
3114
		}
3115
3116
        // Support for bulk edit
3117
        if ( isset( $params->id ) && !empty( $params->id ) && is_array( $params->id ) ) {
3118
            $ids = array();
3119
            $new_params = $params;
3120
3121
            foreach ( $params->id as $id ) {
3122
                $new_params->id = $id;
3123
3124
                $ids[] = $this->save_pod_item( $new_params );
3125
            }
3126
3127
            return $ids;
3128
        }
3129
3130
        // Allow Helpers to know what's going on, are we adding or saving?
3131
        $is_new_item = false;
3132
3133
        if ( empty( $params->id ) )
3134
            $is_new_item = true;
3135
3136
        if ( isset( $params->is_new_item ) )
3137
            $is_new_item = (boolean) $params->is_new_item;
3138
3139
        // Allow Helpers to bypass subsequent helpers in recursive save_pod_item calls
3140
        $bypass_helpers = false;
3141
3142
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
3143
            $bypass_helpers = true;
3144
3145
        // Allow Custom Fields not defined by Pods to be saved
3146
        $allow_custom_fields = false;
3147
3148
        if ( isset( $params->allow_custom_fields ) && false !== $params->allow_custom_fields )
3149
            $allow_custom_fields = true;
3150
3151
        // Get array of Pods
3152
        $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
3153
3154
        if ( false === $pod )
3155
            return pods_error( __( 'Pod not found', 'pods' ), $error_mode );
3156
3157
        $params->pod = $pod[ 'name' ];
3158
        $params->pod_id = $pod[ 'id' ];
3159
3160
        if ( 'settings' == $pod[ 'type' ] )
3161
            $params->id = $pod[ 'id' ];
3162
3163
        $fields = $pod[ 'fields' ];
3164
3165
        $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
3166
3167
        $fields_active = array();
3168
        $custom_data = array();
3169
3170
        // Find the active fields (loop through $params->data to retain order)
3171
        if ( !empty( $params->data ) && is_array( $params->data ) ) {
3172
            $custom_fields = array();
3173
3174
            foreach ( $params->data as $field => $value ) {
3175
                if ( isset( $object_fields[ $field ] ) ) {
3176
                    $object_fields[ $field ][ 'value' ] = $value;
3177
                    $fields_active[] = $field;
3178
                }
3179
                elseif ( isset( $fields[ $field ] ) ) {
3180
                    if ( 'save' == $params->from || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3181
                        $fields[ $field ][ 'value' ] = $value;
3182
                        $fields_active[] = $field;
3183
                    }
3184
                    elseif ( !pods_has_permissions( $fields[ $field ][ 'options' ] ) && pods_var( 'hidden', $fields[ $field ][ 'options' ], false ) ) {
3185
                        $fields[ $field ][ 'value' ] = $value;
3186
                        $fields_active[] = $field;
3187
                    }
3188
                }
3189
                else {
3190
                    $found = false;
3191
3192
                    foreach ( $object_fields as $object_field => $object_field_opt ) {
3193
                        if ( in_array( $field, $object_field_opt[ 'alias' ] ) ) {
3194
                            $object_fields[ $object_field ][ 'value' ] = $value;
3195
                            $fields_active[] = $object_field;
3196
3197
                            $found = true;
3198
3199
                            break;
3200
                        }
3201
                    }
3202
3203
                    if ( $allow_custom_fields && !$found )
3204
                        $custom_fields[] = $field;
3205
                }
3206
            }
3207
3208
            if ( $allow_custom_fields && !empty( $custom_fields ) ) {
3209
                foreach ( $custom_fields as $field ) {
3210
                    $custom_data[ $field ] = $params->data[ $field ];
3211
                }
3212
            }
3213
3214
           unset( $params->data );
3215
        }
3216
3217 View Code Duplication
		if ( empty( $params->id ) && !in_array( 'created', $fields_active ) && isset( $fields[ 'created' ] ) && in_array( $fields[ 'created' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3218
			$fields[ 'created' ][ 'value' ] = current_time( 'mysql' );
3219
			$fields_active[] = 'created';
3220
		}
3221
3222 View Code Duplication
		if ( !in_array( 'modified', $fields_active ) && isset( $fields[ 'modified' ] ) && in_array( $fields[ 'modified' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3223
			$fields[ 'modified' ][ 'value' ] = current_time( 'mysql' );
3224
			$fields_active[] = 'modified';
3225
		}
3226
3227
        if ( in_array( $pod[ 'type' ], array( 'pod', 'table' ) ) && empty( $params->id ) && !empty( $pod[ 'pod_field_index' ] ) && in_array( $pod[ 'pod_field_index' ], $fields_active ) && !in_array( $pod[ 'pod_field_slug' ], $fields_active ) && isset( $fields[ $pod[ 'pod_field_slug' ] ] ) ) {
3228
			$fields[ $pod[ 'pod_field_slug' ] ][ 'value' ] = ''; // this will get picked up by slug pre_save method
3229
			$fields_active[] = $pod[ 'pod_field_slug' ];
3230
        }
3231
3232
        // Handle hidden fields
3233
        if ( empty( $params->id ) ) {
3234
            foreach ( $fields as $field => $field_data ) {
3235
                if ( in_array( $field, $fields_active ) )
3236
                    continue;
3237
3238
                if ( in_array( $params->from, array( 'save', 'process_form' ) ) || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3239
                    $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3240
3241
                    if ( null !== $value && '' !== $value && false !== $value ) {
3242
                        $fields[ $field ][ 'value' ] = $value;
3243
                        $fields_active[] = $field;
3244
                    }
3245
                }
3246
            }
3247
3248
			// Set default field values for object fields
3249
			if ( !empty( $object_fields ) ) {
3250 View Code Duplication
				foreach ( $object_fields as $field => $field_data ) {
3251
					if ( in_array( $field, $fields_active ) ) {
3252
						continue;
3253
					}
3254
					elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3255
						continue;
3256
					}
3257
3258
                    $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3259
3260
                    if ( null !== $value && '' !== $value && false !== $value ) {
3261
                        $object_fields[ $field ][ 'value' ] = $value;
3262
                        $fields_active[] = $field;
3263
                    }
3264
				}
3265
			}
3266
3267
			// Set default field values for Pod fields
3268 View Code Duplication
			foreach ( $fields as $field => $field_data ) {
3269
				if ( in_array( $field, $fields_active ) ) {
3270
					continue;
3271
				}
3272
				elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3273
					continue;
3274
				}
3275
3276
				$value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3277
3278
				if ( null !== $value && '' !== $value && false !== $value ) {
3279
					$fields[ $field ][ 'value' ] = $value;
3280
					$fields_active[] = $field;
3281
				}
3282
			}
3283
        }
3284
3285
        $columns =& $fields; // @deprecated 2.0
3286
        $active_columns =& $fields_active; // @deprecated 2.0
3287
        $params->tbl_row_id =& $params->id; // @deprecated 2.0
3288
3289
        $pre_save_helpers = $post_save_helpers = array();
3290
3291
		$pieces = array(
3292
			'fields',
3293
			'params',
3294
			'pod',
3295
			'fields_active',
3296
			'object_fields',
3297
			'custom_fields',
3298
			'custom_data',
3299
			'track_changed_fields',
3300
			'changed_fields'
3301
		);
3302
3303
		if ( $track_changed_fields ) {
3304
			self::handle_changed_fields( $params->pod, $params->id, 'set' );
3305
		}
3306
3307
        if ( false === $bypass_helpers ) {
3308
            // Plugin hooks
3309
            $hooked = $this->do_hook( 'pre_save_pod_item', compact( $pieces ), $is_new_item, $params->id );
3310
3311
            if ( is_array( $hooked ) && !empty( $hooked ) )
3312
                extract( $hooked );
3313
3314
            $hooked = $this->do_hook( "pre_save_pod_item_{$params->pod}", compact( $pieces ), $is_new_item, $params->id );
3315
3316
            if ( is_array( $hooked ) && !empty( $hooked ) )
3317
                extract( $hooked );
3318
3319
            if ( $is_new_item ) {
3320
                $hooked = $this->do_hook( 'pre_create_pod_item', compact( $pieces ) );
3321
3322
                if ( is_array( $hooked ) && !empty( $hooked ) )
3323
                    extract( $hooked );
3324
3325
                $hooked = $this->do_hook( "pre_create_pod_item_{$params->pod}", compact( $pieces ) );
3326
3327
                if ( is_array( $hooked ) && !empty( $hooked ) )
3328
                    extract( $hooked );
3329
            }
3330
            else {
3331
                $hooked = $this->do_hook( 'pre_edit_pod_item', compact( $pieces ), $params->id );
3332
3333
                if ( is_array( $hooked ) && !empty( $hooked ) )
3334
                    extract( $hooked );
3335
3336
                $hooked = $this->do_hook( "pre_edit_pod_item_{$params->pod}", compact( $pieces ), $params->id );
3337
3338
                if ( is_array( $hooked ) && !empty( $hooked ) )
3339
                    extract( $hooked );
3340
            }
3341
3342
            // Call any pre-save helpers (if not bypassed)
3343 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3344
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
3345
                    $helpers = array( 'pre_save_helpers', 'post_save_helpers' );
3346
3347
                    foreach ( $helpers as $helper ) {
3348
                        if ( isset( $pod[ 'options' ][ $helper ] ) && !empty( $pod[ 'options' ][ $helper ] ) )
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
3349
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
3350
                    }
3351
                }
3352
3353
                if ( !empty( $pre_save_helpers ) ) {
3354
                    pods_deprecated( sprintf( __( 'Pre-save helpers are deprecated, use the action pods_pre_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3355
3356
                    foreach ( $pre_save_helpers as $helper ) {
3357
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3358
3359
                        if ( false !== $helper )
3360
                            eval( '?>' . $helper[ 'code' ] );
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

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

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

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

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

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

Loading history...
3497
                    }
3498
                }
3499
3500
                // Prepare all table / meta data
3501
                if ( !in_array( $type, $tableless_field_types ) || $simple ) {
3502
                    if ( in_array( $type, $repeatable_field_types ) && 1 == pods_var( $type . '_repeatable', $field_data, 0 ) ) {
3503
                        // Don't save an empty array, just make it an empty string
3504 View Code Duplication
                        if ( empty( $value ) )
3505
                            $value = '';
3506
                        elseif ( is_array( $value ) ) {
3507
                            // If there's just one item, don't save as an array, save the string
3508
                            if ( 1 == count( $value ) )
3509
                                $value = implode( '', $value );
3510
                            // If storage is set to table, json encode, otherwise WP will serialize automatically
3511
                            elseif ( 'table' == pods_var( 'storage', $pod ) )
3512
                                $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
0 ignored issues
show
Unused Code introduced by
The call to json_encode() has too many arguments starting with JSON_UNESCAPED_UNICODE.

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

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

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

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

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

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

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

Let’s take a look at an example:

class A
{
    public function foo() { }
}

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

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

Available Fixes

  1. Add an additional type-check:

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

    function someFunction(B $x) { /** ... */ }
    
Loading history...
3748
3749
										// @todo Support non-Pods for tagging
3750
									}
3751
								}
3752
							}
3753
							elseif ( $is_file_field && isset( $v[ 'id' ] ) ) {
3754
								$v = (int) $v[ 'id' ];
3755
							}
3756
							else {
3757
								continue;
3758
							}
3759
3760
							if ( !empty( $v ) && !in_array( $v, $value_ids ) ) {
3761
								$value_ids[] = $v;
3762
							}
3763
                        }
3764
                    }
3765
3766
                    $value_ids = array_unique( array_filter( $value_ids ) );
3767
3768
                    // Filter unique values not equal to false in case of a multidimensional array
3769
                    $filtered_values = $this->array_filter_walker( $values );
3770
                    $serialized_values = array_map( 'serialize', $filtered_values );
3771
                    $unique_serialized_values = array_unique( $serialized_values );
3772
3773
	            $values = array_map( 'unserialize', $unique_serialized_values );
3774
3775
                    // Limit values
3776
                    if ( 0 < $related_limit && !empty( $value_ids ) ) {
3777
	                    $value_ids = array_slice( $value_ids, 0, $related_limit );
3778
	                    $values    = array_slice( $values, 0, $related_limit );
3779
                    }
3780
3781
                    // Get current values
3782
                    if ( 'pick' == $type && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ] ) )
3783
                        $related_ids = PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ];
3784
                    else
3785
                        $related_ids = $this->lookup_related_items( $fields[ $field ][ 'id' ], $pod[ 'id' ], $params->id, $fields[ $field ], $pod );
3786
3787
                    // Get ids to remove
3788
                    $remove_ids = array_diff( $related_ids, $value_ids );
3789
3790
                    // Delete relationships
3791
                    if ( !empty( $remove_ids ) )
3792
                        $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] );
3793
3794
                    // Save relationships
3795
                    if ( !empty( $value_ids ) )
3796
                        $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] );
3797
3798
                    $field_save_values = $value_ids;
3799
3800
                    if ( 'file' === $type ) {
3801
                    	$field_save_values = $values;
3802
                    }
3803
3804
                    // Run save function for field type (where needed)
3805
                    PodsForm::save( $type, $field_save_values, $params->id, $field, array_merge( $fields[ $field ], $fields[ $field ][ 'options' ] ), array_merge( $fields, $object_fields ), $pod, $params );
3806
                }
3807
3808
                // Unset data no longer needed
3809
                if ( 'pick' == $type ) {
3810
                    foreach ( $data as $field => $values ) {
3811
                        if ( isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) ) {
3812
                            unset( PodsField_Pick::$related_data[ PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'related_field' ][ 'id' ] ] );
3813
                            unset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] );
3814
                        }
3815
                    }
3816
                }
3817
            }
3818
        }
3819
3820
        if ( !$no_conflict )
3821
            pods_no_conflict_off( $pod[ 'type' ] );
3822
3823
        // Clear cache
3824
        pods_cache_clear( $params->id, 'pods_items_' . $pod[ 'name' ] );
3825
3826
		if ( $params->clear_slug_cache && !empty( $pod[ 'field_slug' ] ) ) {
3827
			$slug = pods( $pod[ 'name' ], $params->id )->field( $pod[ 'field_slug' ] );
3828
3829
			if ( 0 < strlen( $slug ) ) {
3830
        		pods_cache_clear( $slug, 'pods_items_' . $pod[ 'name' ] );
3831
			}
3832
		}
3833
3834
        // Clear WP meta cache
3835
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3836
            $meta_type = $pod[ 'type' ];
3837
3838
            if ( 'post_type' == $meta_type )
3839
                $meta_type = 'post';
3840
3841
            wp_cache_delete( $params->id, $meta_type . '_meta' );
3842
            wp_cache_delete( $params->id, 'pods_' . $meta_type . '_meta' );
3843
        }
3844
3845
        if ( false === $bypass_helpers ) {
3846
			if ( $track_changed_fields ) {
3847
				$changed_fields = self::handle_changed_fields( $params->pod, $params->id, 'get' );
3848
			}
3849
3850
            $compact_pieces = compact( $pieces );
3851
3852
            // Plugin hooks
3853
            $this->do_hook( 'post_save_pod_item', $compact_pieces, $is_new_item, $params->id );
3854
            $this->do_hook( "post_save_pod_item_{$params->pod}", $compact_pieces, $is_new_item, $params->id );
3855
3856
            if ( $is_new_item ) {
3857
                $this->do_hook( 'post_create_pod_item', $compact_pieces, $params->id );
3858
                $this->do_hook( "post_create_pod_item_{$params->pod}", $compact_pieces, $params->id );
3859
            }
3860
            else {
3861
                $this->do_hook( 'post_edit_pod_item', $compact_pieces, $params->id );
3862
                $this->do_hook( "post_edit_pod_item_{$params->pod}", $compact_pieces, $params->id );
3863
            }
3864
3865
            // Call any post-save helpers (if not bypassed)
3866
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3867 View Code Duplication
                if ( !empty( $post_save_helpers ) ) {
3868
                    pods_deprecated( sprintf( __( 'Post-save helpers are deprecated, use the action pods_post_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3869
3870
                    foreach ( $post_save_helpers as $helper ) {
3871
                        $helper = $this->load_helper( array( 'name' => $helper ) );
3872
3873
                        if ( false !== $helper && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
3874
                            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...
3875
                    }
3876
                }
3877
            }
3878
        }
3879
3880
        // Success! Return the id
3881
        return $params->id;
3882
3883
    }
3884
3885
    /**
3886
     * @see PodsAPI::save_pod_item
3887
     * Add multiple pod items
3888
     *
3889
     * $params['pod'] string The Pod name (pod or pod_id is required)
3890
     * $params['pod_id'] string The Pod ID (pod or pod_id is required)
3891
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
3892
     *
3893
     * $data['id'] int The item ID (optional)
3894
     * $data['data'] array An associative array of field names + values
3895
     *
3896
     * @param array|object $params An associative array of parameters, data excluded
3897
     * @param array $data An associative array of pod ids and field names + values (arrays of field data)
3898
     *
3899
     * @return int The item ID
3900
     * @since 2.0
3901
     */
3902
    public function save_pod_items ( $params, $data ) {
3903
        $params = (object) $params;
3904
3905
        $ids = array();
3906
3907
        foreach ( $data as $fields ) {
3908
            $params->data = $fields;
3909
3910
            if ( isset( $fields[ 'id' ] ) && isset( $fields[ 'data' ] ) ) {
3911
                $params->id = $fields[ 'id' ];
3912
                $params->data = $fields[ 'data' ];
3913
            }
3914
3915
            $ids[] = $this->save_pod_item( $params );
3916
        }
3917
3918
        return $ids;
3919
    }
3920
3921
	/**
3922
	 *Handle tracking changed fields or get them
3923
	 *
3924
	 * @param string $pod
3925
	 * @param int    $id
3926
	 * @param string $mode
3927
	 *
3928
	 * @return array List of changed fields (if $mode = 'get')
3929
	 */
3930
	public static function handle_changed_fields( $pod, $id, $mode = 'set' ) {
3931
3932
		static $changed_pods_cache = array();
3933
		static $old_fields_cache = array();
3934
		static $changed_fields_cache = array();
3935
3936
		$cache_key = $pod . '|' . $id;
3937
3938
		$export_params = array(
3939
			'depth' => 1,
3940
		);
3941
3942
		if ( in_array( $mode, array( 'set', 'reset' ), true ) ) {
3943
			if ( isset( $changed_fields_cache[ $cache_key ] ) ) {
3944
				unset( $changed_fields_cache[ $cache_key ] );
3945
			}
3946
3947
			if ( empty( $old_fields_cache[ $cache_key ] ) || 'reset' === $mode ) {
3948
				$old_fields_cache[ $cache_key ] = array();
3949
3950
				if ( ! empty( $id ) ) {
3951
					if ( ! isset( $changed_pods_cache[ $pod ] ) ) {
3952
						$changed_pods_cache[ $pod ] = pods( $pod );
3953
					}
3954
3955
					if ( $changed_pods_cache[ $pod ] && $changed_pods_cache[ $pod ]->valid() ) {
3956
						$changed_pods_cache[ $pod ]->fetch( $id );
3957
3958
						$old_fields_cache[ $cache_key ] = $changed_pods_cache[ $pod ]->export( $export_params );
3959
					}
3960
				}
3961
			}
3962
		}
3963
3964
		$changed_fields = array();
3965
3966
		if ( isset( $changed_fields_cache[ $cache_key ] ) ) {
3967
			$changed_fields = $changed_fields_cache[ $cache_key ];
3968
		} elseif ( isset( $old_fields_cache[ $cache_key ] ) ) {
3969
			$old_fields = $old_fields_cache[ $cache_key ];
3970
3971
			if ( 'get' === $mode ) {
3972
				$changed_fields_cache[ $cache_key ] = array();
3973
3974
				if ( ! empty( $changed_pods_cache[ $pod ] ) ) {
3975
					if ( $id != $changed_pods_cache[ $pod ]->id() ) {
3976
						$changed_pods_cache[ $pod ]->fetch( $id );
3977
					}
3978
3979
					$new_fields = $changed_pods_cache[ $pod ]->export( $export_params );
3980
3981
					foreach ( $new_fields as $field => $value ) {
3982
						if ( ! isset( $old_fields[ $field ] ) || $value != $old_fields[ $field ] ) {
3983
							$changed_fields[ $field ] = $value;
3984
						}
3985
					}
3986
3987
					$changed_fields_cache[ $cache_key ] = $changed_fields;
3988
				}
3989
			}
3990
		}
3991
3992
		return $changed_fields;
3993
3994
	}
3995
3996
	/**
3997
	 * Get the fields that have changed during a save
3998
	 *
3999
	 * @param array $pieces Pieces array from save_pod_item
4000
	 *
4001
	 * @return array Array of fields and values that have changed
4002
	 *
4003
	 * @deprecated Use PodsAPI::handle_changed_fields
4004
	 */
4005
	public function get_changed_fields( $pieces ) {
4006
4007
		return self::handle_changed_fields( $pieces['params']->pod, $pieces['params']->id, 'get' );
4008
4009
	}
4010
4011
    /**
4012
     * Save relationships
4013
     *
4014
     * @param int $id ID of item
4015
     * @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...
4016
     * @param array $pod Pod data
4017
     * @param array $field Field data
4018
     */
4019
    public function save_relationships ( $id, $related_ids, $pod, $field ) {
4020
        // Get current values
4021
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ] ) )
4022
            $current_ids = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ];
4023
        else
4024
            $current_ids = $this->lookup_related_items( $field[ 'id' ], $pod[ 'id' ], $id, $field, $pod );
4025
4026
	    if ( isset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] ) ) {
4027
		    // Delete relationship from cache
4028
		    unset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] );
4029
	    }
4030
4031
        if ( !is_array( $related_ids ) )
4032
            $related_ids = implode( ',', $related_ids );
4033
4034
        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...
4035
            $related_ids[ $k ] = (int) $related_id;
4036
        }
4037
4038
        $related_ids = array_unique( array_filter( $related_ids ) );
4039
4040
        $related_limit = (int) pods_var_raw( $field[ 'type' ] . '_limit', $field[ 'options' ], 0 );
4041
4042 View Code Duplication
        if ( 'single' == pods_var_raw( $field[ 'type' ] . '_format_type', $field[ 'options' ] ) )
4043
            $related_limit = 1;
4044
4045
        // Limit values
4046
        if ( 0 < $related_limit && !empty( $related_ids ) )
4047
            $related_ids = array_slice( $related_ids, 0, $related_limit );
4048
4049
        // Post Types, Media, Users, and Comments (meta-based)
4050 View Code Duplication
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
4051
            $object_type = $pod[ 'type' ];
4052
4053
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
4054
                $object_type = 'post';
4055
            elseif ( 'taxonomy' == $object_type )
4056
                $object_type = 'term';
4057
4058
            delete_metadata( $object_type, $id, $field[ 'name' ] );
4059
4060
            if ( !empty( $related_ids ) ) {
4061
                update_metadata( $object_type, $id, '_pods_' . $field[ 'name' ], $related_ids );
4062
4063
                foreach ( $related_ids as $related_id ) {
4064
                    add_metadata( $object_type, $id, $field[ 'name' ], $related_id );
4065
                }
4066
            }
4067
            else
4068
                delete_metadata( $object_type, $id, '_pods_' . $field[ 'name' ] );
4069
        }
4070
        // Custom Settings Pages (options-based)
4071
        elseif ( 'settings' == $pod[ 'type' ] ) {
4072
            if ( !empty( $related_ids ) )
4073
                update_option( $pod[ 'name' ] . '_' . $field[ 'name' ], $related_ids );
4074
            else
4075
                delete_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
4076
        }
4077
4078
        $related_pod_id = $related_field_id = 0;
4079
4080
        if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && !empty( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ] ) ) {
4081
            $related_pod_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_pod' ][ 'id' ];
4082
            $related_field_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ][ 'id' ];
4083
        }
4084
4085
        // Relationships table
4086
        if ( !pods_tableless() ) {
4087
            $related_weight = 0;
4088
4089
            foreach ( $related_ids as $related_id ) {
4090
                if ( in_array( $related_id, $current_ids ) ) {
4091
                    pods_query( "
4092
                        UPDATE `@wp_podsrel`
4093
                        SET
4094
                            `pod_id` = %d,
4095
                            `field_id` = %d,
4096
                            `item_id` = %d,
4097
                            `related_pod_id` = %d,
4098
                            `related_field_id` = %d,
4099
                            `related_item_id` = %d,
4100
                            `weight` = %d
4101
                        WHERE
4102
                            `pod_id` = %d
4103
                            AND `field_id` = %d
4104
                            AND `item_id` = %d
4105
                            AND `related_item_id` = %d
4106
                    ", array(
4107
                        $pod[ 'id' ],
4108
                        $field[ 'id' ],
4109
                        $id,
4110
                        $related_pod_id,
4111
                        $related_field_id,
4112
                        $related_id,
4113
                        $related_weight,
4114
4115
                        $pod[ 'id' ],
4116
                        $field[ 'id' ],
4117
                        $id,
4118
                        $related_id,
4119
                    ) );
4120
                }
4121
                else {
4122
                    pods_query( "
4123
                        INSERT INTO `@wp_podsrel`
4124
                            (
4125
                                `pod_id`,
4126
                                `field_id`,
4127
                                `item_id`,
4128
                                `related_pod_id`,
4129
                                `related_field_id`,
4130
                                `related_item_id`,
4131
                                `weight`
4132
                            )
4133
                        VALUES ( %d, %d, %d, %d, %d, %d, %d )
4134
                    ", array(
4135
                        $pod[ 'id' ],
4136
                        $field[ 'id' ],
4137
                        $id,
4138
                        $related_pod_id,
4139
                        $related_field_id,
4140
                        $related_id,
4141
                        $related_weight
4142
                    ) );
4143
                }
4144
4145
                $related_weight++;
4146
            }
4147
        }
4148
    }
4149
4150
    /**
4151
     * Duplicate a Pod
4152
     *
4153
     * $params['id'] int The Pod ID
4154
     * $params['name'] string The Pod name
4155
     * $params['new_name'] string The new Pod name
4156
     *
4157
     * @param array $params An associative array of parameters
4158
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4159
     *
4160
     * @return int New Pod ID
4161
     * @since 2.3
4162
     */
4163
    public function duplicate_pod ( $params, $strict = false ) {
4164 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4165
            if ( is_numeric( $params ) )
4166
                $params = array( 'id' => $params );
4167
            else
4168
                $params = array( 'name' => $params );
4169
4170
            $params = (object) pods_sanitize( $params );
4171
        }
4172
        else
4173
            $params = (object) pods_sanitize( $params );
4174
4175
        $params->table_info = false;
4176
4177
        $pod = $this->load_pod( $params, $strict );
4178
4179
        if ( empty( $pod ) ) {
4180
            if ( false !== $strict )
4181
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4182
4183
            return false;
4184
        }
4185
        elseif ( in_array( $pod[ 'type' ], array( 'media', 'user', 'comment' ) ) ) {
4186
            if ( false !== $strict )
4187
                return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this );
4188
4189
            return false;
4190
        }
4191
        elseif ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod[ 'object' ] ) ) {
4192
			$pod[ 'object' ] = '';
4193
        }
4194
4195
        unset( $pod[ 'id' ] );
4196
4197
        if ( isset( $params->new_name ) )
4198
            $pod[ 'name' ] = $params->new_name;
4199
4200
        $try = 1;
4201
4202
        $check_name = $pod[ 'name' ];
4203
        $new_label = $pod[ 'label' ];
4204
4205 View Code Duplication
        while ( $this->load_pod( array( 'name' => $check_name, 'table_info' => false ), false ) ) {
4206
            $try++;
4207
4208
            $check_name = $pod[ 'name' ] . $try;
4209
            $new_label = $pod[ 'label' ] . $try;
4210
        }
4211
4212
        $pod[ 'name' ] = $check_name;
4213
        $pod[ 'label' ] = $new_label;
4214
4215
        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
4216
            unset( $pod[ 'fields' ][ $field ][ 'id' ] );
4217
        }
4218
4219
        return $this->save_pod( $pod );
4220
    }
4221
4222
    /**
4223
     * Duplicate a Field
4224
     *
4225
     * $params['pod_id'] int The Pod ID
4226
     * $params['pod'] string The Pod name
4227
     * $params['id'] int The Field ID
4228
     * $params['name'] string The Field name
4229
     * $params['new_name'] string The new Field name
4230
     *
4231
     * @param array $params An associative array of parameters
4232
     * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error
4233
     *
4234
     * @return int New Field ID
4235
     * @since 2.3.10
4236
     */
4237
	public function duplicate_field( $params, $strict = false ) {
4238
4239
		if ( !is_object( $params ) && !is_array( $params ) ) {
4240
			if ( is_numeric( $params ) ) {
4241
				$params = array( 'id' => $params );
4242
			}
4243
			else {
4244
				$params = array( 'name' => $params );
4245
			}
4246
		}
4247
4248
		$params = (object) pods_sanitize( $params );
4249
4250
		$params->table_info = false;
4251
4252
		$field = $this->load_field( $params, $strict );
4253
4254
		if ( empty( $field ) ) {
4255
			if ( false !== $strict ) {
4256
				return pods_error( __( 'Field not found', 'pods' ), $this );
4257
			}
4258
4259
			return false;
4260
		}
4261
4262
		unset( $field[ 'id' ] );
4263
4264
		if ( isset( $params->new_name ) ) {
4265
			$field[ 'name' ] = $params->new_name;
4266
		}
4267
4268
		$try = 1;
4269
4270
		$check_name = $field[ 'name' ];
4271
		$new_label = $field[ 'label' ];
4272
4273 View Code Duplication
		while ( $this->load_field( array( 'pod_id' => $field[ 'pod_id' ], 'name' => $check_name, 'table_info' => false ), false ) ) {
4274
			$try++;
4275
4276
			$check_name = $field[ 'name' ] . $try;
4277
			$new_label = $field[ 'label' ] . $try;
4278
		}
4279
4280
		$field[ 'name' ] = $check_name;
4281
		$field[ 'label' ] = $new_label;
4282
4283
		return $this->save_field( $field );
4284
4285
	}
4286
4287
	/**
4288
	* @see PodsAPI::save_pod_item
4289
	*
4290
	* Duplicate a pod item
4291
	*
4292
	* $params['pod'] string The Pod name
4293
	* $params['id'] int The item's ID from the wp_pods_* table
4294
	*
4295
	* @param array $params An associative array of parameters
4296
	*
4297
	* @return int The table row ID
4298
	*
4299
	* @since 1.12
4300
	*/
4301
	public function duplicate_pod_item ( $params ) {
4302
4303
		$params = (object) pods_sanitize( $params );
4304
4305
		$load_pod_params = array(
4306
			'name' => $params->pod,
4307
			'table_info' => false,
4308
		);
4309
4310
		$pod = $this->load_pod( $load_pod_params );
4311
4312
		if ( false === $pod ) {
4313
			return pods_error( __( 'Pod not found', 'pods' ), $this );
4314
		}
4315
4316
		$pod = pods( $params->pod, $params->id );
4317
4318
		$params->pod = $pod->pod;
4319
		$params->pod_id = $pod->pod_id;
4320
4321
		$fields = (array) pods_var_raw( 'fields', $pod->pod_data, array(), null, true );
4322
		$object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4323
4324
		if ( ! empty( $object_fields ) ) {
4325
			$fields = array_merge( $object_fields, $fields );
4326
		}
4327
4328
		$save_params = array(
4329
			'pod' => $params->pod,
4330
			'data' => array()
4331
		);
4332
4333
		$ignore_fields = array(
4334
			$pod->pod_data['field_id'],
4335
			$pod->pod_data['field_slug'],
4336
		);
4337
4338
		if ( in_array( $pod->pod_data['type'], array( 'post_type', 'media' ) ) ) {
4339
			$ignore_fields = array(
4340
				'ID',
4341
				'post_name',
4342
				'post_date',
4343
				'post_date_gmt',
4344
				'post_modified',
4345
				'post_modified_gmt',
4346
				'guid',
4347
		        );
4348
		} elseif ( 'term' == $pod->pod_data['type'] ) {
4349
			$ignore_fields = array(
4350
				'term_id',
4351
				'term_taxonomy_id',
4352
				'slug',
4353
		        );
4354
		} elseif ( 'user' == $pod->pod_data['type'] ) {
4355
			$ignore_fields = array(
4356
				'ID',
4357
				'user_nicename',
4358
		        );
4359
		} elseif ( 'comment' == $pod->pod_data['type'] ) {
4360
			$ignore_fields = array(
4361
				'comment_ID',
4362
		        );
4363
		} elseif ( 'settings' == $pod->pod_data['type'] ) {
4364
			return pods_error( __( 'Settings do not support duplication.', 'pods' ), $this );
4365
		}
4366
4367
		/**
4368
		 * Filter the fields to ignore during duplication
4369
		 *
4370
		 * @since 2.6.6
4371
		 *
4372
		 * @param array  $ignore_fields Fields to ignore and not save during duplication
4373
		 * @param Pods   $pod           Pod object
4374
		 * @param array  $fields        Fields on the pod to duplicate
4375
		 * @param object $params        Params passed into duplicate_pod_item()
4376
		 */
4377
		$ignore_fields = apply_filters( 'pods_api_duplicate_pod_item_ignore_fields', $ignore_fields, $pod, $fields, $params );
4378
4379
		foreach ( $fields as $field ) {
4380
			if ( in_array( $field['name'], $ignore_fields ) ) {
4381
				continue;
4382
			}
4383
4384
			$field = array(
4385
				'name' => $field['name'],
4386
				'output' => 'ids'
4387
			);
4388
4389
			$value = $pod->field( $field );
4390
4391
			// @todo Add post type compatibility to set unique post_title
4392
			// @todo Add term compatibility to set unique name
4393
			// @todo Add user compatibility to set unique user_login/user_email
4394
4395
			if ( ! empty( $value ) || ( ! is_array( $value ) && 0 < strlen( $value ) ) ) {
4396
				$save_params['data'][ $field['name'] ] = $value;
4397
			}
4398
		}
4399
4400
		$save_params = $this->do_hook( 'duplicate_pod_item', $save_params, $pod->pod, $pod->id(), $params );
4401
4402
		$id = $this->save_pod_item( $save_params );
4403
4404
		return $id;
4405
4406
	}
4407
4408
    /**
4409
     * @see pods()
4410
     *
4411
     * Export a pod item
4412
     *
4413
     * $params['pod'] string The Pod name
4414
     * $params['id'] int The item's ID from the wp_pods_* table
4415
     * $params['fields'] array The fields to export
4416
     * $params['depth'] int How many levels deep to export data
4417
     *
4418
     * @param array $params An associative array of parameters
4419
     * @param object $pod (optional) Pods object
4420
     *
4421
     * @return int The table row ID
4422
     * @since 1.12
4423
     */
4424
    public function export_pod_item ( $params, $pod = null ) {
4425
4426
	    if ( ! is_object( $pod ) || 'Pods' != get_class( $pod ) ) {
4427
		    if ( empty( $params ) ) {
4428
			    return false;
4429
		    }
4430
4431
		    if ( is_object( $params ) ) {
4432
			    $params = get_object_vars( (object) $params );
4433
		    }
4434
4435
		    $params = pods_sanitize( $params );
4436
4437
		    $pod = pods( $params['pod'], $params['id'], false );
4438
4439
		    if ( empty( $pod ) ) {
4440
			    return false;
4441
		    }
4442
	    }
4443
4444
        $params['fields'] = (array) pods_v( 'fields', $params, array(), true );
4445
        $params['depth'] = (int) pods_v( 'depth', $params, 2, true );
4446
        $params['object_fields'] = (array) pods_v( 'object_fields', $pod->pod_data, array(), true );
4447
        $params['flatten'] = (boolean) pods_v( 'flatten', $params, false, true );
4448
        $params['context'] = pods_v( 'context', $params, null, true );
4449
4450 View Code Duplication
        if ( empty( $params['fields'] ) ) {
4451
            $params['fields'] = array_merge( $pod->fields, $params['object_fields'] );
4452
        }
4453
4454
        $data = $this->export_pod_item_level( $pod, $params );
4455
4456
        $data = $this->do_hook( 'export_pod_item', $data, $pod->pod, $pod->id(), $pod, $params['fields'], $params['depth'], $params['flatten'], $params );
4457
4458
        return $data;
4459
    }
4460
4461
    /**
4462
     * Export a pod item by depth level
4463
     *
4464
     * @param Pods $pod Pods object
4465
     * @param array $params Export params
4466
     *
4467
     * @return array Data array
4468
     *
4469
     * @since 2.3
4470
     */
4471
    private function export_pod_item_level ( $pod, $params ) {
4472
	    $fields        = $params['fields'];
4473
	    $depth         = $params['depth'];
4474
	    $flatten       = $params['flatten'];
4475
	    $current_depth = pods_v( 'current_depth', $params, 1, true );
4476
	    $context       = $params['context'];
4477
4478
        $tableless_field_types = PodsForm::tableless_field_types();
4479
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4480
4481
        $object_fields = (array) pods_v( 'object_fields', $pod->pod_data, array(), true );
4482
4483
        $export_fields = array();
4484
4485
		$pod_type = $pod->pod_data['type'];
4486
4487
		if ( 'post_type' === $pod_type ) {
4488
			$pod_type = 'post';
4489
		} elseif ( 'taxonomy' === $pod_type ) {
4490
			$pod_type = 'term';
4491
		}
4492
4493
		$registered_meta_keys = false;
4494
4495
		if ( function_exists( 'get_registered_meta_keys' ) ) {
4496
			$registered_meta_keys = get_registered_meta_keys( $pod_type );
4497
		}
4498
4499
        foreach ( $fields as $k => $field ) {
4500
            if ( !is_array( $field ) ) {
4501
                $field = array(
4502
                    'id' => 0,
4503
                    'name' => $field
4504
                );
4505
            }
4506
4507
            if ( isset( $pod->fields[ $field[ 'name' ] ] ) ) {
4508
	            if ( 'rest' === $context && false !== $registered_meta_keys ) {
4509
		            if ( ! isset( $registered_meta_keys[ $field['name'] ] ) ) {
4510
			            continue;
4511
		            } elseif ( empty( $registered_meta_keys[ $field['name'] ]['show_in_rest'] ) ) {
4512
			            continue;
4513
		            }
4514
	            }
4515
4516
                $field = $pod->fields[ $field[ 'name' ] ];
4517
                $field[ 'lookup_name' ] = $field[ 'name' ];
4518
4519
                if ( in_array( $field[ 'type' ], $tableless_field_types ) && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4520
                    if ( 'pick' == $field[ 'type' ] ) {
4521
                        if ( empty( $field[ 'table_info' ] ) )
4522
                            $field[ 'table_info' ] = $this->get_table_info( pods_var_raw( 'pick_object', $field ), pods_var_raw( 'pick_val', $field ), null, null, $field );
4523
4524
                        if ( !empty( $field[ 'table_info' ] ) )
4525
                            $field[ 'lookup_name' ] .= '.' . $field[ 'table_info' ][ 'field_id' ];
4526
                    }
4527
                    elseif ( in_array( $field[ 'type' ], PodsForm::file_field_types() ) )
4528
                        $field[ 'lookup_name' ] .= '.guid';
4529
                }
4530
4531
                $export_fields[ $field[ 'name' ] ] = $field;
4532
            }
4533
            elseif ( isset( $object_fields[ $field[ 'name' ] ] ) ) {
4534
                $field = $object_fields[ $field[ 'name' ] ];
4535
                $field[ 'lookup_name' ] = $field[ 'name' ];
4536
4537
                $export_fields[ $field[ 'name' ] ] = $field;
4538
            }
4539
            elseif ( $field[ 'name' ] == $pod->pod_data[ 'field_id' ] ) {
4540
                $field[ 'type' ] = 'number';
4541
                $field[ 'lookup_name' ] = $field[ 'name' ];
4542
4543
                $export_fields[ $field[ 'name' ] ] = $field;
4544
            }
4545
        }
4546
4547
        $data = array();
4548
4549
        foreach ( $export_fields as $field ) {
4550
            // Return IDs (or guid for files) if only one level deep
4551
            if ( 1 == $depth )
4552
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'lookup_name' ], 'output' => 'arrays' ) );
4553
            // Recurse depth levels for pick fields if $depth allows
4554
            elseif ( ( -1 == $depth || $current_depth < $depth ) && 'pick' == $field[ 'type' ] && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4555
                $related_data = array();
4556
4557
                $related_ids = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'ids' ) );
4558
4559
                if ( !empty( $related_ids ) ) {
4560
                    $related_ids = (array) $related_ids;
4561
4562
                    $pick_object = pods_var_raw( 'pick_object', $field );
4563
4564
                    $related_pod = pods( pods_var_raw( 'pick_val', $field ), null, false );
4565
4566
                    // If this isn't a Pod, return data exactly as Pods does normally
4567
                    if ( empty( $related_pod ) || ( 'pod' != $pick_object && $pick_object != $related_pod->pod_data[ 'type' ] ) || $related_pod->pod == $pod->pod )
4568
                        $related_data = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4569
                    else {
4570
                        $related_object_fields = (array) pods_var_raw( 'object_fields', $related_pod->pod_data, array(), null, true );
4571
4572
                        $related_fields = array_merge( $related_pod->fields, $related_object_fields );
4573
4574
                        foreach ( $related_ids as $related_id ) {
4575
                            if ( $related_pod->fetch( $related_id ) ) {
4576
	                            $related_params = array(
4577
		                            'related_fields' => $related_fields,
4578
		                            'depth'          => $depth,
4579
		                            'flatten'        => $flatten,
4580
		                            'current_depth'  => $current_depth + 1,
4581
		                            'context'        => $context,
4582
	                            );
4583
4584
                                $related_item = $this->export_pod_item_level( $related_pod, $related_params );
4585
4586
                                $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 ), $params );
4587
                            }
4588
                        }
4589
4590
                        if ( $flatten && !empty( $related_data ) )
4591
                            $related_data = pods_serial_comma( array_values( $related_data ), array( 'and' => '', 'field_index' => $related_pod->pod_data[ 'field_index' ] ) );
4592
                    }
4593
                }
4594
4595
                $data[ $field[ 'name' ] ] = $related_data;
4596
            }
4597
            // Return data exactly as Pods does normally
4598
            else
4599
                $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4600
4601
            if ( $flatten && is_array( $data[ $field[ 'name' ] ] ) )
4602
                $data[ $field[ 'name' ] ] = pods_serial_comma( $data[ $field[ 'name' ] ], array( 'field' => $field[ 'name' ], 'fields' => $export_fields, 'and' => '' ) );
4603
        }
4604
4605
	$data[ 'id' ] = (int) $pod->id();
4606
        return $data;
4607
    }
4608
4609
    /**
4610
     * Reorder a Pod
4611
     *
4612
     * $params['pod'] string The Pod name
4613
     * $params['field'] string The field name of the field to reorder
4614
     * $params['order'] array The key => value array of items to reorder (key should be an integer)
4615
     *
4616
     * @param array $params An associative array of parameters
4617
     *
4618
     * @return bool
4619
     *
4620
     * @since 1.9.0
4621
     */
4622
    public function reorder_pod_item ( $params ) {
4623
        $params = (object) pods_sanitize( $params );
4624
4625
        // @deprecated 2.0
4626
        if ( isset( $params->datatype ) ) {
4627
            pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4628
4629
            $params->pod = $params->datatype;
4630
4631
            unset( $params->datatype );
4632
        }
4633
4634
        if ( null === pods_var_raw( 'pod', $params, null, null, true ) )
4635
            return pods_error( __( '$params->pod is required', 'pods' ), $this );
4636
4637
        if ( !is_array( $params->order ) )
4638
            $params->order = explode( ',', $params->order );
4639
4640
        $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
4641
4642
        $params->name = $pod[ 'name' ];
4643
4644
        if ( false === $pod )
4645
            return pods_error( __( 'Pod is required', 'pods' ), $this );
4646
4647
        foreach ( $params->order as $order => $id ) {
4648
            if ( isset( $pod[ 'fields' ][ $params->field ] ) || isset( $pod[ 'object_fields' ][ $params->field ] ) ) {
4649
                if ( 'table' == $pod[ 'storage' ] && ( !pods_tableless() ) ) {
4650
                    if ( isset( $pod[ 'fields' ][ $params->field ] ) )
4651
                        pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" );
4652
                    else
4653
                        pods_query( "UPDATE `{$pod['table']}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `{$pod['field_id']}` = " . pods_absint( $id ) . " LIMIT 1" );
4654
                }
4655
                else
4656
                    $this->save_pod_item( array( 'pod' => $params->pod, 'pod_id' => $params->pod_id, 'id' => $id, 'data' => array( $params->field => pods_absint( $order ) ) ) );
4657
            }
4658
        }
4659
4660
        return true;
4661
    }
4662
4663
    /**
4664
     *
4665
     * Delete all content for a Pod
4666
     *
4667
     * $params['id'] int The Pod ID
4668
     * $params['name'] string The Pod name
4669
     *
4670
     * @param array $params An associative array of parameters
4671
     * @param array $pod Pod data
4672
     *
4673
     * @return bool
4674
     *
4675
     * @uses pods_query
4676
     * @uses pods_cache_clear
4677
     *
4678
     * @since 1.9.0
4679
     */
4680
    public function reset_pod ( $params, $pod = false ) {
4681
        $params = (object) pods_sanitize( $params );
4682
4683
        $params->table_info = true;
4684
4685
        if ( empty( $pod ) )
4686
            $pod = $this->load_pod( $params );
4687
4688
        if ( false === $pod )
4689
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4690
4691
        $params->id = $pod[ 'id' ];
4692
        $params->name = $pod[ 'name' ];
4693
4694 View Code Duplication
        if ( !pods_tableless() ) {
4695
            if ( 'table' == $pod[ 'storage' ] ) {
4696
                try {
4697
                    pods_query( "TRUNCATE `@wp_pods_{$params->name}`", false );
4698
                }
4699
                catch ( Exception $e ) {
4700
                    // Allow pod to be reset if the table doesn't exist
4701
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4702
                        return pods_error( $e->getMessage(), $this );
4703
                }
4704
            }
4705
4706
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4707
        }
4708
4709
        // @todo Delete relationships from tableless relationships
4710
4711
        // Delete all posts/revisions from this post type
4712
        if ( in_array( $pod[ 'type' ], array( 'post_type', 'media' ) ) ) {
4713
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4714
4715
            $sql = "
4716
                DELETE `t`, `r`, `m`
4717
                FROM `{$pod['table']}` AS `t`
4718
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4719
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4720
                LEFT JOIN `{$pod['table']}` AS `r`
4721
                    ON `r`.`post_parent` = `t`.`{$pod['field_id']}` AND `r`.`post_status` = 'inherit'
4722
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4723
            ";
4724
4725
            pods_query( $sql, false );
4726
        }
4727
        // Delete all terms from this taxonomy
4728
        elseif ( 'taxonomy' == $pod[ 'type' ] ) {
4729
            if ( function_exists( 'get_term_meta' ) ) {
4730
                $sql = "
4731
                    DELETE `t`, `m`, `tt`, `tr`
4732
                    FROM `{$pod['table']}` AS `t`
4733
                    LEFT JOIN `{$pod['meta_table']}` AS `m`
4734
                        ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4735
                    " . $pod['join']['tt'] . "
4736
                    " . $pod['join']['tr'] . "
4737
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4738
                ";
4739
            } else {
4740
                $sql = "
4741
                    DELETE `t`, `tt`, `tr`
4742
                    FROM `{$pod['table']}` AS `t`
4743
                    " . $pod['join']['tt'] . "
4744
                    " . $pod['join']['tr'] . "
4745
                    WHERE " . implode( ' AND ', $pod['where'] ) . "
4746
                ";
4747
            }
4748
4749
            pods_query( $sql, false );
4750
        }
4751
        // Delete all users except the current one
4752
        elseif ( 'user' == $pod[ 'type' ] ) {
4753
            $sql = "
4754
                DELETE `t`, `m`
4755
                FROM `{$pod['table']}` AS `t`
4756
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4757
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4758
                WHERE `t`.`{$pod['field_id']}` != " . (int) get_current_user_id() . "
4759
            ";
4760
4761
            pods_query( $sql, false );
4762
        }
4763
        // Delete all comments
4764
        elseif ( 'comment' == $pod[ 'type' ] ) {
4765
            $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4766
4767
            $sql = "
4768
                DELETE `t`, `m`
4769
                FROM `{$pod['table']}` AS `t`
4770
                LEFT JOIN `{$pod['meta_table']}` AS `m`
4771
                    ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4772
                WHERE `t`.`{$pod['field_type']}` = '{$type}'
4773
            ";
4774
4775
            pods_query( $sql, false );
4776
        }
4777
4778
        pods_cache_clear( true ); // only way to reliably clear out cached data across an entire group
4779
4780
        return true;
4781
    }
4782
4783
    /**
4784
     * Delete a Pod and all its content
4785
     *
4786
     * $params['id'] int The Pod ID
4787
     * $params['name'] string The Pod name
4788
     *
4789
     * @param array $params An associative array of parameters
4790
     * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4791
     * @param bool $delete_all (optional) Whether to delete all content from a WP object
4792
     *
4793
     * @uses PodsAPI::load_pod
4794
     * @uses wp_delete_post
4795
     * @uses pods_query
4796
     *
4797
     * @return bool
4798
     * @since 1.7.9
4799
     */
4800
    public function delete_pod ( $params, $strict = false, $delete_all = false ) {
4801
        /**
4802
         * @var $wpdb wpdb
4803
         */
4804
        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...
4805
4806 View Code Duplication
        if ( !is_object( $params ) && !is_array( $params ) ) {
4807
            if ( is_numeric( $params ) )
4808
                $params = array( 'id' => $params );
4809
            else
4810
                $params = array( 'name' => $params );
4811
4812
            $params = (object) pods_sanitize( $params );
4813
        }
4814
        else
4815
            $params = (object) pods_sanitize( $params );
4816
4817
        $params->table_info = false;
4818
4819
        $pod = $this->load_pod( $params, $strict );
4820
4821
        if ( empty( $pod ) ) {
4822
            if ( false !== $strict )
4823
                return pods_error( __( 'Pod not found', 'pods' ), $this );
4824
4825
            return false;
4826
        }
4827
4828
        $params->id = (int) $pod[ 'id' ];
4829
        $params->name = $pod[ 'name' ];
4830
4831
        foreach ( $pod[ 'fields' ] as $field ) {
4832
            $field[ 'pod' ] = $pod;
4833
4834
            $this->delete_field( $field, false );
4835
        }
4836
4837
        // Only delete the post once the fields are taken care of, it's not required anymore
4838
        $success = wp_delete_post( $params->id );
4839
4840
        if ( !$success )
4841
            return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this );
4842
4843
        // Reset content
4844
        if ( $delete_all )
4845
            $this->reset_pod( $params, $pod );
4846
4847 View Code Duplication
        if ( !pods_tableless() ) {
4848
            if ( 'table' == $pod[ 'storage' ] ) {
4849
                try {
4850
                    pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false );
4851
                }
4852
                catch ( Exception $e ) {
4853
                    // Allow pod to be deleted if the table doesn't exist
4854
                    if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4855
                        return pods_error( $e->getMessage(), $this );
4856
                }
4857
            }
4858
4859
            pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4860
        }
4861
4862
        // @todo Delete relationships from tableless relationships
4863
4864
        // Delete any relationship references
4865
        $sql = "
4866
            DELETE `pm`
4867
            FROM `{$wpdb->postmeta}` AS `pm`
4868
            LEFT JOIN `{$wpdb->posts}` AS `p`
4869
                ON `p`.`post_type` = '_pods_field'
4870
                    AND `p`.`ID` = `pm`.`post_id`
4871
            LEFT JOIN `{$wpdb->postmeta}` AS `pm2`
4872
                ON `pm2`.`meta_key` = 'pick_object'
4873
                    AND `pm2`.`meta_value` = 'pod'
4874
                    AND `pm2`.`post_id` = `pm`.`post_id`
4875
            WHERE
4876
                `p`.`ID` IS NOT NULL
4877
                AND `pm2`.`meta_id` IS NOT NULL
4878
                AND `pm`.`meta_key` = 'pick_val'
4879
                AND `pm`.`meta_value` = '{$params->name}'
4880
        ";
4881
4882
        pods_query( $sql );
4883
4884
        $this->cache_flush_pods( $pod );
4885
4886
        return true;
4887
    }
4888
4889
    /**
4890
     * Drop a field within a Pod
4891
     *
4892
     * $params['id'] int The field ID
4893
     * $params['name'] int The field name
4894
     * $params['pod'] string The Pod name
4895
     * $params['pod_id'] string The Pod name
4896
     *
4897
     * @param array $params An associative array of parameters
4898
     * @param bool $table_operation Whether or not to handle table operations
4899
     *
4900
     * @uses PodsAPI::load_field
4901
     * @uses wp_delete_post
4902
     * @uses pods_query
4903
     *
4904
     * @return bool
4905
     * @since 1.7.9
4906
     */
4907
    public function delete_field ( $params, $table_operation = true ) {
4908
        /**
4909
         * @var $wpdb wpdb
4910
         */
4911
        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...
4912
4913
        $tableless_field_types = PodsForm::tableless_field_types();
4914
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
4915
4916
        $params = (object) pods_sanitize( $params );
4917
4918
        if ( !isset( $params->pod ) )
4919
            $params->pod = '';
4920
4921
        if ( !isset( $params->pod_id ) )
4922
            $params->pod_id = 0;
4923
4924
        $pod = $params->pod;
4925
4926
        $save_pod = false;
4927
4928
        if ( !is_array( $pod ) )
4929
            $pod = $this->load_pod( array( 'name' => $pod, 'id' => $params->pod_id, 'table_info' => false ) );
4930
        else
4931
            $save_pod = true;
4932
4933
        if ( empty( $pod ) )
4934
            return pods_error( __( 'Pod not found', 'pods' ), $this );
4935
4936
        $params->pod_id = $pod[ 'id' ];
4937
        $params->pod = $pod[ 'name' ];
4938
4939
        if ( !isset( $params->name ) )
4940
            $params->name = '';
4941
4942
        if ( !isset( $params->id ) )
4943
            $params->id = 0;
4944
4945
        $field = $this->load_field( array( 'name' => $params->name, 'id' => $params->id, 'pod' => $params->pod, 'pod_id' => $params->pod_id ) );
4946
4947
        if ( false === $field )
4948
            return pods_error( __( 'Field not found', 'pods' ), $this );
4949
4950
        $params->id = $field[ 'id' ];
4951
        $params->name = $field[ 'name' ];
4952
4953
        $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
4954
        $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params );
4955
4956
        if ( $table_operation && 'table' == $pod[ 'storage' ] && ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) )
4957
            pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false );
4958
4959
        $success = wp_delete_post( $params->id );
4960
4961
        if ( !$success )
4962
            return pods_error( __( 'Field unable to be deleted', 'pods' ), $this );
4963
4964
        $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm
4965
            LEFT JOIN {$wpdb->posts} AS p
4966
                ON p.post_type = '_pods_field' AND p.ID = pm.post_id
4967
            WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) );
4968
4969
        if ( ( !pods_tableless() ) && $table_operation ) {
4970
            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 );
4971
        }
4972
4973
        // @todo Delete tableless relationship meta
4974
4975
        if ( true === $save_pod )
4976
            $this->cache_flush_pods( $pod );
4977
4978
        return true;
4979
    }
4980
4981
    /**
4982
     * Drop a Pod Object
4983
     *
4984
     * $params['id'] int The object ID
4985
     * $params['name'] string The object name
4986
     * $params['type'] string The object type
4987
     *
4988
     * @param array|object $params An associative array of parameters
4989
     *
4990
     * @uses wp_delete_post
4991
     *
4992
     * @return bool
4993
     * @since 2.0
4994
     */
4995
    public function delete_object ( $params ) {
4996
        $params = (object) $params;
4997
        $object = $this->load_object( $params );
4998
4999 View Code Duplication
        if ( empty( $object ) )
5000
            return pods_error( sprintf( __( "%s Object not found", 'pods' ), ucwords( $params->type ) ), $this );
5001
5002
        $success = wp_delete_post( $params->id );
5003
5004 View Code Duplication
        if ( !$success )
5005
            return pods_error( sprintf( __( "%s Object not deleted", 'pods' ), ucwords( $params->type ) ), $this );
5006
5007
        pods_transient_clear( 'pods_objects_' . $params->type );
5008
5009
        return true;
5010
    }
5011
5012
    /**
5013
     * @see PodsAPI::delete_object
5014
     *
5015
     * Drop a Pod Template
5016
     *
5017
     * $params['id'] int The template ID
5018
     * $params['name'] string The template name
5019
     *
5020
     * @param array $params An associative array of parameters
5021
     *
5022
     * @return bool
5023
     * @since 1.7.9
5024
     */
5025
    public function delete_template ( $params ) {
5026
        $params = (object) $params;
5027
        $params->type = 'template';
5028
        return $this->delete_object( $params );
5029
    }
5030
5031
    /**
5032
     * @see PodsAPI::delete_object
5033
     *
5034
     * Drop a Pod Page
5035
     *
5036
     * $params['id'] int The page ID
5037
     * $params['uri'] string The page URI
5038
     *
5039
     * @param array $params An associative array of parameters
5040
     *
5041
     * @return bool
5042
     * @since 1.7.9
5043
     */
5044
    public function delete_page ( $params ) {
5045
        $params = (object) $params;
5046
        if ( isset( $params->uri ) ) {
5047
            $params->name = $params->uri;
5048
            unset( $params->uri );
5049
        }
5050
        if ( isset( $params->name ) )
5051
            $params->name = trim( $params->name, '/' );
5052
        $params->type = 'page';
5053
        return $this->delete_object( $params );
5054
    }
5055
5056
    /**
5057
     * @see PodsAPI::delete_object
5058
     *
5059
     * Drop a Pod Helper
5060
     *
5061
     * $params['id'] int The helper ID
5062
     * $params['name'] string The helper name
5063
     *
5064
     * @param array $params An associative array of parameters
5065
     *
5066
     * @return bool
5067
     * @since 1.7.9
5068
     */
5069
    public function delete_helper ( $params ) {
5070
        $params = (object) $params;
5071
        $params->type = 'helper';
5072
        return $this->delete_object( $params );
5073
    }
5074
5075
    /**
5076
     * Drop a single pod item
5077
     *
5078
     * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter)
5079
     * $params['pod'] string (optional) The Pod name (used with id parameter)
5080
     * $params['pod_id'] int (optional) The Pod ID (used with id parameter)
5081
     * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
5082
     *
5083
     * @param array $params An associative array of parameters
5084
     * @param bool $wp Whether to run WP object delete action
5085
     *
5086
     * @return bool
5087
     * @since 1.7.9
5088
     */
5089
    public function delete_pod_item ( $params, $wp = true ) {
5090
        $params = (object) pods_sanitize( $params );
5091
5092
        // @deprecated 2.0
5093
        if ( isset( $params->datatype_id ) || isset( $params->datatype ) || isset( $params->tbl_row_id ) ) {
5094
            if ( isset( $params->tbl_row_id ) ) {
5095
                pods_deprecated( __( '$params->id instead of $params->tbl_row_id', 'pods' ), '2.0' );
5096
                $params->id = $params->tbl_row_id;
5097
                unset( $params->tbl_row_id );
5098
            }
5099
5100 View Code Duplication
            if ( isset( $params->pod_id ) ) {
5101
                pods_deprecated( __( '$params->id instead of $params->pod_id', 'pods' ), '2.0' );
5102
                $params->id = $params->pod_id;
5103
                unset( $params->pod_id );
5104
            }
5105
5106 View Code Duplication
            if ( isset( $params->dataype_id ) ) {
5107
                pods_deprecated( __( '$params->pod_id instead of $params->datatype_id', 'pods' ), '2.0' );
5108
                $params->pod_id = $params->dataype_id;
5109
                unset( $params->dataype_id );
5110
            }
5111
5112
            if ( isset( $params->datatype ) ) {
5113
                pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
5114
                $params->pod = $params->datatype;
5115
                unset( $params->datatype );
5116
            }
5117
        }
5118
5119
        if ( !isset( $params->id ) )
5120
            return pods_error( __( 'Pod Item not found', 'pods' ), $this );
5121
5122
        $params->id = pods_absint( $params->id );
5123
5124
        if ( !isset( $params->pod ) )
5125
            $params->pod = '';
5126
5127
        if ( !isset( $params->pod_id ) )
5128
            $params->pod_id = 0;
5129
5130
        $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ) );
5131
5132
        if ( false === $pod )
5133
            return pods_error( __( 'Pod not found', 'pods' ), $this );
5134
5135
        $params->pod_id = $pod[ 'id' ];
5136
        $params->pod = $pod[ 'name' ];
5137
5138
        // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls
5139
        $bypass_helpers = false;
5140
5141
        if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
5142
            $bypass_helpers = true;
5143
5144
        $pre_delete_helpers = $post_delete_helpers = array();
5145
5146
        if ( false === $bypass_helpers ) {
5147
            // Plugin hook
5148
            $this->do_hook( 'pre_delete_pod_item', $params, $pod );
5149
            $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod );
5150
5151
            // Call any pre-save helpers (if not bypassed)
5152 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
5153
                if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
5154
                    $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' );
5155
5156
                    foreach ( $helpers as $helper ) {
5157
                        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...
5158
                            ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
5159
                    }
5160
                }
5161
5162
                if ( !empty( $pre_delete_helpers ) ) {
5163
                    pods_deprecated( sprintf( __( 'Pre-delete helpers are deprecated, use the action pods_pre_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5164
5165
                    foreach ( $pre_delete_helpers as $helper ) {
5166
                        $helper = $this->load_helper( array( 'name' => $helper ) );
5167
5168
                        if ( false !== $helper )
5169
                            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...
5170
                    }
5171
                }
5172
            }
5173
        }
5174
5175
        // Delete object from relationship fields
5176
        $this->delete_object_from_relationships( $params->id, $pod );
5177
5178
        if ( 'table' == $pod[ 'storage' ] )
5179
            pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" );
5180
5181
        if ( $wp ) {
5182
            if ( 'taxonomy' == $pod['type'] ) {
5183
                $taxonomy = $pod['name'];
5184
5185
                if ( ! empty( $pod['object'] ) ) {
5186
                    $taxonomy = $pod['object'];
5187
                }
5188
5189
                wp_delete_term( $params->id, $taxonomy );
5190
            } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) {
5191
                $this->delete_wp_object( $pod['type'], $params->id );
5192
            }
5193
        }
5194
5195
        if ( false === $bypass_helpers ) {
5196
            // Plugin hook
5197
            $this->do_hook( 'post_delete_pod_item', $params, $pod );
5198
            $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod );
5199
5200
            // Call any post-save helpers (if not bypassed)
5201 View Code Duplication
            if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
5202
                if ( !empty( $post_delete_helpers ) ) {
5203
                    pods_deprecated( sprintf( __( 'Post-delete helpers are deprecated, use the action pods_post_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5204
5205
                    foreach ( $post_delete_helpers as $helper ) {
5206
                        $helper = $this->load_helper( array( 'name' => $helper ) );
5207
5208
                        if ( false !== $helper )
5209
                            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...
5210
                    }
5211
                }
5212
            }
5213
        }
5214
5215
        pods_cache_clear( $params->id, 'pods_items_' . $params->pod );
5216
5217
        return true;
5218
    }
5219
5220
    /**
5221
     * Delete an object from tableless fields
5222
     *
5223
     * @param int $id
5224
     * @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...
5225
     * @param string $name
5226
     *
5227
     * @return bool
5228
     *
5229
     * @since 2.3
5230
     */
5231
    public function delete_object_from_relationships ( $id, $object, $name = null ) {
5232
        /**
5233
         * @var $pods_init \PodsInit
5234
         */
5235
        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...
5236
5237
        $pod = false;
5238
5239
        // Run any bidirectional delete operations
5240
        if ( is_array( $object ) )
5241
            $pod = $object;
5242
        elseif ( is_object( $pods_init ) )
5243
            $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...
5244
5245
        if ( !empty( $pod ) ) {
5246
            $object = $pod[ 'type' ];
5247
            $name = $pod[ 'name' ];
5248
5249
            foreach ( $pod[ 'fields' ] as $field ) {
5250
                PodsForm::delete( $field[ 'type' ], $id, $field[ 'name' ], array_merge( $field, $field[ 'options' ] ), $pod );
5251
            }
5252
        }
5253
5254
        // Lookup related fields (non-bidirectional)
5255
        $params = array(
5256
            'where' => array(
5257
                array(
5258
                    'key' => 'type',
5259
                    'value' => 'pick'
5260
                ),
5261
                array(
5262
                    'key' => 'pick_object',
5263
                    'value' => $object
5264
                )
5265
            )
5266
        );
5267
5268
        if ( !empty( $name ) && $name != $object ) {
5269
            $params[ 'where' ][] = array(
5270
                'key' => 'pick_val',
5271
                'value' => $name
5272
            );
5273
        }
5274
5275
        $fields = $this->load_fields( $params, false );
5276
5277
        if ( !empty( $pod ) && 'media' == $pod[ 'type' ] ) {
5278
            $params[ 'where' ] = array(
5279
                array(
5280
                    'key' => 'type',
5281
                    'value' => 'file'
5282
                )
5283
            );
5284
5285
            $fields = array_merge( $fields, $this->load_fields( $params, false ) );
5286
        }
5287
5288
        if ( is_array( $fields ) && !empty( $fields ) ) {
5289
            foreach ( $fields as $related_field ) {
5290
                $related_pod = $this->load_pod( array( 'id' => $related_field[ 'pod_id' ], 'fields' => false ), false );
5291
5292
                if ( empty( $related_pod ) )
5293
                    continue;
5294
5295
                $related_from = $this->lookup_related_items_from( $related_field[ 'id' ], $related_pod[ 'id' ], $id, $related_field, $related_pod );
5296
5297
                $this->delete_relationships( $related_from, $id, $related_pod, $related_field );
5298
            }
5299
        }
5300
5301
        if ( !empty( $pod ) && !pods_tableless() ) {
5302
            pods_query( "
5303
                DELETE FROM `@wp_podsrel`
5304
                WHERE
5305
                (
5306
                    `pod_id` = %d
5307
                    AND `item_id` = %d
5308
                )
5309
                OR (
5310
                    `related_pod_id` = %d
5311
                    AND `related_item_id` = %d
5312
                )
5313
            ", array(
5314
                $pod[ 'id' ],
5315
                $id,
5316
5317
                $pod[ 'id' ],
5318
                $id
5319
            ) );
5320
        }
5321
5322
        return true;
5323
    }
5324
5325
    /**
5326
     * Delete relationships
5327
     *
5328
     * @param int|array $related_id IDs for items to save
5329
     * @param int|array $id ID or IDs to remove
5330
     * @param array $related_pod Pod data
5331
     * @param array $related_field Field data
5332
     *
5333
     * @return void
5334
     *
5335
     * @since 2.3
5336
     */
5337
    public function delete_relationships ( $related_id, $id, $related_pod, $related_field ) {
5338
        if ( is_array( $related_id ) ) {
5339
            foreach ( $related_id as $rid ) {
5340
                $this->delete_relationships( $rid, $id, $related_pod, $related_field );
5341
            }
5342
5343
            return;
5344
        }
5345
5346
        if ( is_array( $id ) ) {
5347
            foreach ( $id as $rid ) {
5348
                $this->delete_relationships( $related_id, $rid, $related_pod, $related_field );
5349
            }
5350
5351
            return;
5352
        }
5353
5354
        $id = (int) $id;
5355
5356
        if ( empty( $id ) )
5357
            return;
5358
5359
        $related_ids = $this->lookup_related_items( $related_field[ 'id' ], $related_pod[ 'id' ], $related_id, $related_field, $related_pod );
5360
5361
        if ( empty( $related_ids ) )
5362
            return;
5363
        elseif ( !in_array( $id, $related_ids ) )
5364
            return;
5365
5366
	    if ( isset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] ) ) {
5367
		    // Delete relationship from cache
5368
		    unset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] );
5369
	    }
5370
        unset( $related_ids[ array_search( $id, $related_ids ) ] );
5371
5372
        $no_conflict = pods_no_conflict_check( $related_pod[ 'type' ] );
5373
5374
        if ( !$no_conflict )
5375
            pods_no_conflict_on( $related_pod[ 'type' ] );
5376
5377
        // Post Types, Media, Users, and Comments (meta-based)
5378 View Code Duplication
        if ( in_array( $related_pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
5379
            $object_type = $related_pod[ 'type' ];
5380
5381
            if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
5382
                $object_type = 'post';
5383
            elseif ( 'taxonomy' == $object_type )
5384
                $object_type = 'term';
5385
5386
            delete_metadata( $object_type, $related_id, $related_field[ 'name' ] );
5387
5388
            if ( !empty( $related_ids ) ) {
5389
                update_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ], $related_ids );
5390
5391
                foreach ( $related_ids as $rel_id ) {
5392
                    add_metadata( $object_type, $related_id, $related_field[ 'name' ], $rel_id );
5393
                }
5394
            }
5395
            else
5396
                delete_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ] );
5397
        }
5398
        // Custom Settings Pages (options-based)
5399
        elseif ( 'settings' == $related_pod[ 'type' ] ) {
5400
            if ( !empty( $related_ids ) )
5401
                update_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ], $related_ids );
5402
            else
5403
                delete_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ] );
5404
        }
5405
5406
        // Relationships table
5407
        if ( !pods_tableless() ) {
5408
            pods_query( "
5409
                DELETE FROM `@wp_podsrel`
5410
                WHERE
5411
                (
5412
                    `pod_id` = %d
5413
                    AND `field_id` = %d
5414
                    AND `item_id` = %d
5415
                    AND `related_item_id` = %d
5416
                )
5417
                OR (
5418
                    `related_pod_id` = %d
5419
                    AND `related_field_id` = %d
5420
                    AND `related_item_id` = %d
5421
                    AND `item_id` = %d
5422
                )
5423
            ", array(
5424
                $related_pod[ 'id' ],
5425
                $related_field[ 'id' ],
5426
                $related_id,
5427
                $id,
5428
5429
                $related_pod[ 'id' ],
5430
                $related_field[ 'id' ],
5431
                $related_id,
5432
                $id
5433
            ) );
5434
        }
5435
5436
        if ( !$no_conflict )
5437
            pods_no_conflict_off( $related_pod[ 'type' ] );
5438
    }
5439
5440
    /**
5441
     * Check if a Pod exists
5442
     *
5443
     * $params['id'] int Pod ID
5444
     * $params['name'] string Pod name
5445
     *
5446
     * @param array $params An associative array of parameters
5447
     *
5448
     * @return bool True if exists
5449
     *
5450
     * @since 1.12
5451
     */
5452
    public function pod_exists ( $params, $type = null ) {
5453
        if ( is_string( $params ) )
5454
            $params = array( 'name' => $params );
5455
5456
        $params = (object) pods_sanitize( $params );
5457
5458
        if ( !empty( $params->id ) || !empty( $params->name ) ) {
5459
            if ( !isset( $params->name ) )
5460
                $pod = get_post( $dummy = (int) $params->id );
5461
            else {
5462
                $pod = get_posts( array(
5463
                    'name' => $params->name,
5464
                    'post_type' => '_pods_pod',
5465
                    'posts_per_page' => 1
5466
                ) );
5467
5468
                if ( is_array( $pod ) ) {
5469
                    $pod = $pod[0];
5470
                }
5471
            }
5472
5473
            if ( !empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) )
5474
                return true;
5475
        }
5476
5477
        return false;
5478
    }
5479
5480
	/**
5481
	 * Get number of pods for a specific pod type
5482
	 *
5483
	 * @param string $type Type to get count
5484
	 *
5485
	 * @return int Total number of pods for a type
5486
	 *
5487
	 * @since 2.6.6
5488
	 */
5489
	public function get_pod_type_count( $type ) {
5490
5491
		$args = array(
5492
			'post_type'      => '_pods_pod',
5493
			'posts_per_page' => - 1,
5494
			'nopaging'       => true,
5495
			'fields'         => 'ids',
5496
			'meta_query'     => array(
5497
				array(
5498
					'key'   => 'type',
5499
					'value' => $type,
5500
				),
5501
			),
5502
		);
5503
5504
		$posts = get_posts( $args );
5505
5506
		$total = count( $posts );
5507
5508
		return $total;
5509
5510
	}
5511
5512
    /**
5513
     * Load a Pod and all of its fields
5514
     *
5515
     * $params['id'] int The Pod ID
5516
     * $params['name'] string The Pod name
5517
     * $params['fields'] bool Whether to load fields (default is true)
5518
     * $params['bypass_cache'] boolean Bypass the cache when getting data
5519
     *
5520
     * @param array|object $params An associative array of parameters or pod name as a string
5521
     * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work
5522
     *
5523
     * @return array|bool|mixed|void
5524
     * @since 1.7.9
5525
     */
5526
    public function load_pod ( $params, $strict = true ) {
5527
5528
        /**
5529
         * @var $sitepress SitePress
5530
		 * @var $wpdb wpdb
5531
         */
5532
        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...
5533
5534
        $current_language = false;
5535
        $load_fields = true;
5536
	    $bypass_cache = false;
5537
5538
	    // Get current language data
5539
		$lang_data = PodsInit::$i18n->get_current_language_data();
0 ignored issues
show
Bug introduced by
The property i18n cannot be accessed from this context as it is declared private in class PodsInit.

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

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

Loading history...
5540
5541
	    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...
5542
		    if ( ! empty( $lang_data['language'] ) ) {
5543
			    $current_language = $lang_data['language'];
5544
		    }
5545
	    }
5546
5547
        if ( !is_array( $params ) && !is_object( $params ) )
5548
            $params = array( 'name' => $params, 'table_info' => false, 'fields' => true );
5549
5550
        if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && isset( $params->fields ) && !$params->fields )
5551
            $load_fields = false;
5552
        elseif ( is_array( $params ) && isset( $params[ 'fields' ] ) && !$params[ 'fields' ] )
5553
            $load_fields = false;
5554
5555
	    $table_info = false;
5556
5557
        if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->table_info ) )
5558
            $table_info = true;
5559
        elseif ( is_array( $params ) && ! empty( $params[ 'table_info' ] ) )
5560
            $table_info = true;
5561
5562
        $transient = 'pods_' . $wpdb->prefix . '_pod';
5563
5564
        if ( !empty( $current_language ) )
5565
            $transient .= '_' . $current_language;
5566
5567
        if ( !$load_fields )
5568
            $transient .= '_nofields';
5569
5570
        if ( $table_info )
5571
            $transient .= '_tableinfo';
5572
5573
	    $check_pod = $params;
5574
5575
	    if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->pod ) ) {
5576
		    $check_pod = $params->pod;
5577
	    } elseif ( is_array( $params ) && ! empty( $params['pod'] ) ) {
5578
		    $check_pod = $params['pod'];
5579
	    }
5580
5581
        if ( is_object( $check_pod ) && ( is_a( $check_pod, 'WP_Post' ) || isset( $check_pod->post_name ) ) ) {
5582
            $pod = false;
5583
5584
            if ( pods_api_cache() )
5585
                $pod = pods_transient_get( $transient . '_' . $check_pod->post_name );
5586
5587 View Code Duplication
            if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5588
	            // @todo Is this needed anymore for WPML?
5589
                if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) )
5590
                     && did_action( 'wpml_loaded' )
5591
                     && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
5592
                    $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
5593
                }
5594
5595
                return $pod;
5596
            }
5597
5598
            $_pod = get_object_vars( $check_pod );
5599
        }
5600
        else {
5601
            $params = (object) pods_sanitize( $params );
5602
5603 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) ) {
5604
                if ( $strict ) {
5605
	                  return pods_error( 'Either Pod ID or Name are required', $this );
5606
                }
5607
5608
                return false;
5609
            }
5610
5611
		    if ( ! empty( $params->bypass_cache ) ) {
5612
		        $bypass_cache = true;
5613
		    }
5614
5615
            if ( isset( $params->name ) ) {
5616
                $pod = false;
5617
5618
				if ( '_pods_pod' == $params->name ) {
5619
					$pod = array(
5620
						'id' => 0,
5621
						'name' => $params->name,
5622
						'label' => __( 'Pods', 'pods' ),
5623
						'type' => 'post_type',
5624
						'storage' => 'meta',
5625
						'options' => array(
5626
							'label_singular' => __( 'Pod', 'pods' )
5627
						),
5628
						'fields' => array()
5629
					);
5630
				}
5631
				elseif ( '_pods_field' == $params->name ) {
5632
					$pod = array(
5633
						'id' => 0,
5634
						'name' => $params->name,
5635
						'label' => __( 'Pod Fields', 'pods' ),
5636
						'type' => 'post_type',
5637
						'storage' => 'meta',
5638
						'options' => array(
5639
							'label_singular' => __( 'Pod Field', 'pods' )
5640
						),
5641
						'fields' => array()
5642
					);
5643
				}
5644 View Code Duplication
                elseif ( ! $bypass_cache & pods_api_cache() )
5645
                    $pod = pods_transient_get( $transient . '_' . $params->name );
5646
5647 View Code Duplication
                if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5648
                    if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && did_action( 'wpml_loaded' )
5649
                        && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) )
5650
                        $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5651
5652
                    return $pod;
5653
                }
5654
            }
5655
5656 View Code Duplication
            if ( !isset( $params->name ) )
5657
                $pod = get_post( $dummy = (int) $params->id );
5658
            else {
5659
                $pod = get_posts( array(
5660
                    'name' => $params->name,
5661
                    'post_type' => '_pods_pod',
5662
                    'posts_per_page' => 1
5663
                ) );
5664
            }
5665
5666
            if ( empty( $pod ) ) {
5667
                if ( $strict )
5668
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
5669
5670
                return false;
5671
            }
5672
5673
            if ( is_array( $pod ) )
5674
                $pod = $pod[ 0 ];
5675
5676
            $_pod = get_object_vars( $pod );
5677
        }
5678
5679
        $pod = false;
5680
5681 View Code Duplication
        if ( ! $bypass_cache || pods_api_cache() )
5682
            $pod = pods_transient_get( $transient . '_' . $_pod[ 'post_name' ] );
5683
5684 View Code Duplication
        if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5685
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) )
5686
                 && did_action( 'wpml_loaded' )
5687
                && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
5688
	            $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
5689
            }
5690
5691
            return $pod;
5692
        }
5693
5694
        $pod = array(
5695
            'id' => $_pod[ 'ID' ],
5696
            'name' => $_pod[ 'post_name' ],
5697
            'label' => $_pod[ 'post_title' ],
5698
            'description' => $_pod[ 'post_content' ]
5699
        );
5700
5701
        if ( strlen( $pod[ 'label' ] ) < 1 )
5702
            $pod[ 'label' ] = $pod[ 'name' ];
5703
5704
        // @todo update with a method to put all options in
5705
        $defaults = array(
5706
            'show_in_menu' => 1,
5707
            'type' => 'post_type',
5708
            'storage' => 'meta',
5709
            'object' => '',
5710
            'alias' => ''
5711
        );
5712
5713
        if ( $bypass_cache ) {
5714
            wp_cache_delete( $pod['id'], 'post_meta' );
5715
5716
            update_postmeta_cache( array( $pod['id'] ) );
5717
        }
5718
5719
        $pod[ 'options' ] = get_post_meta( $pod[ 'id' ] );
5720
5721 View Code Duplication
        foreach ( $pod[ 'options' ] as $option => $value ) {
5722
            if ( is_array( $value ) ) {
5723
                foreach ( $value as $k => $v ) {
5724
                    if ( !is_array( $v ) )
5725
                        $value[ $k ] = maybe_unserialize( $v );
5726
                }
5727
5728
                if ( 1 == count( $value ) )
5729
                    $value = current( $value );
5730
            }
5731
            else
5732
                $value = maybe_unserialize( $value );
5733
5734
            $pod[ 'options' ][ $option ] = $value;
5735
        }
5736
5737
        $pod[ 'options' ] = array_merge( $defaults, $pod[ 'options' ] );
5738
5739
        $pod[ 'type' ] = $pod[ 'options' ][ 'type' ];
5740
        $pod[ 'storage' ] = $pod[ 'options' ][ 'storage' ];
5741
        $pod[ 'object' ] = $pod[ 'options' ][ 'object' ];
5742
        $pod[ 'alias' ] = $pod[ 'options' ][ 'alias' ];
5743
5744
        unset( $pod[ 'options' ][ 'type' ] );
5745
        unset( $pod[ 'options' ][ 'storage' ] );
5746
        unset( $pod[ 'options' ][ 'object' ] );
5747
        unset( $pod[ 'options' ][ 'alias' ] );
5748
5749
        if ( $table_info )
5750
            $pod = array_merge( $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ), $pod );
5751
5752
        // Override old 'none' storage type
5753 View Code Duplication
        if ( 'taxonomy' == $pod['type'] && 'none' == $pod['storage'] && function_exists( 'get_term_meta' ) ) {
5754
            $pod[ 'storage' ] = 'meta';
5755
        }
5756
5757
        if ( isset( $pod[ 'pod' ] ) )
5758
            unset( $pod[ 'pod' ] );
5759
5760
        $pod[ 'fields' ] = array();
5761
5762
        $pod[ 'object_fields' ] = array();
5763
5764
        if ( 'pod' != $pod[ 'type' ] )
5765
            $pod[ 'object_fields' ] = $this->get_wp_object_fields( $pod[ 'type' ], $pod );
5766
5767
        $fields = get_posts( array(
5768
            'post_type' => '_pods_field',
5769
            'posts_per_page' => -1,
5770
            'nopaging' => true,
5771
            'post_parent' => $pod[ 'id' ],
5772
            'orderby' => 'menu_order',
5773
            'order' => 'ASC'
5774
        ) );
5775
5776
        if ( !empty( $fields ) ) {
5777
            foreach ( $fields as $field ) {
5778
                $field->pod = $pod[ 'name' ];
5779
                $field->table_info = $table_info;
5780
                $field->bypass_cache = $bypass_cache;
5781
5782
                if ( $load_fields ) {
5783
                    $field = $this->load_field( $field );
5784
5785
                    $field = PodsForm::field_setup( $field, null, $field[ 'type' ] );
5786
                }
5787
                else {
5788
			        if ( $bypass_cache ) {
5789
                        wp_cache_delete( $field->ID, 'post_meta' );
5790
5791
			            update_postmeta_cache( array( $field->ID ) );
5792
			        }
5793
5794
                    $field = array(
5795
                        'id' => $field->ID,
5796
                        'name' => $field->post_name,
5797
                        'label' => $field->post_title,
5798
                        'type' => get_post_meta( $field->ID, 'type', true )
5799
                    );
5800
                }
5801
5802
                $pod[ 'fields' ][ $field[ 'name' ] ] = $field;
5803
            }
5804
        }
5805
5806 View Code Duplication
        if ( did_action( 'init' ) && pods_api_cache() )
5807
            pods_transient_set( $transient . '_' . $pod[ 'name' ], $pod );
5808
5809
        return $pod;
5810
    }
5811
5812
    /**
5813
     * Load a list of Pods based on filters specified.
5814
     *
5815
     * $params['type'] string/array Pod Type(s) to filter by
5816
     * $params['object'] string/array Pod Object(s) to filter by
5817
     * $params['options'] array Pod Option(s) key=>value array to filter by
5818
     * $params['orderby'] string ORDER BY clause of query
5819
     * $params['limit'] string Number of Pods to return
5820
     * $params['where'] string WHERE clause of query
5821
     * $params['ids'] string|array IDs of Objects
5822
     * $params['count'] boolean Return only a count of Pods
5823
     * $params['names'] boolean Return only an array of name => label
5824
     * $params['ids'] boolean Return only an array of ID => label
5825
     * $params['fields'] boolean Return pod fields with Pods (default is true)
5826
     * $params['key_names'] boolean Return pods keyed by name
5827
     * $params['bypass_cache'] boolean Bypass the cache when getting data
5828
     *
5829
     * @param array $params An associative array of parameters
5830
     *
5831
     * @return array|mixed
5832
     *
5833
     * @uses PodsAPI::load_pod
5834
     *
5835
     * @since 2.0
5836
     */
5837
    public function load_pods ( $params = null ) {
5838
5839
        $current_language = false;
5840
5841
	    // Get current language data
5842
		$lang_data = PodsInit::$i18n->get_current_language_data();
0 ignored issues
show
Bug introduced by
The property i18n cannot be accessed from this context as it is declared private in class PodsInit.

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

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

Loading history...
5843
5844
	    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...
5845
		    if ( ! empty( $lang_data['language'] ) ) {
5846
			    $current_language = $lang_data['language'];
5847
		    }
5848
	    }
5849
5850
        $params = (object) pods_sanitize( $params );
5851
5852
        $order = 'ASC';
5853
        $orderby = 'menu_order title';
5854
        $limit = -1;
5855
        $ids = false;
5856
5857
        $meta_query = array();
5858
        $cache_key = '';
5859
5860
        $bypass_cache = false;
5861
5862
	    if ( ! empty( $params->bypass_cache ) ) {
5863
	    	$bypass_cache = true;
5864
	    }
5865
5866
        if ( isset( $params->type ) && !empty( $params->type ) ) {
5867
            if ( !is_array( $params->type ) )
5868
                $params->type = array( trim( $params->type ) );
5869
5870
            sort( $params->type );
5871
5872
            $meta_query[] = array(
5873
                'key' => 'type',
5874
                'value' => $params->type,
5875
                'compare' => 'IN'
5876
            );
5877
5878
            if ( 0 < count( $params->type ) )
5879
                $cache_key .= '_type_' . trim( implode( '_', $params->type ) );
5880
        }
5881
5882
        if ( isset( $params->object ) && !empty( $params->object ) ) {
5883
            if ( !is_array( $params->object ) )
5884
                $params->object = array( $params->object );
5885
5886
            $params->object = pods_trim( $params->object );
5887
5888
            sort( $params->object );
5889
5890
            $meta_query[] = array(
5891
                'key' => 'object',
5892
                'value' => $params->object,
5893
                'compare' => 'IN'
5894
            );
5895
5896
            if ( 1 == count( $params->object ) )
5897
                $cache_key .= '_object_' . trim( implode( '', $params->object ) );
5898
        }
5899
5900 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
5901
            foreach ( $params->options as $option => $value ) {
5902
                if ( !is_array( $value ) )
5903
                    $value = array( $value );
5904
5905
                $value = pods_trim( $value );
5906
5907
                sort( $value );
5908
5909
                $meta_query[] = array(
5910
                    'key' => $option,
5911
                    'value' => pods_sanitize( $value ),
5912
                    'compare' => 'IN'
5913
                );
5914
            }
5915
5916
            $cache_key = '';
5917
        }
5918
5919
        if ( isset( $params->where ) && is_array( $params->where ) )
5920
            $meta_query = array_merge( $meta_query, (array) $params->where );
5921
5922 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
5923
            $order = strtoupper( $params->order );
5924
5925
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
5926
            $orderby = strtoupper( $params->orderby );
5927
5928
        if ( isset( $params->limit ) && !empty( $params->limit ) )
5929
            $limit = pods_absint( $params->limit );
5930
5931
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
5932
            $ids = $params->ids;
5933
5934
            if ( !is_array( $ids ) )
5935
                $ids = explode( ',', $ids );
5936
        }
5937
5938
        if ( empty( $ids ) )
5939
            $ids = false;
5940
5941
        $pre_key = '';
5942
5943
        if ( !empty( $current_language ) )
5944
            $pre_key .= '_' . $current_language;
5945
5946
        if ( isset( $params->count ) && $params->count )
5947
            $pre_key .= '_count';
5948
5949
        if ( isset( $params->ids ) && $params->ids && !empty( $ids ) )
5950
            $pre_key .= '_ids_' . implode( '_', $ids );
5951
5952
        if ( isset( $params->names ) && $params->names )
5953
            $pre_key .= '_names';
5954
        elseif ( isset( $params->names_ids ) && $params->names_ids )
5955
            $pre_key .= '_names_ids';
5956
5957
        if ( isset( $params->key_names ) && $params->key_names )
5958
            $pre_key .= '_namekeys';
5959
5960
        if ( isset( $params->fields ) && !$params->fields )
5961
            $pre_key .= '_nofields';
5962
5963
        if ( isset( $params->table_info ) && $params->table_info )
5964
            $pre_key .= '_tableinfo';
5965
5966
5967
        $pre_key .= '_get';
5968
5969
        if ( empty( $cache_key ) )
5970
            $cache_key = 'pods' . $pre_key . '_all';
5971
        else
5972
            $cache_key = 'pods' . $pre_key . $cache_key;
5973
5974
        if ( ! $bypass_cache && pods_api_cache() && !empty( $cache_key ) && ( 'pods' . ( !empty( $current_language ) ? '_' . $current_language : '' ) . '_get_all' != $cache_key || empty( $meta_query ) ) && $limit < 1 && ( empty( $orderby ) || 'menu_order title' == $orderby ) && empty( $ids ) ) {
5975
            $the_pods = pods_transient_get( $cache_key );
5976
5977
            if ( false === $the_pods )
5978
                $the_pods = pods_cache_get( $cache_key, 'pods' );
5979
5980
            if ( !is_array( $the_pods ) && 'none' == $the_pods )
5981
                return array();
5982
            elseif ( false !== $the_pods )
5983
                return $the_pods;
5984
        }
5985
5986
        $the_pods = array();
5987
5988
		$args = array(
5989
			'post_type' => '_pods_pod',
5990
			'nopaging' => true,
5991
			'posts_per_page' => $limit,
5992
			'order' => $order,
5993
			'orderby' => $orderby,
5994
			'meta_query' => $meta_query,
5995
		);
5996
5997
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
5998
		if ( false != $ids ) {
5999
			$args[ 'post__in' ] = $ids;
6000
		}
6001
6002
		$_pods = get_posts( $args );
6003
6004
        $export_ignore = array(
6005
            'object_type',
6006
            'object_name',
6007
            'table',
6008
            'meta_table',
6009
            'pod_table',
6010
            'field_id',
6011
            'field_index',
6012
            'field_slug',
6013
            'field_type',
6014
            'field_parent',
6015
            'field_parent_select',
6016
            'meta_field_id',
6017
            'meta_field_index',
6018
            'meta_field_value',
6019
            'pod_field_id',
6020
            'pod_field_index',
6021
            'object_fields',
6022
            'join',
6023
            'where',
6024
            'where_default',
6025
            'orderby',
6026
            'pod',
6027
            'recurse',
6028
            'table_info',
6029
            'attributes',
6030
            'group',
6031
            'grouped',
6032
            'developer_mode',
6033
            'dependency',
6034
            'depends-on',
6035
            'excludes-on'
6036
        );
6037
6038
        $total_fields = 0;
6039
6040
        if ( isset( $params->count ) && $params->count )
6041
            $the_pods = count( $_pods );
6042
        else {
6043
            foreach ( $_pods as $pod ) {
6044
                if ( isset( $params->names ) && $params->names )
6045
                    $the_pods[ $pod->post_name ] = $pod->post_title;
6046
                elseif ( isset( $params->names_ids ) && $params->names_ids )
6047
                    $the_pods[ $pod->ID ] = $pod->post_name;
6048
                else {
6049
                    if ( isset( $params->fields ) && !$params->fields )
6050
                        $pod->fields = false;
6051
6052
                    $pod = $this->load_pod( array( 'pod' => $pod, 'table_info' => ! empty( $params->table_info ), 'bypass_cache' => $bypass_cache ) );
6053
6054
                    // Remove extra data not needed
6055
                    if ( pods_var( 'export', $params, false ) && ( !isset( $params->fields ) || $params->fields ) ) {
6056
                        foreach ( $export_ignore as $ignore ) {
6057
                            if ( isset( $pod[ $ignore ] ) )
6058
                                unset( $pod[ $ignore ] );
6059
                        }
6060
6061
                        foreach ( $pod[ 'fields' ] as $field => $field_data ) {
6062
                            if ( isset( $pod[ 'fields' ][ $field ][ 'table_info' ] ) )
6063
                                unset( $pod[ 'fields' ][ $field ][ 'table_info' ] );
6064
                        }
6065
                    }
6066
6067
                    $total_fields += count( $pod[ 'fields' ] );
6068
6069
                    if ( isset( $params->key_names ) && $params->key_names )
6070
                        $the_pods[ $pod[ 'name' ] ] = $pod;
6071
                    else
6072
                        $the_pods[ $pod[ 'id' ] ] = $pod;
6073
                }
6074
            }
6075
        }
6076
6077
        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 ) ) {
6078
            // Too many Pods can cause issues with the DB when caching is not enabled
6079
            if ( 15 < count( $the_pods ) || 75 < count( $total_fields ) ) {
6080
                pods_transient_clear( $cache_key );
6081
6082 View Code Duplication
                if ( pods_api_cache() ) {
6083
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
6084
                        pods_cache_set( $cache_key, 'none', 'pods' );
6085
                    else
6086
                        pods_cache_set( $cache_key, $the_pods, 'pods' );
6087
                }
6088
            }
6089
            else {
6090
                pods_cache_clear( $cache_key, 'pods' );
6091
6092 View Code Duplication
                if ( pods_api_cache() ) {
6093
                    if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
6094
                        pods_transient_set( $cache_key, 'none' );
6095
                    else
6096
                        pods_transient_set( $cache_key, $the_pods );
6097
                }
6098
            }
6099
        }
6100
6101
        return $the_pods;
6102
    }
6103
6104
    /**
6105
     * Check if a Pod's field exists
6106
     *
6107
     * $params['pod_id'] int The Pod ID
6108
     * $params['id'] int The field ID
6109
     * $params['name'] string The field name
6110
     *
6111
     * @param array $params An associative array of parameters
6112
     *
6113
     * @return bool
6114
     *
6115
     * @since 1.12
6116
     */
6117
    public function field_exists ( $params ) {
6118
        $params = (object) pods_sanitize( $params );
6119
6120
        if ( ( !empty( $params->id ) || !empty( $params->name ) ) && isset( $params->pod_id ) && !empty( $params->pod_id ) ) {
6121 View Code Duplication
            if ( !isset( $params->name ) )
6122
                $field = get_post( $dummy = (int) $params->id );
6123
            else {
6124
                $field = get_posts( array(
6125
                    'name' => $params->name,
6126
                    'post_type' => '_pods_field',
6127
                    'posts_per_page' => 1,
6128
                    'post_parent' => $params->pod_id
6129
                ) );
6130
            }
6131
6132
            if ( !empty( $field ) )
6133
                return true;
6134
        }
6135
6136
        return false;
6137
    }
6138
6139
    /**
6140
     * Load a field
6141
     *
6142
     * $params['pod_id'] int The Pod ID
6143
     * $params['pod'] string The Pod name
6144
     * $params['id'] int The field ID
6145
     * $params['name'] string The field name
6146
     * $params['table_info'] boolean Whether to lookup a pick field's table info
6147
     * $params['bypass_cache'] boolean Bypass the cache when getting data
6148
     *
6149
     * @param array $params An associative array of parameters
6150
     * @param boolean $strict Whether to require a field exist or not when loading the info
6151
     *
6152
     * @return array|bool Array with field data, false if field not found
6153
     * @since 1.7.9
6154
     */
6155
    public function load_field ( $params, $strict = false ) {
6156
        $params = (object) $params;
6157
6158
        if ( !isset( $params->table_info ) )
6159
            $params->table_info = false;
6160
6161
        $bypass_cache = false;
6162
6163
        if ( ! empty( $params->bypass_cache ) )
6164
            $bypass_cache = true;
6165
6166
        $pod = array();
6167
        $field = array();
6168
6169
        if ( isset( $params->post_title ) )
6170
            $_field = $params;
6171
        elseif ( isset( $params->id ) && !empty( $params->id ) )
6172
            $_field = get_post( $dumb = (int) $params->id );
6173
        else {
6174
            if ( !isset( $params->pod ) )
6175
                $params->pod = '';
6176
6177
            if ( !isset( $params->pod_id ) )
6178
                $params->pod_id = 0;
6179
6180
            if ( isset( $params->pod_data ) )
6181
                $pod = $params->pod_data;
6182
            else {
6183
                $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false, 'bypass_cache' => $bypass_cache ), false );
6184
6185
                if ( false === $pod ) {
6186
                    if ( $strict )
6187
                        return pods_error( __( 'Pod not found', 'pods' ), $this );
6188
6189
                    return false;
6190
                }
6191
            }
6192
6193
            $params->pod_id = $pod[ 'id' ];
6194
            $params->pod = $pod[ 'name' ];
6195
6196 View Code Duplication
            if ( empty( $params->name ) && empty( $params->pod ) && empty( $params->pod_id ) )
6197
                return pods_error( __( 'Either Field Name or Field ID / Pod ID are required', 'pods' ), $this );
6198
6199
            $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
6200
6201
            if ( isset( $pod[ 'fields' ][ $params->name ] ) && isset( $pod[ 'fields' ][ $params->name ][ 'id' ] ) )
6202
                return $pod[ 'fields' ][ $params->name ];
6203
6204
            $field = false;
6205
6206
            if ( ! $bypass_cache && pods_api_cache() )
6207
                $field = pods_transient_get( 'pods_field_' . $params->pod . '_' . $params->name );
6208
6209
            if ( empty( $field ) ) {
6210
                $field = get_posts( array(
6211
                    'name' => $params->name,
6212
                    'post_type' => '_pods_field',
6213
                    'posts_per_page' => 1,
6214
                    'post_parent' => $params->pod_id
6215
                ) );
6216
6217
                if ( empty( $field ) ) {
6218
                    if ( $strict )
6219
                        return pods_error( __( 'Field not found', 'pods' ), $this );
6220
6221
                    return false;
6222
                }
6223
6224
                $_field = $field[ 0 ];
6225
6226
                $field = array();
6227
            }
6228
        }
6229
6230
        if ( empty( $_field ) ) {
6231
            if ( $strict )
6232
                return pods_error( __( 'Field not found', 'pods' ), $this );
6233
6234
            return false;
6235
        }
6236
6237
        $_field = get_object_vars( $_field );
6238
6239
        if ( !isset( $pod[ 'name' ] ) && !isset( $_field[ 'pod' ] ) ) {
6240
            if ( 0 < $_field[ 'post_parent' ] )
6241
                $pod = $this->load_pod( array( 'id' => $_field[ 'post_parent' ], 'table_info' => false ), false );
6242
6243
            if ( empty( $pod ) ) {
6244
                if ( $strict )
6245
                    return pods_error( __( 'Pod for field not found', 'pods' ), $this );
6246
6247
                return false;
6248
            }
6249
        }
6250
6251
        if ( empty( $field ) ) {
6252 View Code Duplication
            if ( ! $bypass_cache && pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6253
                $field = pods_transient_get( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $_field[ 'post_name' ] );
6254
6255
            if ( empty( $field ) ) {
6256
                $defaults = array(
6257
                    'type' => 'text'
6258
                );
6259
6260
                $field = array(
6261
                    'id' => $_field[ 'ID' ],
6262
                    'name' => $_field[ 'post_name' ],
6263
                    'label' => $_field[ 'post_title' ],
6264
                    'description' => $_field[ 'post_content' ],
6265
                    'weight' => $_field[ 'menu_order' ],
6266
                    'pod_id' => $_field[ 'post_parent' ],
6267
                    'pick_object' => '',
6268
                    'pick_val' => '',
6269
                    'sister_id' => '',
6270
                    'table_info' => array()
6271
                );
6272
6273
                if ( isset( $pod[ 'name' ] ) )
6274
                    $field[ 'pod' ] = $pod[ 'name' ];
6275
                elseif ( isset( $_field[ 'pod' ] ) )
6276
                    $field[ 'pod' ] = $_field[ 'pod' ];
6277
6278
	            if ( $bypass_cache ) {
6279
	                wp_cache_delete( $field['id'], 'post_meta' );
6280
6281
	                update_postmeta_cache( array( $field['id'] ) );
6282
	            }
6283
6284
                $field[ 'options' ] = get_post_meta( $field[ 'id' ] );
6285
6286
                $options_ignore = array(
6287
                    'method',
6288
                    'table_info',
6289
                    'attributes',
6290
                    'group',
6291
                    'grouped',
6292
                    'developer_mode',
6293
                    'dependency',
6294
                    'depends-on',
6295
                    'excludes-on'
6296
                );
6297
6298
                foreach ( $options_ignore as $ignore ) {
6299
                    if ( isset( $field[ 'options' ][ $ignore ] ) )
6300
                        unset( $field[ 'options' ][ $ignore ] );
6301
                }
6302
6303 View Code Duplication
                foreach ( $field[ 'options' ] as $option => $value ) {
6304
                    if ( is_array( $value ) ) {
6305
                        foreach ( $value as $k => $v ) {
6306
                            if ( !is_array( $v ) )
6307
                                $value[ $k ] = maybe_unserialize( $v );
6308
                        }
6309
6310
                        if ( 1 == count( $value ) )
6311
                            $value = current( $value );
6312
                    }
6313
                    else
6314
                        $value = maybe_unserialize( $value );
6315
6316
                    $field[ 'options' ][ $option ] = $value;
6317
                }
6318
6319
                $field[ 'options' ] = array_merge( $defaults, $field[ 'options' ] );
6320
6321
                $field[ 'type' ] = $field[ 'options' ][ 'type' ];
6322
6323
                unset( $field[ 'options' ][ 'type' ] );
6324
6325 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_object' ] ) ) {
6326
                    $field[ 'pick_object' ] = $field[ 'options' ][ 'pick_object' ];
6327
6328
                    unset( $field[ 'options' ][ 'pick_object' ] );
6329
                }
6330
6331 View Code Duplication
                if ( isset( $field[ 'options' ][ 'pick_val' ] ) ) {
6332
                    $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_val' ];
6333
6334
                    unset( $field[ 'options' ][ 'pick_val' ] );
6335
                }
6336
6337 View Code Duplication
                if ( isset( $field[ 'options' ][ 'sister_id' ] ) ) {
6338
                    $field[ 'sister_id' ] = $field[ 'options' ][ 'sister_id' ];
6339
6340
                    unset( $field[ 'options' ][ 'sister_id' ] );
6341
                }
6342
6343
                if ( isset( $field[ 'options' ][ 'sister_field_id' ] ) )
6344
                    unset( $field[ 'options' ][ 'sister_field_id' ] );
6345
6346 View Code Duplication
                if ( pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6347
                    pods_transient_set( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $field[ 'name' ], $field );
6348
            }
6349
        }
6350
6351
        $field[ 'table_info' ] = array();
6352
6353
        if ( 'pick' == $field[ 'type' ] && $params->table_info )
6354
            $field[ 'table_info' ] = $this->get_table_info( $field[ 'pick_object' ], $field[ 'pick_val' ], null, null, $field );
6355
6356
        return $field;
6357
    }
6358
6359
    /**
6360
     * Load fields by Pod, ID, Name, and/or Type
6361
     *
6362
     * $params['pod_id'] int The Pod ID
6363
     * $params['pod'] string The Pod name
6364
     * $params['id'] array The field IDs
6365
     * $params['name'] array The field names
6366
     * $params['type'] array The field types
6367
     * $params['options'] array Field Option(s) key=>value array to filter by
6368
     * $params['where'] string WHERE clause of query
6369
     *
6370
     * @param array $params An associative array of parameters
6371
     * @param bool $strict  Whether to require a field exist or not when loading the info
6372
     *
6373
     * @return array Array of field data.
6374
     *
6375
     * @since 1.7.9
6376
     */
6377
    public function load_fields ( $params, $strict = false ) {
6378
		// @todo Get away from using md5/serialize, I'm sure we can cache specific parts
6379
	    $cache_key = md5( serialize( $params  ) );
6380
	    if ( isset( $this->fields_cache[ $cache_key ] ) ) {
6381
		    return $this->fields_cache[ $cache_key ];
6382
	    }
6383
6384
        $params = (object) pods_sanitize( $params );
6385
6386
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6387
            $params->pod = '';
6388
6389
        if ( !isset( $params->pod_id ) || empty( $params->pod_id ) )
6390
            $params->pod_id = 0;
6391
6392 View Code Duplication
        if ( !isset( $params->name ) || empty( $params->name ) )
6393
            $params->name = array();
6394
        else
6395
            $params->name = (array) $params->name;
6396
6397
        if ( !isset( $params->id ) || empty( $params->id ) )
6398
            $params->id = array();
6399
        else {
6400
            $params->id = (array) $params->id;
6401
6402
            foreach ( $params->id as &$id ) {
6403
                $id = pods_absint( $id );
6404
            }
6405
        }
6406
6407 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6408
            $params->type = array();
6409
        else
6410
            $params->type = (array) $params->type;
6411
6412
        $fields = array();
6413
6414
        if ( !empty( $params->pod ) || !empty( $params->pod_id ) ) {
6415
            $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => true ), false );
6416
6417
            if ( false === $pod ) {
6418
                if ( $strict )
6419
                    return pods_error( __( 'Pod not found', 'pods' ), $this );
6420
6421
                return $fields;
6422
            }
6423
6424
			$pod[ 'fields' ] = array_merge( pods_var_raw( 'object_fields', $pod, array() ), $pod[ 'fields' ] );
6425
6426
            foreach ( $pod[ 'fields' ] as $field ) {
6427
                if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6428
                    $fields[ $field[ 'name' ] ] = $field;
6429
				elseif ( in_array( $fields[ 'name' ], $params->name ) || in_array( $fields[ 'id' ], $params->id ) || in_array( $fields[ 'type' ], $params->type ) )
6430
                    $fields[ $field[ 'name' ] ] = $field;
6431
            }
6432
        }
6433
        elseif ( ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) || ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) ) ) {
6434
            $order = 'ASC';
6435
            $orderby = 'menu_order title';
6436
            $limit = -1;
6437
            $ids = false;
6438
6439
            $meta_query = array();
6440
6441 View Code Duplication
            if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6442
                foreach ( $params->options as $option => $value ) {
6443
                    if ( !is_array( $value ) )
6444
                        $value = array( $value );
6445
6446
                    $value = pods_trim( $value );
6447
6448
                    sort( $value );
6449
6450
                    $meta_query[] = array(
6451
                        'key' => $option,
6452
                        'value' => pods_sanitize( $value ),
6453
                        'compare' => 'IN'
6454
                    );
6455
                }
6456
            }
6457
6458
            if ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) )
6459
                $meta_query = array_merge( $meta_query, (array) $params->where );
6460
6461
			$args = array(
6462
				'post_type' => '_pods_field',
6463
				'nopaging' => true,
6464
				'posts_per_page' => $limit,
6465
				'order' => $order,
6466
				'orderby' => $orderby,
6467
				'meta_query' => $meta_query,
6468
			);
6469
6470
			// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6471
			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...
6472
				$args[ 'post__in' ] = $ids;
6473
			}
6474
6475
            $fields = array();
6476
6477
            $_fields = get_posts( $args );
6478
6479
            foreach ( $_fields as $field ) {
6480
                $field = $this->load_field( $field, false );
6481
6482
                if ( !empty( $field ) )
6483
                    $fields[ $field[ 'id' ] ] = $field;
6484
            }
6485
        }
6486
        else {
6487 View Code Duplication
            if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6488
                return pods_error( __( 'Either Field Name / Field ID / Field Type, or Pod Name / Pod ID are required', 'pods' ), $this );
6489
6490
            $lookup = array();
6491
6492 View Code Duplication
            if ( !empty( $params->name ) ) {
6493
                $fields = implode( "', '", $params->name );
6494
6495
                $lookup[] = "`post_name` IN ( '{$fields}' )";
6496
            }
6497
6498 View Code Duplication
            if ( !empty( $params->id ) ) {
6499
                $fields = implode( ", ", $params->id );
6500
6501
                $lookup[] = "`ID` IN ( {$fields} )";
6502
            }
6503
6504
            $lookup = implode( ' AND ', $lookup );
6505
6506
            $result = pods_query( "SELECT `ID`, `post_name`, `post_parent` FROM `@wp_posts` WHERE `post_type` = '_pods_field' AND ( {$lookup} )" );
6507
6508
            $fields = array();
6509
6510
            if ( !empty( $result ) ) {
6511
                foreach ( $result as $field ) {
6512
					$field = $this->load_field( array(
6513
                        'id' => $field->ID,
6514
                        'name' => $field->post_name,
6515
                        'pod_id' => $field->post_parent
6516
                    ), false );
6517
6518
                    if ( !empty( $field ) && ( empty( $params->type ) || in_array( $field[ 'type' ], $params->type ) ) )
6519
                        $fields[ $field[ 'id' ] ] = $field;
6520
                }
6521
            }
6522
        }
6523
	    if ( isset( $cache_key ) ) {
6524
		    $this->fields_cache[ $cache_key ] = $fields;
6525
	    }
6526
        return $fields;
6527
    }
6528
6529
    /**
6530
     * Load a Pods Object
6531
     *
6532
     * $params['id'] int The Object ID
6533
     * $params['name'] string The Object name
6534
     * $params['type'] string The Object type
6535
     *
6536
     * @param array|object $params An associative array of parameters
6537
     * @param bool $strict
6538
     *
6539
     * @return array|bool
6540
     * @since 2.0
6541
     */
6542
    public function load_object ( $params, $strict = false ) {
6543
        if ( is_object( $params ) && isset( $params->post_title ) )
6544
            $_object = get_object_vars( $params );
6545
        else {
6546
            $params = (object) pods_sanitize( $params );
6547
6548 View Code Duplication
            if ( !isset( $params->type ) || empty( $params->type ) )
6549
                return pods_error( __( 'Object type is required', 'pods' ), $this );
6550
6551 View Code Duplication
            if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) )
6552
                return pods_error( __( 'Either Object ID or Name are required', 'pods' ), $this );
6553
6554
            /**
6555
             * @var $wpdb wpdb
6556
             */
6557
            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...
6558
6559
            if ( isset( $params->name ) )
6560
                $_object = pods_by_title( $params->name, ARRAY_A, '_pods_' . $params->type, 'publish' );
6561
            else {
6562
                $object = $params->id;
6563
6564
                $_object = get_post( $object, ARRAY_A );
6565
            }
6566
6567
            if ( empty( $_object ) ) {
6568
                if ( $strict )
6569
                    return pods_error( __( 'Object not found', 'pods' ), $this );
6570
6571
                return false;
6572
            }
6573
        }
6574
6575
        $object = array(
6576
            'id' => $_object[ 'ID' ],
6577
            'name' => $_object[ 'post_title' ],
6578
            'code' => $_object[ 'post_content' ],
6579
            'type' => str_replace( '_pods_', '', $_object[ 'post_type' ] ),
6580
            'slug' => $_object[ 'post_name' ]
6581
        );
6582
6583
        $object[ 'options' ] = get_post_meta( $object[ 'id' ] );
6584
6585
        foreach ( $object[ 'options' ] as $option => &$value ) {
6586
            if ( is_array( $value ) && 1 == count( $value ) )
6587
                $value = current( $value );
6588
        }
6589
6590
        return $object;
6591
    }
6592
6593
    /**
6594
     * Load Multiple Pods Objects
6595
     *
6596
     * $params['type'] string The Object type
6597
     * $params['options'] array Pod Option(s) key=>value array to filter by
6598
     * $params['orderby'] string ORDER BY clause of query
6599
     * $params['limit'] string Number of objects to return
6600
     * $params['where'] string WHERE clause of query
6601
     * $params['ids'] string|array IDs of Objects
6602
     *
6603
     * @param array|object $params An associative array of parameters
6604
     *
6605
     * @return array
6606
     * @since 2.0
6607
     */
6608
    public function load_objects ( $params ) {
6609
        $params = (object) pods_sanitize( $params );
6610
6611 View Code Duplication
        if ( !isset( $params->type ) || empty( $params->type ) )
6612
            return pods_error( __( 'Pods Object type is required', 'pods' ), $this );
6613
6614
        $order = 'ASC';
6615
        $orderby = 'menu_order';
6616
        $limit = -1;
6617
        $ids = false;
6618
6619
        $meta_query = array();
6620
        $cache_key = '';
6621
6622 View Code Duplication
        if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6623
            foreach ( $params->options as $option => $value ) {
6624
                if ( !is_array( $value ) )
6625
                    $value = array( $value );
6626
6627
                $value = pods_trim( $value );
6628
6629
                sort( $value );
6630
6631
                $meta_query[] = array(
6632
                    'key' => $option,
6633
                    'value' => pods_sanitize( $value ),
6634
                    'compare' => 'IN'
6635
                );
6636
            }
6637
        }
6638
6639
        if ( isset( $params->where ) && is_array( $params->where ) )
6640
            $meta_query = array_merge( $meta_query, (array) $params->where );
6641
6642 View Code Duplication
        if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
6643
            $order = strtoupper( $params->order );
6644
6645
        if ( isset( $params->orderby ) && !empty( $params->orderby ) )
6646
            $orderby = strtoupper( $params->orderby );
6647
6648
        if ( isset( $params->limit ) && !empty( $params->limit ) )
6649
            $limit = pods_absint( $params->limit );
6650
6651
        if ( isset( $params->ids ) && !empty( $params->ids ) ) {
6652
            $ids = $params->ids;
6653
6654
            if ( !is_array( $ids ) )
6655
                $ids = explode( ',', $ids );
6656
        }
6657
6658
        if ( empty( $ids ) )
6659
            $ids = false;
6660
6661
        if ( pods_api_cache() && empty( $meta_query ) && empty( $limit ) && ( empty( $orderby ) || 'menu_order' == $orderby ) && empty( $ids ) ) {
6662
            $cache_key = 'pods_objects_' . $params->type;
6663
6664
            $the_objects = pods_transient_get( $cache_key );
6665
6666
            if ( false !== $the_objects )
6667
                return $the_objects;
6668
        }
6669
6670
        $the_objects = array();
6671
6672
		$args = array(
6673
			'post_type' => '_pods_' . $params->type,
6674
			'nopaging' => true,
6675
			'posts_per_page' => $limit,
6676
			'order' => $order,
6677
			'orderby' => $orderby,
6678
			'meta_query' => $meta_query,
6679
		);
6680
6681
		// Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6682
		if ( false != $ids ) {
6683
			$args[ 'post__in' ] = $ids;
6684
		}
6685
6686
		$objects = get_posts( $args );
6687
6688
        foreach ( $objects as $object ) {
6689
            $object = $this->load_object( $object );
6690
6691
            $the_objects[ $object[ 'name' ] ] = $object;
6692
        }
6693
6694
        if ( pods_api_cache() && !empty( $cache_key ) )
6695
            pods_transient_set( $cache_key, $the_objects );
6696
6697
        return $the_objects;
6698
    }
6699
6700
    /**
6701
     * @see PodsAPI::load_object
6702
     *
6703
     * Load a Pod Template
6704
     *
6705
     * $params['id'] int The template ID
6706
     * $params['name'] string The template name
6707
     *
6708
     * @param array $params An associative array of parameters
6709
     *
6710
     * @return array|bool
6711
     * @since 1.7.9
6712
     */
6713
    public function load_template ( $params ) {
6714
        if ( !class_exists( 'Pods_Templates' ) )
6715
            return false;
6716
6717
        $params = (object) $params;
6718
        $params->type = 'template';
6719
        return $this->load_object( $params );
6720
    }
6721
6722
    /**
6723
     * @see PodsAPI::load_objects
6724
     *
6725
     * Load Multiple Pod Templates
6726
     *
6727
     * $params['where'] string The WHERE clause of query
6728
     * $params['options'] array Pod Option(s) key=>value array to filter by
6729
     * $params['orderby'] string ORDER BY clause of query
6730
     * $params['limit'] string Number of templates to return
6731
     *
6732
     * @param array $params (optional) An associative array of parameters
6733
     *
6734
     * @return array
6735
     *
6736
     * @since 2.0
6737
     */
6738
    public function load_templates ( $params = null ) {
6739
        if ( !class_exists( 'Pods_Templates' ) )
6740
            return array();
6741
6742
        $params = (object) $params;
6743
        $params->type = 'template';
6744
        return $this->load_objects( $params );
6745
    }
6746
6747
    /**
6748
     * @see PodsAPI::load_object
6749
     *
6750
     * Load a Pod Page
6751
     *
6752
     * $params['id'] int The page ID
6753
     * $params['name'] string The page URI
6754
     *
6755
     * @param array $params An associative array of parameters
6756
     *
6757
     * @return array|bool
6758
     *
6759
     * @since 1.7.9
6760
     */
6761
    public function load_page ( $params ) {
6762
        if ( !class_exists( 'Pods_Pages' ) )
6763
            return false;
6764
6765
        $params = (object) $params;
6766 View Code Duplication
        if ( !isset( $params->name ) && isset( $params->uri ) ) {
6767
            $params->name = $params->uri;
6768
            unset( $params->uri );
6769
        }
6770
        $params->type = 'page';
6771
        return $this->load_object( $params );
6772
    }
6773
6774
    /**
6775
     * @see PodsAPI::load_objects
6776
     *
6777
     * Load Multiple Pod Pages
6778
     *
6779
     * $params['where'] string The WHERE clause of query
6780
     * $params['options'] array Pod Option(s) key=>value array to filter by
6781
     * $params['orderby'] string ORDER BY clause of query
6782
     * $params['limit'] string Number of pages to return
6783
     *
6784
     * @param array $params (optional) An associative array of parameters
6785
     *
6786
     * @return array
6787
     *
6788
     * @since 2.0
6789
     */
6790
    public function load_pages ( $params = null ) {
6791
        if ( !class_exists( 'Pods_Pages' ) )
6792
            return array();
6793
6794
        $params = (object) $params;
6795
        $params->type = 'page';
6796
        return $this->load_objects( $params );
6797
    }
6798
6799
    /**
6800
     * @see PodsAPI::load_object
6801
     *
6802
     * Load a Pod Helper
6803
     *
6804
     * $params['id'] int The helper ID
6805
     * $params['name'] string The helper name
6806
     *
6807
     * @param array $params An associative array of parameters
6808
     *
6809
     * @return array|bool
6810
     *
6811
     * @since 1.7.9
6812
     */
6813 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...
6814
        if ( !class_exists( 'Pods_Helpers' ) )
6815
            return false;
6816
6817
        $params = (object) $params;
6818
        $params->type = 'helper';
6819
        return $this->load_object( $params );
6820
    }
6821
6822
    /**
6823
     * @see PodsAPI::load_objects
6824
     *
6825
     * Load Multiple Pod Helpers
6826
     *
6827
     * $params['where'] string The WHERE clause of query
6828
     * $params['options'] array Pod Option(s) key=>value array to filter by
6829
     * $params['orderby'] string ORDER BY clause of query
6830
     * $params['limit'] string Number of pages to return
6831
     *
6832
     * @param array $params (optional) An associative array of parameters
6833
     *
6834
     * @return array
6835
     *
6836
     * @since 2.0
6837
     */
6838 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...
6839
        if ( !class_exists( 'Pods_Helpers' ) )
6840
            return array();
6841
6842
        $params = (object) $params;
6843
        $params->type = 'helper';
6844
        return $this->load_objects( $params );
6845
    }
6846
6847
    /**
6848
     * Load the pod item object
6849
     *
6850
     * $params['pod'] string The datatype name
6851
     * $params['id'] int (optional) The item's ID
6852
     *
6853
     * @param array $params An associative array of parameters
6854
     *
6855
     * @return bool|\Pods
6856
     *
6857
     * @uses pods()
6858
     *
6859
     * @since 2.0
6860
     */
6861
    public function load_pod_item ( $params ) {
6862
        $params = (object) pods_sanitize( $params );
6863
6864 View Code Duplication
        if ( !isset( $params->pod ) || empty( $params->pod ) )
6865
            return pods_error( __( 'Pod name required', 'pods' ), $this );
6866 View Code Duplication
        if ( !isset( $params->id ) || empty( $params->id ) )
6867
            return pods_error( __( 'Item ID required', 'pods' ), $this );
6868
6869
        $pod = false;
6870
6871
        if ( pods_api_cache() )
6872
            $pod = pods_cache_get( $params->id, 'pods_item_object_' . $params->pod );
6873
6874
        if ( false !== $pod )
6875
            return $pod;
6876
6877
        $pod = pods( $params->pod, $params->id );
6878
6879
        if ( pods_api_cache() )
6880
            pods_cache_set( $params->id, $pod, 'pods_item_object_' . $params->pod );
6881
6882
        return $pod;
6883
    }
6884
6885
    /**
6886
     * Load potential sister fields for a specific field
6887
     *
6888
     * $params['pod'] int The Pod name
6889
     * $params['related_pod'] string The related Pod name
6890
     *
6891
     * @param array $params An associative array of parameters
6892
     * @param array $pod (optional) Array of Pod data to use (to avoid lookup)
6893
     *
6894
     * @return array|bool
6895
     *
6896
     * @since 1.7.9
6897
     *
6898
     * @uses PodsAPI::load_pod
6899
     */
6900
    public function load_sister_fields ( $params, $pod = null ) {
6901
        $params = (object) pods_sanitize( $params );
6902
6903
        if ( empty( $pod ) ) {
6904
            $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ), false );
6905
6906
            if ( false === $pod )
6907
                return pods_error( __( 'Pod not found', 'pods' ), $this );
6908
        }
6909
6910
        $params->pod_id = $pod[ 'id' ];
6911
        $params->pod = $pod[ 'name' ];
6912
6913
        $type = false;
6914
6915
        if ( 0 === strpos( $params->related_pod, 'pod-' ) ) {
6916
            $params->related_pod = pods_str_replace( 'pod-', '', $params->related_pod, 1 );
6917
            $type = 'pod';
6918
        }
6919 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'post_type-' ) ) {
6920
            $params->related_pod = pods_str_replace( 'post_type-', '', $params->related_pod, 1 );
6921
            $type = 'post_type';
6922
        }
6923 View Code Duplication
        elseif ( 0 === strpos( $params->related_pod, 'taxonomy-' ) ) {
6924
            $params->related_pod = pods_str_replace( 'taxonomy-', '', $params->related_pod, 1 );
6925
            $type = 'taxonomy';
6926
        }
6927
        elseif ( 'comment' === $params->related_pod ) {
6928
            $type = $params->related_pod;
6929
        }
6930
6931
        $related_pod = $this->load_pod( array( 'name' => $params->related_pod, 'table_info' => false ), false );
6932
6933
        if ( false === $related_pod || ( false !== $type && 'pod' != $type && $type != $related_pod[ 'type' ] ) )
6934
            return pods_error( __( 'Related Pod not found', 'pods' ), $this );
6935
6936
        $params->related_pod_id = $related_pod[ 'id' ];
6937
        $params->related_pod = $related_pod[ 'name' ];
6938
6939
        $sister_fields = array();
6940
6941
        foreach ( $related_pod[ 'fields' ] as $field ) {
6942
            if ( 'pick' == $field[ 'type' ] && in_array( $field[ 'pick_object' ], array( $pod[ 'type' ], 'pod' ) ) && ( $params->pod == $field[ 'pick_object' ] || $params->pod == $field[ 'pick_val' ] ) )
6943
                $sister_fields[ $field[ 'id' ] ] = esc_html( $field[ 'label' ] . ' (' . $field[ 'name' ] . ')' );
6944
        }
6945
6946
        return $sister_fields;
6947
    }
6948
6949
    /**
6950
     * Takes a sql field such as tinyint and returns the pods field type, such as num.
6951
     *
6952
     * @param string $sql_field The SQL field to look for
6953
     *
6954
     * @return string The field type
6955
     *
6956
     * @since 2.0
6957
     */
6958
    public static function detect_pod_field_from_sql_data_type ( $sql_field ) {
6959
        $sql_field = strtolower( $sql_field );
6960
6961
        $field_to_field_map = array(
6962
            'tinyint' => 'number',
6963
            'smallint' => 'number',
6964
            'mediumint' => 'number',
6965
            'int' => 'number',
6966
            'bigint' => 'number',
6967
            'float' => 'number',
6968
            'double' => 'number',
6969
            'decimal' => 'number',
6970
            'date' => 'date',
6971
            'datetime' => 'datetime',
6972
            'timestamp' => 'datetime',
6973
            'time' => 'time',
6974
            'year' => 'date',
6975
            'varchar' => 'text',
6976
            'text' => 'paragraph',
6977
            'mediumtext' => 'paragraph',
6978
            'longtext' => 'paragraph'
6979
        );
6980
6981
        return ( array_key_exists( $sql_field, $field_to_field_map ) ) ? $field_to_field_map[ $sql_field ] : 'paragraph';
6982
    }
6983
6984
    /**
6985
     * Gets all field types
6986
     *
6987
     * @return array Array of field types
6988
     *
6989
     * @uses PodsForm::field_loader
6990
     *
6991
     * @since 2.0
6992
     * @deprecated
6993
     */
6994
    public function get_field_types () {
6995
        return PodsForm::field_types();
6996
    }
6997
6998
    /**
6999
     * Gets the schema definition of a field.
7000
     *
7001
     * @param string $type Field type to look for
7002
     * @param array $options (optional) Options of the field to pass to the schema function.
7003
     *
7004
     * @return array|bool|mixed|null
7005
     *
7006
     * @since 2.0
7007
     */
7008
    private function get_field_definition ( $type, $options = null ) {
7009
        $definition = PodsForm::field_method( $type, 'schema', $options );
7010
7011
        return $this->do_hook( 'field_definition', $definition, $type, $options );
7012
    }
7013
7014
    /**
7015
     * @see PodsForm:validate
7016
     *
7017
     * Validates the value of a field.
7018
     *
7019
     * @param mixed $value The value to validate
7020
     * @param string $field Field to use for validation
7021
     * @param array $object_fields Fields of the object we're validating
7022
     * @param array $fields Array of all fields data
7023
     * @param array|Pods $pod Array of pod data (or Pods object)
7024
     * @param array|object $params Extra parameters to pass to the validation function of the field.
7025
     *
7026
     * @return array|bool
7027
     *
7028
     * @uses PodsForm::validate
7029
     *
7030
     * @since 2.0
7031
     */
7032
    public function handle_field_validation ( &$value, $field, $object_fields, $fields, $pod, $params ) {
7033
        $tableless_field_types = PodsForm::tableless_field_types();
7034
7035
        $fields = array_merge( $fields, $object_fields );
7036
7037
        $options = $fields[ $field ];
7038
7039
        $id = ( is_object( $params ) ? $params->id : ( is_object( $pod ) ? $pod->id() : 0 ) );
7040
7041
        if ( is_object( $pod ) )
7042
            $pod = $pod->pod_data;
7043
7044
        $type = $options[ 'type' ];
7045
        $label = $options[ 'label' ];
7046
        $label = empty( $label ) ? $field : $label;
7047
7048
        // Verify required fields
7049
        if ( 1 == pods_var( 'required', $options[ 'options' ], 0 ) && 'slug' != $type ) {
7050
            if ( '' == $value || null === $value || array() === $value )
7051
                return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this );
7052
7053
            if ( 'multi' == pods_var( 'pick_format_type', $options[ 'options' ] ) && 'autocomplete' != pods_var( 'pick_format_multi', $options[ 'options' ] ) ) {
7054
                $has_value = false;
7055
7056
                $check_value = (array) $value;
7057
7058
                foreach ( $check_value as $val ) {
7059
                    if ( '' != $val && null !== $val && 0 !== $val && '0' !== $val ) {
7060
                        $has_value = true;
7061
7062
                        continue;
7063
                    }
7064
                }
7065
7066
                if ( !$has_value )
7067
                    return pods_error( sprintf( __( '%s is required', 'pods' ), $label ), $this );
7068
            }
7069
7070
        }
7071
7072
        // @todo move this to after pre-save preparations
7073
        // Verify unique fields
7074
        if ( 1 == pods_var( 'unique', $options[ 'options' ], 0 ) && '' !== $value && null !== $value && array() !== $value ) {
7075
            if ( empty( $pod ) )
7076
                return false;
7077
7078
            if ( !in_array( $type, $tableless_field_types ) ) {
7079
                $exclude = '';
7080
7081
                if ( !empty( $id ) )
7082
                    $exclude = "AND `id` != {$id}";
7083
7084
                $check = false;
7085
7086
                $check_value = pods_sanitize( $value );
7087
7088
                // @todo handle meta-based fields
7089
                // Trigger an error if not unique
7090
                if ( 'table' == $pod[ 'storage' ] )
7091
                    $check = pods_query( "SELECT `id` FROM `@wp_pods_" . $pod[ 'name' ] . "` WHERE `{$field}` = '{$check_value}' {$exclude} LIMIT 1", $this );
7092
7093
                if ( !empty( $check ) )
7094
                    return pods_error( sprintf( __( '%s needs to be unique', 'pods' ), $label ), $this );
7095
            }
7096
            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...
7097
                // @todo handle tableless check
7098
            }
7099
        }
7100
7101
        $validate = PodsForm::validate( $options[ 'type' ], $value, $field, array_merge( $options, pods_var( 'options', $options, array() ) ), $fields, $pod, $id, $params );
7102
7103
        $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params );
7104
7105
        return $validate;
7106
    }
7107
7108
    /**
7109
     * Find items related to a parent field
7110
     *
7111
     * @param int $field_id The Field ID
7112
     * @param int $pod_id The Pod ID
7113
     * @param mixed $ids A comma-separated string (or array) of item IDs
7114
     * @param array $field Field data array
7115
     * @param array $pod Pod data array
7116
     *
7117
     * @return int[]
7118
     *
7119
     * @since 2.0
7120
     *
7121
     * @uses pods_query()
7122
     */
7123
    public function lookup_related_items ( $field_id, $pod_id, $ids, $field = null, $pod = null ) {
7124
        $related_ids = array();
7125
7126
        if ( !is_array( $ids ) )
7127
            $ids = explode( ',', $ids );
7128
7129
        $ids = array_map( 'absint', $ids );
7130
7131
        $ids = array_unique( array_filter( $ids ) );
7132
7133
	    $idstring = implode( ',', $ids );
7134
7135
	    if ( 0 != $pod_id && 0 != $field_id && isset( self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] ) ) {
7136
		    // Check cache first, no point in running the same query multiple times
7137
		    return self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ];
7138
	    }
7139
7140
        $tableless_field_types = PodsForm::tableless_field_types();
7141
7142
		$field_type = pods_v( 'type', $field );
7143
7144
        if ( empty( $ids ) || !in_array( $field_type, $tableless_field_types ) )
7145
            return array();
7146
7147
        $related_pick_limit = 0;
7148
7149
		if ( empty( $field ) ) {
7150
			$field = $this->load_field( array( 'id' => $field_id ) );
7151
		}
7152
7153
        if ( !empty( $field ) ) {
7154
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7155
7156
            $related_pick_limit = (int) pods_v( $field_type . '_limit', $options, 0 );
7157
7158
            if ( 'single' == pods_var_raw( $field_type . '_format_type', $options ) )
7159
                $related_pick_limit = 1;
7160
7161
            // Temporary hack until there's some better handling here
7162
            $related_pick_limit = $related_pick_limit * count( $ids );
7163
        }
7164
7165
		if ( 'taxonomy' == $field_type ) {
7166
			$related = wp_get_object_terms( $ids, pods_v( 'name', $field ), array( 'fields' => 'ids' ) );
7167
7168
			if ( !is_wp_error( $related ) ) {
7169
				$related_ids = $related;
7170
			}
7171
		} elseif ( 'comment' == $field_type ) {
7172
			$comment_args = array(
7173
				'post__in' => $ids,
7174
				'fields' => 'ids',
7175
			);
7176
7177
			$related = get_comments( $comment_args );
7178
7179
			if ( ! is_wp_error( $related ) ) {
7180
				$related_ids = $related;
7181
			}
7182
		} elseif ( !pods_tableless() ) {
7183
            $ids = implode( ', ', $ids );
7184
7185
            $field_id = (int) $field_id;
7186
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7187
7188
            $related_where = "
7189
                `field_id` = {$field_id}
7190
                AND `item_id` IN ( {$ids} )
7191
            ";
7192
7193
            $sql = "
7194
                SELECT item_id, related_item_id, related_field_id
7195
                FROM `@wp_podsrel`
7196
                WHERE
7197
                    {$related_where}
7198
                ORDER BY `weight`
7199
            ";
7200
7201
            $relationships = pods_query( $sql );
7202
7203
            if ( !empty( $relationships ) ) {
7204
                foreach ( $relationships as $relation ) {
7205
                    if ( !in_array( $relation->related_item_id, $related_ids ) )
7206
                        $related_ids[] = (int) $relation->related_item_id;
7207
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->item_id, $related_ids ) )
7208
                        $related_ids[] = (int) $relation->item_id;
7209
                }
7210
            }
7211
        }
7212 View Code Duplication
        else {
7213
            if ( !is_array( $pod ) )
7214
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7215
7216
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
7217
                $meta_type = $pod[ 'type' ];
7218
7219
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
7220
                    $meta_type = 'post';
7221
                elseif ( 'taxonomy' == $meta_type )
7222
                    $meta_type = 'term';
7223
7224
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7225
7226
                if ( !$no_conflict )
7227
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7228
7229
                foreach ( $ids as $id ) {
7230
                    if ( 'settings' == $meta_type ) {
7231
                        $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7232
7233
                        if ( empty( $related_id ) )
7234
                            $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7235
7236
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
7237
                            foreach ( $related_id as $related ) {
7238
                                if ( is_array( $related ) && !empty( $related ) ) {
7239
                                    if ( isset( $related[ 'id' ] ) )
7240
                                        $related_ids[] = (int) $related[ 'id' ];
7241
                                    else {
7242
                                        foreach ( $related as $r ) {
7243
                                            $related_ids[] = (int) $r;
7244
                                        }
7245
                                    }
7246
                                }
7247
                                else
7248
                                    $related_ids[] = (int) $related;
7249
                            }
7250
                        }
7251
                    }
7252
                    else {
7253
                        $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7254
7255
                        if ( empty( $related_id ) )
7256
                            $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7257
7258
                        if ( is_array( $related_id ) && !empty( $related_id ) ) {
7259
                            foreach ( $related_id as $related ) {
7260
                                if ( is_array( $related ) && !empty( $related ) ) {
7261
                                    if ( isset( $related[ 'id' ] ) )
7262
                                        $related_ids[] = (int) $related[ 'id' ];
7263
                                    else {
7264
                                        foreach ( $related as $r ) {
7265
                                            if ( isset( $related[ 'id' ] ) )
7266
                                                $related_ids[] = (int) $r[ 'id' ];
7267
                                            else
7268
                                                $related_ids[] = (int) $r;
7269
                                        }
7270
                                    }
7271
                                }
7272
                                else
7273
                                    $related_ids[] = (int) $related;
7274
                            }
7275
                        }
7276
                    }
7277
                }
7278
7279
                if ( !$no_conflict )
7280
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7281
            }
7282
        }
7283
7284
        if ( is_array( $related_ids ) ) {
7285
            $related_ids = array_unique( array_filter( $related_ids ) );
7286
7287
            if ( 0 < $related_pick_limit && !empty( $related_ids ) )
7288
                $related_ids = array_slice( $related_ids, 0, $related_pick_limit );
7289
        }
7290
	    if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) {
7291
                    // Only cache if $pod_id and $field_id were passed
7292
		    self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] = $related_ids;
7293
	    }
7294
7295
        return $related_ids;
7296
    }
7297
7298
    /**
7299
     * Find related items related to an item
7300
     *
7301
     * @param int $field_id The Field ID
7302
     * @param int $pod_id The Pod ID
7303
     * @param int $id Item ID to get related IDs from
7304
     * @param array $field Field data array
7305
     * @param array $pod Pod data array
7306
     *
7307
     * @return array|bool
7308
     *
7309
     * @since 2.3
7310
     *
7311
     * @uses pods_query()
7312
     */
7313
    public function lookup_related_items_from ( $field_id, $pod_id, $id, $field = null, $pod = null ) {
7314
        $related_ids = false;
7315
7316
        $id = (int) $id;
7317
7318
        $tableless_field_types = PodsForm::tableless_field_types();
7319
7320
        if ( empty( $id ) || !in_array( pods_v( 'type', $field ), $tableless_field_types ) )
7321
            return false;
7322
7323
        $related_pick_limit = 0;
7324
7325
        if ( !empty( $field ) ) {
7326
            $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7327
7328
            $related_pick_limit = (int) pods_v( 'pick_limit', $options, 0 );
7329
7330
            if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
7331
                $related_pick_limit = 1;
7332
        }
7333
7334
        if ( !pods_tableless() ) {
7335
            $field_id = (int) $field_id;
7336
            $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7337
7338
            $related_where = "
7339
                `field_id` = {$field_id}
7340
                AND `related_item_id` = {$id}
7341
            ";
7342
7343
            $sql = "
7344
                SELECT *
7345
                FROM `@wp_podsrel`
7346
                WHERE
7347
                    {$related_where}
7348
                ORDER BY `weight`
7349
            ";
7350
7351
            $relationships = pods_query( $sql );
7352
7353
            if ( !empty( $relationships ) ) {
7354
                $related_ids = array();
7355
7356
                foreach ( $relationships as $relation ) {
7357
                    if ( $field_id == $relation->field_id && !in_array( $relation->item_id, $related_ids ) )
7358
                        $related_ids[] = (int) $relation->item_id;
7359
                    elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->related_item_id, $related_ids ) )
7360
                        $related_ids[] = (int) $relation->related_item_id;
7361
                }
7362
            }
7363
        }
7364 View Code Duplication
        else {
7365
            // @todo handle meta-based lookups
7366
            return false;
7367
7368
            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...
7369
                $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7370
7371
            if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
7372
                $related_ids = array();
7373
7374
                $meta_type = $pod[ 'type' ];
7375
7376
                if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
7377
                    $meta_type = 'post';
7378
                elseif ( 'taxonomy' == $meta_type )
7379
                    $meta_type = 'term';
7380
7381
                $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7382
7383
                if ( !$no_conflict )
7384
                    pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7385
7386
                if ( 'settings' == $meta_type ) {
7387
                    $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7388
7389
                    if ( empty( $related_id ) )
7390
                        $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7391
7392
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7393
                        foreach ( $related_id as $related ) {
7394
                            if ( is_array( $related ) && !empty( $related ) ) {
7395
                                if ( isset( $related[ 'id' ] ) )
7396
                                    $related_ids[] = (int) $related[ 'id' ];
7397
                                else {
7398
                                    foreach ( $related as $r ) {
7399
                                        $related_ids[] = (int) $r;
7400
                                    }
7401
                                }
7402
                            }
7403
                            else
7404
                                $related_ids[] = (int) $related;
7405
                        }
7406
                    }
7407
                }
7408
                else {
7409
                    $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7410
7411
                    if ( empty( $related_id ) )
7412
                        $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7413
7414
                    if ( is_array( $related_id ) && !empty( $related_id ) ) {
7415
                        foreach ( $related_id as $related ) {
7416
                            if ( is_array( $related ) && !empty( $related ) ) {
7417
                                if ( isset( $related[ 'id' ] ) )
7418
                                    $related_ids[] = (int) $related[ 'id' ];
7419
                                else {
7420
                                    foreach ( $related as $r ) {
7421
                                        if ( isset( $related[ 'id' ] ) )
7422
                                            $related_ids[] = (int) $r[ 'id' ];
7423
                                        else
7424
                                            $related_ids[] = (int) $r;
7425
                                    }
7426
                                }
7427
                            }
7428
                            else
7429
                                $related_ids[] = (int) $related;
7430
                        }
7431
                    }
7432
                }
7433
7434
                if ( !$no_conflict )
7435
                    pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7436
            }
7437
        }
7438
7439
        if ( is_array( $related_ids ) )
7440
            $related_ids = array_unique( array_filter( $related_ids ) );
7441
7442
        return $related_ids;
7443
    }
7444
7445
	/**
7446
	 *
7447
	 * Load the information about an objects MySQL table
7448
	 *
7449
	 * @param $object_type
7450
	 * @param string $object The object to look for
7451
	 * @param null $name (optional) Name of the pod to load
7452
	 * @param array $pod (optional) Array with pod information
7453
	 *
7454
	 * @return array
7455
	 *
7456
	 * @since 2.5
7457
	 */
7458
	public function get_table_info_load ( $object_type, $object, $name = null, $pod = null ) {
7459
7460
		$info = array();
7461
7462
		if ( 'pod' == $object_type && null === $pod ) {
7463 View Code Duplication
			if ( empty( $name ) ) {
7464
				$prefix = 'pod-';
7465
7466
				// Make sure we actually have the prefix before trying anything with the name
7467
				if ( 0 === strpos( $object_type, $prefix ) )
7468
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7469
			}
7470
7471
			if ( empty( $name ) && !empty( $object ) )
7472
				$name = $object;
7473
7474
			$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7475
7476
			if ( !empty( $pod ) ) {
7477
				$object_type = $pod[ 'type' ];
7478
				$name = $pod[ 'name' ];
7479
				$object = $pod[ 'object' ];
7480
7481
				$info[ 'pod' ] = $pod;
7482
			}
7483
		}
7484
		elseif ( null === $pod ) {
7485
			if ( empty( $name ) ) {
7486
				$prefix = $object_type . '-';
7487
7488
				// Make sure we actually have the prefix before trying anything with the name
7489
				if ( 0 === strpos( $object_type, $prefix ) )
7490
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7491
			}
7492
7493
			if ( empty( $name ) && !empty( $object ) )
7494
				$name = $object;
7495
7496
			if ( !empty( $name ) ) {
7497
				$pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7498
7499
				if ( !empty( $pod ) && ( null === $object_type || $object_type == $pod[ 'type' ] ) ) {
7500
					$object_type = $pod[ 'type' ];
7501
					$name = $pod[ 'name' ];
7502
					$object = $pod[ 'object' ];
7503
7504
					$info[ 'pod' ] = $pod;
7505
				}
7506
			}
7507
		}
7508
		elseif ( !empty( $pod ) )
7509
			$info[ 'pod' ] = $pod;
7510
7511
		if ( 0 === strpos( $object_type, 'pod' ) ) {
7512 View Code Duplication
			if ( empty( $name ) ) {
7513
				$prefix = 'pod-';
7514
7515
				// Make sure we actually have the prefix before trying anything with the name
7516
				if ( 0 === strpos( $object_type, $prefix ) )
7517
					$name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7518
			}
7519
7520
			$info[ 'type' ] = 'pod';
7521
			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...
7522
7523
			$info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object );
7524
7525
			if ( is_array( $info[ 'pod' ] ) && 'pod' == pods_v( 'type', $info[ 'pod' ] ) ) {
7526
				$info[ 'pod_field_index' ] = $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_v( 'pod_index', $info[ 'pod' ][ 'options' ], 'id', true );
7527
7528
				$slug_field = get_posts( array(
7529
					'post_type' => '_pods_field',
7530
					'posts_per_page' => 1,
7531
					'nopaging' => true,
7532
					'post_parent' => $info[ 'pod' ][ 'id' ],
7533
					'orderby' => 'menu_order',
7534
					'order' => 'ASC',
7535
					'meta_query' => array(
7536
						array(
7537
							'key' => 'type',
7538
							'value' => 'slug',
7539
						)
7540
					)
7541
				) );
7542
7543
				if ( !empty( $slug_field ) ) {
7544
					$slug_field = $slug_field[ 0 ];
7545
7546
					$info[ 'field_slug' ] = $info[ 'pod_field_slug' ] = $slug_field->post_name;
7547
				}
7548
7549
				if ( 1 == pods_v( 'hierarchical', $info[ 'pod' ][ 'options' ], 0 ) ) {
7550
					$parent_field = pods_v( 'pod_parent', $info[ 'pod' ][ 'options' ], 'id', true );
7551
7552
					if ( !empty( $parent_field ) && isset( $info[ 'pod' ][ 'fields' ][ $parent_field ] ) ) {
7553
						$info[ 'object_hierarchical' ] = true;
7554
7555
						$info[ 'pod_field_parent' ] = $info[ 'field_parent' ] = $parent_field . '_select';
7556
						$info[ 'field_parent_select' ] = '`' . $parent_field . '`.`id` AS `' . $info[ 'field_parent' ] . '`';
7557
					}
7558
				}
7559
			}
7560
		}
7561
		return $info;
7562
	}
7563
7564
    /**
7565
     * Get information about an objects MySQL table
7566
     *
7567
     * @param string $object_type
7568
     * @param string $object The object to look for
7569
     * @param null $name (optional) Name of the pod to load
7570
     * @param array $pod (optional) Array with pod information
7571
     * @param array $field (optional) Array with field information
7572
     *
7573
     * @return array|bool
7574
     *
7575
     * @since 2.0
7576
     */
7577
    public function get_table_info ( $object_type, $object, $name = null, $pod = null, $field = null ) {
7578
7579
	    /**
7580
	     * @var $wpdb                         wpdb
7581
	     * @var $sitepress                    SitePress
7582
	     * @var $polylang                     object
7583
	     */
7584
	    /*
7585
	     * @todo wpml-comp Remove global object usage
7586
	     */
7587
        global $wpdb, $sitepress, $polylang;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

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

1. Pass all data via parameters

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

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

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

    public function myFunction() {
        // Do something
    }
}
Loading history...
7588
7589
		// @todo Handle $object arrays for Post Types, Taxonomies, Comments (table pulled from first object in array)
7590
7591
        $info = array(
7592
            //'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...
7593
            'object_type' => $object_type,
7594
            'type' => null,
7595
            'object_name' => $object,
7596
            'object_hierarchical' => false,
7597
7598
            'table' => $object,
7599
            'meta_table' => $object,
7600
            'pod_table' => $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object ),
7601
7602
            'field_id' => 'id',
7603
            'field_index' => 'name',
7604
            'field_slug' => null,
7605
            'field_type' => null,
7606
            'field_parent' => null,
7607
            'field_parent_select' => null,
7608
7609
            'meta_field_id' => 'id',
7610
            'meta_field_index' => 'name',
7611
            'meta_field_value' => 'name',
7612
7613
            'pod_field_id' => 'id',
7614
            'pod_field_index' => 'name',
7615
            'pod_field_slug' => null,
7616
            'pod_field_parent' => null,
7617
7618
            'join' => array(),
7619
7620
            'where' => null,
7621
            'where_default' => null,
7622
7623
            'orderby' => null,
7624
7625
            'pod' => null,
7626
            'recurse' => false
7627
        );
7628
7629
        if ( empty( $object_type ) ) {
7630
            $object_type = 'post_type';
7631
            $object = 'post';
7632
        }
7633
	    elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ) ) ) {
7634
		    $object = $object_type;
7635
	    }
7636
7637
        $pod_name = $pod;
7638
7639 View Code Duplication
        if ( is_array( $pod_name ) )
7640
            $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...
7641
	    else {
7642
		    $pod_name = $object;
7643
	    }
7644
7645
        $field_name = $field;
7646
7647 View Code Duplication
        if ( is_array( $field_name ) )
7648
            $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...
7649
7650
        $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7651
7652
        $current_language = false;
7653
        $current_language_t_id = $current_language_tt_id = 0;
7654
7655
	    // Get current language data
7656
		$lang_data = PodsInit::$i18n->get_current_language_data();
0 ignored issues
show
Bug introduced by
The property i18n cannot be accessed from this context as it is declared private in class PodsInit.

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

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

Loading history...
7657
7658
	    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...
7659
		    if ( ! empty( $lang_data['language'] ) ) {
7660
			    $current_language = $lang_data['language'];
7661
		    }
7662
7663
		    if ( ! empty( $lang_data['t_id'] ) ) {
7664
			    $current_language_t_id = $lang_data['t_id'];
7665
		    }
7666
7667
		    if ( ! empty( $lang_data['tt_id'] ) ) {
7668
			    $current_language_tt_id = $lang_data['tt_id'];
7669
		    }
7670
7671
		    if ( ! empty( $lang_data['tl_t_id'] ) ) {
7672
			    $current_language_tl_t_id = $lang_data['tl_t_id'];
7673
		    }
7674
7675
		    if ( ! empty( $lang_data['tl_tt_id'] ) ) {
7676
			    $current_language_tl_tt_id = $lang_data['tl_tt_id'];
7677
		    }
7678
	    }
7679
7680
        if ( !empty( $current_language ) )
7681
            $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7682
7683
        $_info = false;
7684
7685
	    if ( isset( self::$table_info_cache[ $transient ] ) ) {
7686
		    // Prefer info from the object internal cache
7687
		    $_info = self::$table_info_cache[ $transient ];
7688
	    } elseif ( pods_api_cache() ) {
7689
		    $_info = pods_transient_get( $transient );
7690
		    if ( false === $_info && ! did_action( 'init' ) ) {
7691
			    $_info = pods_transient_get( $transient . '_pre_init' );
7692
		    }
7693
	    }
7694
7695
	    if ( false !== $_info && is_array( $_info ) ) {
7696
		    // Data was cached, use that
7697
		    $info = $_info;
7698
	    } else {
7699
	        // Data not cached, load it up
7700
		    $_info = $this->get_table_info_load( $object_type, $object, $name, $pod );
7701
		    if ( isset( $_info[ 'type' ] ) ) {
7702
			    // Allow function to override $object_type
7703
			    $object_type = $_info[ 'type' ];
7704
		    }
7705
		    $info = array_merge( $info, $_info );
7706
	    }
7707
7708
	    if ( 0 === strpos( $object_type, 'post_type' ) || 'media' == $object_type || in_array( pods_var_raw( 'type', $info[ 'pod' ] ), array( 'post_type', 'media' ) ) ) {
7709
		    $info[ 'table' ] = $wpdb->posts;
7710
		    $info[ 'meta_table' ] = $wpdb->postmeta;
7711
7712
		    $info[ 'field_id' ] = 'ID';
7713
		    $info[ 'field_index' ] = 'post_title';
7714
		    $info[ 'field_slug' ] = 'post_name';
7715
		    $info[ 'field_type' ] = 'post_type';
7716
		    $info[ 'field_parent' ] = 'post_parent';
7717
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7718
7719
		    $info[ 'meta_field_id' ] = 'post_id';
7720
		    $info[ 'meta_field_index' ] = 'meta_key';
7721
		    $info[ 'meta_field_value' ] = 'meta_value';
7722
7723
		    if ( 'media' == $object_type )
7724
			    $object = 'attachment';
7725
7726
		    if ( empty( $name ) ) {
7727
			    $prefix = 'post_type-';
7728
7729
			    // Make sure we actually have the prefix before trying anything with the name
7730
			    if ( 0 === strpos( $object_type, $prefix ) )
7731
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7732
		    }
7733
7734
		    if ( 'media' != $object_type )
7735
			    $object_type = 'post_type';
7736
7737
		    $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7738
7739
		    if ( 'attachment' == $post_type || 'media' == $object_type )
7740
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_media';
7741
		    else
7742
			    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $post_type, true, false );
7743
7744
		    $post_type_object = get_post_type_object( $post_type );
7745
7746
		    if ( is_object( $post_type_object ) && $post_type_object->hierarchical )
7747
			    $info[ 'object_hierarchical' ] = true;
7748
7749
            // Post Status default
7750
            $post_status = array( 'publish' );
7751
7752
            // Pick field post_status option
7753
            if ( ! empty( $field['pick_post_status'] ) ) {
7754
                $post_status = (array) $field['pick_post_status'];
7755
            }
7756
7757
		    /**
7758
		     * Default Post Status to query for.
7759
		     *
7760
		     * Use to change "default" post status from publish to any other status or statuses.
7761
		     *
7762
		     * @param  array $post_status List of post statuses. Default is 'publish' or field setting (if available)
7763
		     * @param  string $post_type Post type of current object
7764
		     * @param  array $info Array of information about the object.
7765
		     * @param  string $object	Type of object
7766
		     * @param  string $name Name of pod to load
7767
		     * @param  array $pod Array with Pod information. Result of PodsAPI::load_pod()
7768
		     * @param  array $field		Array with field information
7769
		     *
7770
		     * @since unknown
7771
		     */
7772
		    $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', $post_status, $post_type, $info, $object_type, $object, $name, $pod, $field );
7773
7774
		    $info[ 'where' ] = array(
7775
			    //'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...
7776
			    'post_type' => '`t`.`' . $info[ 'field_type' ] . '` = "' . $post_type . '"'
7777
		    );
7778
7779
		    if ( 'post_type' == $object_type )
7780
			    $info[ 'where_default' ] = '`t`.`post_status` IN ( "' . implode( '", "', $post_status ) . '" )';
7781
7782
		    $info[ 'orderby' ] = '`t`.`menu_order`, `t`.`' . $info[ 'field_index' ] . '`, `t`.`post_date`';
7783
7784
            /*
7785
             * @todo wpml-comp Check if WPML filters can be applied afterwards
7786
             */
7787
		    // WPML support
7788
		    if ( did_action( 'wpml_loaded' ) && !empty( $current_language ) && apply_filters( 'wpml_is_translated_post_type', false, $post_type ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' )) {
7789
			    $info[ 'join' ][ 'wpml_translations' ] = "
7790
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7791
                            ON `wpml_translations`.`element_id` = `t`.`ID`
7792
                                AND `wpml_translations`.`element_type` = 'post_{$post_type}'
7793
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7794
                    ";
7795
7796
			    $info[ 'join' ][ 'wpml_languages' ] = "
7797
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7798
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7799
                    ";
7800
7801
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7802
		    }
7803
		    // Polylang support
7804 View Code Duplication
		    elseif( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && !empty( $current_language ) && function_exists( 'pll_is_translated_post_type' ) && pll_is_translated_post_type( $post_type ) ) {
7805
			    $info[ 'join' ][ 'polylang_languages' ] = "
7806
                        LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7807
                            ON `polylang_languages`.`object_id` = `t`.`ID`
7808
                                AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id}
7809
                    ";
7810
7811
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7812
		    }
7813
7814
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7815
	    }
7816
	    elseif ( 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, array( 'nav_menu', 'post_format' ) ) || 'taxonomy' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7817
		    $info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->terms;
7818
7819
		    $info[ 'join' ][ 'tt' ] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`";
7820
		    $info[ 'join' ][ 'tr' ] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`";
7821
		    $info[ 'field_id' ] = $info[ 'meta_field_id' ] = 'term_id';
7822
		    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = 'name';
7823
		    $info[ 'field_slug' ] = 'slug';
7824
		    $info[ 'field_type' ] = 'taxonomy';
7825
		    $info[ 'field_parent' ] = 'parent';
7826
		    $info[ 'field_parent_select' ] = '`tt`.`' . $info[ 'field_parent' ] . '`';
7827
7828
            if ( ! empty( $wpdb->termmeta ) ) {
7829
                $info[ 'meta_table' ] = $wpdb->termmeta;
7830
7831
                $info[ 'meta_field_id' ] = 'term_id';
7832
                $info[ 'meta_field_index' ] = 'meta_key';
7833
                $info[ 'meta_field_value' ] = 'meta_value';
7834
            }
7835
7836
		    if ( 'nav_menu' == $object_type )
7837
			    $object = 'nav_menu';
7838
		    elseif ( 'post_format' == $object_type )
7839
			    $object = 'post_format';
7840
7841
		    if ( empty( $name ) ) {
7842
			    $prefix = 'taxonomy-';
7843
7844
			    // Make sure we actually have the prefix before trying anything with the name
7845
			    if ( 0 === strpos( $object_type, $prefix ) )
7846
				    $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7847
		    }
7848
7849
		    if ( !in_array( $object_type, array( 'nav_menu', 'post_format' ) ) )
7850
			    $object_type = 'taxonomy';
7851
7852
		    $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7853
7854
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $taxonomy, true, false );
7855
7856
		    $taxonomy_object = get_taxonomy( $taxonomy );
7857
7858
		    if ( is_object( $taxonomy_object ) && $taxonomy_object->hierarchical )
7859
			    $info[ 'object_hierarchical' ] = true;
7860
7861
		    $info[ 'where' ] = array(
7862
			    'tt.taxonomy' => '`tt`.`' . $info[ 'field_type' ] . '` = "' . $taxonomy . '"'
7863
		    );
7864
7865
            /*
7866
             * @todo wpml-comp WPML API call for is_translated_taxononomy
7867
             * @todo wpml-comp Check if WPML filters can be applied afterwards
7868
             */
7869
		    // WPML Support
7870
		    if ( is_object( $sitepress ) && !empty( $current_language ) && $sitepress->is_translated_taxonomy( $taxonomy ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
7871
			    $info[ 'join' ][ 'wpml_translations' ] = "
7872
                        LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7873
                            ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id`
7874
                                AND `wpml_translations`.`element_type` = 'tax_{$taxonomy}'
7875
                                AND `wpml_translations`.`language_code` = '{$current_language}'
7876
                    ";
7877
7878
			    $info[ 'join' ][ 'wpml_languages' ] = "
7879
                        LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7880
                            ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7881
                    ";
7882
7883
			    $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7884
		    }
7885
		    // Polylang support
7886 View Code Duplication
		    elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && !empty( $current_language ) && !empty( $current_language_tl_tt_id ) && function_exists( 'pll_is_translated_taxonomy' ) && pll_is_translated_taxonomy( $taxonomy ) ) {
7887
				$info[ 'join' ][ 'polylang_languages' ] = "
7888
					LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7889
						ON `polylang_languages`.`object_id` = `t`.`term_id`
7890
							AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tl_tt_id}
7891
				";
7892
7893
			    $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7894
		    }
7895
7896
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7897
	    }
7898
	    elseif ( 'user' == $object_type || 'user' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7899
		    $info[ 'table' ] = $wpdb->users;
7900
		    $info[ 'meta_table' ] = $wpdb->usermeta;
7901
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_user';
7902
7903
		    $info[ 'field_id' ] = 'ID';
7904
		    $info[ 'field_index' ] = 'display_name';
7905
		    $info[ 'field_slug' ] = 'user_nicename';
7906
7907
		    $info[ 'meta_field_id' ] = 'user_id';
7908
		    $info[ 'meta_field_index' ] = 'meta_key';
7909
		    $info[ 'meta_field_value' ] = 'meta_value';
7910
7911
		    $info[ 'where' ] = array(
7912
			    'user_status' => '`t`.`user_status` = 0'
7913
		    );
7914
7915
		    $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7916
	    }
7917
	    elseif ( 'comment' == $object_type || 'comment' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7918
		    //$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...
7919
7920
		    $info[ 'table' ] = $wpdb->comments;
7921
		    $info[ 'meta_table' ] = $wpdb->commentmeta;
7922
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_comment';
7923
7924
		    $info[ 'field_id' ] = 'comment_ID';
7925
		    $info[ 'field_index' ] = 'comment_date';
7926
		    $info[ 'field_type' ] = 'comment_type';
7927
		    $info[ 'field_parent' ] = 'comment_parent';
7928
		    $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7929
7930
		    $info[ 'meta_field_id' ] = 'comment_id';
7931
		    $info[ 'meta_field_index' ] = 'meta_key';
7932
		    $info[ 'meta_field_value' ] = 'meta_value';
7933
7934
		    $object = 'comment';
7935
7936
		    $comment_type = ( empty( $object ) ? $name : $object );
7937
7938
		    $comment_type_clause = '`t`.`' . $info[ 'field_type' ] . '` = "' . $comment_type . '"';
7939
7940
		    if ( 'comment' == $comment_type ) {
7941
			    $comment_type_clause = '( ' . $comment_type_clause . ' OR `t`.`' . $info[ 'field_type' ] . '` = "" )';
7942
		    }
7943
7944
		    $info[ 'where' ] = array(
7945
			    'comment_approved' => '`t`.`comment_approved` = 1',
7946
			    'comment_type' => $comment_type_clause
7947
		    );
7948
7949
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` DESC, `t`.`' . $info[ 'field_id' ] . '`';
7950
	    }
7951 View Code Duplication
	    elseif ( in_array( $object_type, array( 'option', 'settings' ) ) || 'settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7952
		    $info[ 'table' ] = $wpdb->options;
7953
		    $info[ 'meta_table' ] = $wpdb->options;
7954
7955
		    $info[ 'field_id' ] = 'option_id';
7956
		    $info[ 'field_index' ] = 'option_name';
7957
7958
		    $info[ 'meta_field_id' ] = 'option_id';
7959
		    $info[ 'meta_field_index' ] = 'option_name';
7960
		    $info[ 'meta_field_value' ] = 'option_value';
7961
7962
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7963
	    }
7964 View Code Duplication
	    elseif ( is_multisite() && ( in_array( $object_type, array( 'site_option', 'site_settings' ) ) || 'site_settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) ) {
7965
		    $info[ 'table' ] = $wpdb->sitemeta;
7966
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7967
7968
		    $info[ 'field_id' ] = 'site_id';
7969
		    $info[ 'field_index' ] = 'meta_key';
7970
7971
		    $info[ 'meta_field_id' ] = 'site_id';
7972
		    $info[ 'meta_field_index' ] = 'meta_key';
7973
		    $info[ 'meta_field_value' ] = 'meta_value';
7974
7975
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7976
	    }
7977
	    elseif ( is_multisite() && 'network' == $object_type ) { // Network = Site
7978
		    $info[ 'table' ] = $wpdb->site;
7979
		    $info[ 'meta_table' ] = $wpdb->sitemeta;
7980
7981
		    $info[ 'field_id' ] = 'id';
7982
		    $info[ 'field_index' ] = 'domain';
7983
7984
		    $info[ 'meta_field_id' ] = 'site_id';
7985
		    $info[ 'meta_field_index' ] = 'meta_key';
7986
		    $info[ 'meta_field_value' ] = 'meta_value';
7987
7988
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7989
	    }
7990
	    elseif ( is_multisite() && 'site' == $object_type ) { // Site = Blog
7991
		    $info[ 'table' ] = $wpdb->blogs;
7992
7993
		    $info[ 'field_id' ] = 'blog_id';
7994
		    $info[ 'field_index' ] = 'domain';
7995
		    $info[ 'field_type' ] = 'site_id';
7996
7997
		    $info[ 'where' ] = array(
7998
			    'archived' => '`t`.`archived` = 0',
7999
			    'spam' => '`t`.`spam` = 0',
8000
			    'deleted' => '`t`.`deleted` = 0',
8001
			    'site_id' => '`t`.`' . $info[ 'field_type' ] . '` = ' . (int) get_current_site()->id
8002
		    );
8003
8004
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
8005
	    }
8006
	    elseif ( 'table' == $object_type || 'table' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
8007
		    $info[ 'table' ] = ( empty( $object ) ? $name : $object );
8008
		    $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . $info[ 'table' ];
8009
8010
		    if ( !empty( $field ) && is_array( $field ) ) {
8011
			    $info[ 'table' ] = pods_var_raw( 'pick_table', pods_var_raw( 'options', $field, $field ) );
8012
			    $info[ 'field_id' ] = pods_var_raw( 'pick_table_id', pods_var_raw( 'options', $field, $field ) );
8013
			    $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_var_raw( 'pick_table_index', pods_var_raw( 'options', $field, $field ) );
8014
		    }
8015
	    }
8016
8017
	    $info[ 'table' ] = pods_clean_name( $info[ 'table' ], false, false );
8018
	    $info[ 'meta_table' ] = pods_clean_name( $info[ 'meta_table' ], false, false );
8019
	    $info[ 'pod_table' ] = pods_clean_name( $info[ 'pod_table' ], false, false );
8020
8021
	    $info[ 'field_id' ] = pods_clean_name( $info[ 'field_id' ], false, false );
8022
	    $info[ 'field_index' ] = pods_clean_name( $info[ 'field_index' ], false, false );
8023
	    $info[ 'field_slug' ] = pods_clean_name( $info[ 'field_slug' ], false, false );
8024
8025
	    $info[ 'meta_field_id' ] = pods_clean_name( $info[ 'meta_field_id' ], false, false );
8026
	    $info[ 'meta_field_index' ] = pods_clean_name( $info[ 'meta_field_index' ], false, false );
8027
	    $info[ 'meta_field_value' ] = pods_clean_name( $info[ 'meta_field_value' ], false, false );
8028
8029 View Code Duplication
	    if ( empty( $info[ 'orderby' ] ) )
8030
		    $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '`, `t`.`' . $info[ 'field_id' ] . '`';
8031
8032
	    if ( 'table' == pods_var_raw( 'storage', $info[ 'pod' ] ) && !in_array( $object_type, array( 'pod', 'table' ) ) ) {
8033
		    $info[ 'join' ][ 'd' ] = 'LEFT JOIN `' . $info[ 'pod_table' ] . '` AS `d` ON `d`.`id` = `t`.`' . $info[ 'field_id' ] . '`';
8034
		    //$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...
8035
	    }
8036
8037
	    if ( !empty( $info[ 'pod' ] ) && is_array( $info[ 'pod' ] ) )
8038
		    $info[ 'recurse' ] = true;
8039
8040
	    $info[ 'type' ] = $object_type;
8041
	    $info[ 'object_name' ] = $object;
8042
8043
	    if ( pods_api_cache() ) {
8044
		    if ( ! did_action( 'init' ) ) {
8045
			    $transient .= '_pre_init';
8046
		    }
8047
		    pods_transient_set( $transient, $info );
8048
	    }
8049
8050
8051
	    self::$table_info_cache[ $transient ] = apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
8052
8053
        return self::$table_info_cache[ $transient ];
8054
    }
8055
8056
    /**
8057
     * Export a package
8058
     *
8059
     * $params['pod'] string Pod Type IDs to export
8060
     * $params['template'] string Template IDs to export
8061
     * $params['podpage'] string Pod Page IDs to export
8062
     * $params['helper'] string Helper IDs to export
8063
     *
8064
     * @param array $params An associative array of parameters
8065
     *
8066
     * @return array|bool
8067
     *
8068
     * @since 1.9.0
8069
     * @deprecated 2.0
8070
     */
8071
    public function export_package ( $params ) {
8072
        if ( class_exists( 'Pods_Migrate_Packages' ) )
8073
            return Pods_Migrate_Packages::export( $params );
8074
8075
        return false;
8076
    }
8077
8078
    /**
8079
     * Replace an existing package
8080
     *
8081
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
8082
     *
8083
     * @return bool
8084
     *
8085
     * @since 1.9.8
8086
     * @deprecated 2.0
8087
     */
8088
    public function replace_package ( $data = false ) {
8089
        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...
8090
    }
8091
8092
    /**
8093
     * Import a package
8094
     *
8095
     * @param mixed $data (optional) An associative array containing a package, or the json encoded package
8096
     * @param bool $replace (optional) Replace existing items when found
8097
     *
8098
     * @return bool
8099
     *
8100
     * @since 1.9.0
8101
     * @deprecated 2.0
8102
     */
8103
    public function import_package ( $data = false, $replace = false ) {
8104
        if ( class_exists( 'Pods_Migrate_Packages' ) )
8105
            return Pods_Migrate_Packages::import( $data, $replace );
8106
8107
        return false;
8108
    }
8109
8110
    /**
8111
     * Validate a package
8112
     *
8113
     * @param array|string $data (optional) An associative array containing a package, or the json encoded package
8114
     * @param bool $output (optional)
8115
     *
8116
     * @return array|bool
8117
     *
8118
     * @since 1.9.0
8119
     * @deprecated 2.0
8120
     */
8121
    public function validate_package ( $data = false, $output = false ) {
8122
        return true;
8123
    }
8124
8125
    /**
8126
     * Import data from an array or a CSV file.
8127
     *
8128
     * @param mixed $import_data PHP associative array or CSV input
8129
     * @param bool $numeric_mode Use IDs instead of the name field when matching
8130
     * @param string $format Format of import data, options are php or csv
8131
     *
8132
     * @return array IDs of imported items
8133
     *
8134
     * @since 1.7.1
8135
     * @todo This needs some love and use of table_info etc for relationships
8136
     */
8137
    public function import ( $import_data, $numeric_mode = false, $format = null ) {
8138
        /**
8139
         * @var $wpdb wpdb
8140
         */
8141
        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...
8142
8143
        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...
8144
            $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...
8145
8146
        if ( 'csv' == $format && !is_array( $import_data ) ) {
8147
            $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...
8148
8149
            $import_data = $data[ 'items' ];
8150
        }
8151
8152
        pods_query( "SET NAMES utf8" );
8153
        pods_query( "SET CHARACTER SET utf8" );
8154
8155
        // Loop through the array of items
8156
        $ids = array();
8157
8158
        // Test to see if it's an array of arrays
8159
        if ( !is_array( @current( $import_data ) ) )
8160
            $import_data = array( $import_data );
8161
8162
        $pod = $this->load_pod( array( 'name' => $this->pod ) );
8163
8164
        if ( false === $pod )
8165
            return pods_error( __( 'Pod not found', 'pods' ), $this );
8166
8167
        $fields = array_merge( $pod[ 'fields' ], $pod[ 'object_fields' ] );
8168
8169
        $simple_tableless_objects = PodsForm::simple_tableless_objects();
8170
8171
        foreach ( $import_data as $key => $data_row ) {
8172
            $data = array();
8173
8174
            // Loop through each field (use $fields so only valid fields get parsed)
8175
            foreach ( $fields as $field_name => $field_data ) {
8176
                if ( !isset( $data_row[ $field_name ] ) && !isset( $data_row[ $field_data[ 'label' ] ] ) )
8177
                    continue;
8178
8179
                $field_id = $field_data[ 'id' ];
8180
                $type = $field_data[ 'type' ];
8181
                $pick_object = isset( $field_data[ 'pick_object' ] ) ? $field_data[ 'pick_object' ] : '';
8182
                $pick_val = isset( $field_data[ 'pick_val' ] ) ?  $field_data[ 'pick_val' ] : '';
8183
8184
                if ( isset( $data_row[ $field_name] ) )
8185
                    $field_value = $data_row[ $field_name ];
8186
                else
8187
                    $field_value = $data_row[ $field_data[ 'label' ] ];
8188
8189
                if ( null !== $field_value && false !== $field_value && '' !== $field_value ) {
8190
                    if ( 'pick' == $type || in_array( $type, PodsForm::file_field_types() ) ) {
8191
                        $field_values = is_array( $field_value ) ? $field_value : array( $field_value );
8192
                        $pick_values = array();
8193
8194
                        foreach ( $field_values as $pick_value ) {
8195
                            if ( in_array( $type, PodsForm::file_field_types() ) || 'media' == $pick_object ) {
8196
                                $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'";
8197
8198 View Code Duplication
                                if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8199
                                    $where = "`ID` = " . pods_absint( $pick_value );
8200
8201
                                $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = 'attachment' AND {$where} ORDER BY `ID`", $this );
8202
8203
                                if ( !empty( $result ) )
8204
                                    $pick_values[] = $result[ 0 ]->id;
8205
                            }
8206
                            // @todo This could and should be abstracted better and simplified
8207
                            elseif ( 'pick' == $type ) {
8208
                                $related_pod = false;
8209
8210
                                if ( 'pod' == $pick_object )
8211
                                    $related_pod = $this->load_pod( array( 'name' => $pick_val, 'table_info' => true ), false );
8212
8213
                                if ( empty( $related_pod ) ) {
8214
                                    $related_pod = array(
8215
                                        'id' => 0,
8216
                                        'type' => $pick_object
8217
                                    );
8218
                                }
8219
8220
                                if ( in_array( 'taxonomy', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8221
                                    $where = "`t`.`name` = '" . pods_sanitize( $pick_value ) . "'";
8222
8223 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8224
                                        $where = "`tt`.`term_id` = " . pods_absint( $pick_value );
8225
8226
                                    $result = pods_query( "SELECT `t`.`term_id` AS `id` FROM `{$wpdb->term_taxonomy}` AS `tt` LEFT JOIN `{$wpdb->terms}` AS `t` ON `t`.`term_id` = `tt`.`term_id` WHERE `taxonomy` = '{$pick_val}' AND {$where} ORDER BY `t`.`term_id` LIMIT 1", $this );
8227
8228
                                    if ( !empty( $result ) )
8229
                                        $pick_values[] = $result[ 0 ]->id;
8230
                                }
8231
                                elseif ( in_array( 'post_type', array( $pick_object, $related_pod[ 'type' ] ) ) || in_array( 'media', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8232
                                    $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'";
8233
8234 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8235
                                        $where = "`ID` = " . pods_absint( $pick_value );
8236
8237
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = '{$pick_val}' AND {$where} ORDER BY `ID` LIMIT 1", $this );
8238
8239
                                    if ( !empty( $result ) )
8240
                                        $pick_values[] = $result[ 0 ]->id;
8241
                                }
8242
                                elseif ( in_array( 'user', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8243
                                    $where = "`user_login` = '" . pods_sanitize( $pick_value ) . "'";
8244
8245 View Code Duplication
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8246
                                        $where = "`ID` = " . pods_absint( $pick_value );
8247
8248
                                    $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->users}` WHERE {$where} ORDER BY `ID` LIMIT 1", $this );
8249
8250
                                    if ( !empty( $result ) )
8251
                                        $pick_values[] = $result[ 0 ]->id;
8252
                                }
8253
                                elseif ( in_array( 'comment', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8254
                                    $where = "`comment_ID` = " . pods_absint( $pick_value );
8255
8256
                                    $result = pods_query( "SELECT `comment_ID` AS `id` FROM `{$wpdb->comments}` WHERE {$where} ORDER BY `ID` LIMIT 1", $this );
8257
8258
                                    if ( !empty( $result ) )
8259
                                        $pick_values[] = $result[ 0 ]->id;
8260
                                }
8261
                                elseif ( in_array( $pick_object, $simple_tableless_objects ) )
8262
                                    $pick_values[] = $pick_value;
8263
                                elseif ( !empty( $related_pod[ 'id' ] ) ) {
8264
                                    $where = "`" . $related_pod[ 'field_index' ] . "` = '" . pods_sanitize( $pick_value ) . "'";
8265
8266
                                    if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8267
                                        $where = "`" . $related_pod[ 'field_id' ] . "` = " . pods_absint( $pick_value );
8268
8269
                                    $result = pods_query( "SELECT `" . $related_pod[ 'field_id' ] . "` AS `id` FROM `" . $related_pod[ 'table' ] . "` WHERE {$where} ORDER BY `" . $related_pod[ 'field_id' ] . "` LIMIT 1", $this );
8270
8271
                                    if ( !empty( $result ) )
8272
                                        $pick_values[] = $result[ 0 ]->id;
8273
                                }
8274
                            }
8275
                        }
8276
8277
                        $field_value = implode( ',', $pick_values );
8278
                    }
8279
8280
                    $data[ $field_name ] = $field_value;
8281
                }
8282
            }
8283
8284
            if ( !empty( $data ) ) {
8285
                $params = array(
8286
                    'pod' => $this->pod,
8287
                    'data' => $data
8288
                );
8289
8290
                $ids[] = $this->save_pod_item( $params );
8291
            }
8292
        }
8293
8294
        return $ids;
8295
    }
8296
8297
    /**
8298
     * Export data from a Pod
8299
     *
8300
     * @param string|object $pod The pod name or Pods object
8301
     * @param array $params An associative array of parameters
8302
     *
8303
     * @return array Data arrays of all exported pod items
8304
     * @since 1.7.1
8305
     */
8306
    public function export ( $pod = null, $params = null ) {
8307
8308
        if ( empty( $pod ) ) {
8309
            $pod = $this->pod;
8310
        }
8311
8312
        $find = array(
8313
            'limit' => -1,
8314
            'search' => false,
8315
            'pagination' => false
8316
        );
8317
8318
        if ( !empty( $params ) && isset( $params[ 'params' ] ) ) {
8319
            $find = array_merge( $find, (array) $params[ 'params' ] );
8320
8321
            unset( $params[ 'params' ] );
8322
8323
            $pod = pods( $pod, $find );
8324
        }
8325
        elseif ( !is_object( $pod ) ) {
8326
            $pod = pods( $pod, $find );
8327
        }
8328
8329
        $data = array();
8330
8331
        while ( $pod->fetch() ) {
8332
            $data[ $pod->id() ] = $this->export_pod_item( $params, $pod );
8333
        }
8334
8335
        $data = $this->do_hook( 'export', $data, $pod->pod, $pod );
8336
8337
        return $data;
8338
    }
8339
8340
    /**
8341
     * Convert CSV to a PHP array
8342
     *
8343
     * @param string $data The CSV input
8344
     *
8345
     * @return array
8346
     * @since 1.7.1
8347
     *
8348
     * @deprecated 2.3.5
8349
     */
8350
    public function csv_to_php ( $data, $delimiter = ',' ) {
8351
        pods_deprecated( "PodsAPI->csv_to_php", '2.3.5' );
8352
8353
        $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...
8354
8355
        return $data[ 'items' ];
8356
    }
8357
8358
    /**
8359
     * Clear Pod-related cache
8360
     *
8361
     * @param array $pod
8362
     *
8363
     * @return void
8364
     *
8365
     * @since 2.0
8366
     */
8367
    public function cache_flush_pods ( $pod = null ) {
8368
        /**
8369
         * @var $wpdb wpdb
8370
         */
8371
        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...
8372
8373
        pods_transient_clear( 'pods' );
8374
        pods_transient_clear( 'pods_components' );
8375
8376
        if ( null !== $pod && is_array( $pod ) ) {
8377
            pods_transient_clear( 'pods_pod_' . $pod[ 'name' ] );
8378
            pods_cache_clear( $pod[ 'name' ], 'pods-class' );
8379
8380
            foreach ( $pod[ 'fields' ] as $field ) {
8381
                pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
8382
            }
8383
8384
            if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) )
8385
                pods_transient_clear( 'pods_wp_cpt_ct' );
8386
        }
8387
        else
8388
            pods_transient_clear( 'pods_wp_cpt_ct' );
8389
8390
        // Delete transients in the database
8391
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" );
8392
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" );
8393
8394
        // Delete Pods Options Cache in the database
8395
        $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_pods_option_%'" );
8396
8397
        pods_cache_clear( true );
8398
8399
        pods_transient_set( 'pods_flush_rewrites', 1 );
8400
8401
        do_action( 'pods_cache_flushed' );
8402
    }
8403
8404
    /**
8405
     * Process a Pod-based form
8406
     *
8407
     * @param mixed $params
8408
     * @param object $obj Pod object
8409
     * @param array $fields Fields being submitted in form ( key => settings )
8410
     * @param string $thank_you URL to send to upon success
8411
     *
8412
     * @return mixed
8413
     *
8414
     * @since 2.0
8415
     */
8416
    public function process_form ( $params, $obj = null, $fields = null, $thank_you = null ) {
8417
        $this->display_errors = false;
8418
8419
        $form = null;
8420
8421
        $nonce = pods_var( '_pods_nonce', $params );
8422
        $pod = pods_var( '_pods_pod', $params );
8423
        $id = pods_var( '_pods_id', $params );
8424
        $uri = pods_var( '_pods_uri', $params );
8425
        $form = pods_var( '_pods_form', $params );
8426
        $location = pods_var( '_pods_location', $params );
8427
8428
        if ( is_object( $obj ) ) {
8429
            $pod = $obj->pod;
8430
            $id = $obj->id();
8431
        }
8432
8433
        if ( ! empty( $fields ) ) {
8434
            $fields = array_keys( $fields );
8435
            $form = implode( ',', $fields );
8436
        }
8437
        else
8438
            $fields = explode( ',', $form );
8439
8440
        if ( empty( $nonce ) || empty( $pod ) || empty( $uri ) || empty( $fields ) )
8441
            return pods_error( __( 'Invalid submission', 'pods' ), $this );
8442
8443
        $uid = @session_id();
8444
8445
        if ( is_user_logged_in() )
8446
            $uid = 'user_' . get_current_user_id();
8447
8448
		$field_hash = wp_create_nonce( 'pods_fields_' . $form );
8449
8450
        $action = 'pods_form_' . $pod . '_' . $uid . '_' . $id . '_' . $uri . '_' . $field_hash;
8451
8452
        if ( empty( $uid ) )
8453
            return pods_error( __( 'Access denied for your session, please refresh and try again.', 'pods' ), $this );
8454
8455
        if ( false === wp_verify_nonce( $nonce, $action ) )
8456
            return pods_error( __( 'Access denied, please refresh and try again.', 'pods' ), $this );
8457
8458
        $data = array();
8459
8460
        foreach ( $fields as $field ) {
8461
            $data[ $field ] = pods_var_raw( 'pods_field_' . $field, $params, '' );
8462
        }
8463
8464
        $params = array(
8465
            'pod' => $pod,
8466
            'id' => $id,
8467
            'data' => $data,
8468
            'from' => 'process_form',
8469
			'location' => $location
8470
        );
8471
8472
        $id = $this->save_pod_item( $params );
8473
8474
	    /**
8475
	     * Fires after the form has been processed and save_pod_item has run.
8476
	     *
8477
	     * @param int       $id     Item ID.
8478
	     * @param array     $params save_pod_item parameters.
8479
	     * @param null|Pods $obj    Pod object (if set).
8480
	     */
8481
        do_action( 'pods_api_processed_form', $id, $params, $obj );
8482
8483
		// Always return $id for AJAX requests.
8484
		if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
8485
			if ( 0 < $id && ! empty( $thank_you ) ) {
8486
				$thank_you = str_replace( 'X_ID_X', $id, $thank_you );
8487
8488
				pods_redirect( $thank_you );
8489
			}
8490
		}
8491
8492
        return $id;
8493
    }
8494
8495
    /**
8496
     * Handle filters / actions for the class
8497
     *
8498
     * @since 2.0
8499
     */
8500 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...
8501
        $args = func_get_args();
8502
        if ( empty( $args ) )
8503
            return false;
8504
        $name = array_shift( $args );
8505
        return pods_do_hook( "api", $name, $args, $this );
8506
    }
8507
8508
    /**
8509
     * Handle variables that have been deprecated
8510
     *
8511
     * @since 2.0
8512
     */
8513
    public function __get ( $name ) {
8514
        $name = (string) $name;
8515
8516 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8517
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8518
            $this->deprecated = new PodsAPI_Deprecated( $this );
8519
        }
8520
8521
        $var = null;
8522
8523
        if ( isset( $this->deprecated->{$name} ) ) {
8524
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8525
8526
            $var = $this->deprecated->{$name};
8527
        }
8528
        else
8529
            pods_deprecated( "PodsAPI->{$name}", '2.0' );
8530
8531
        return $var;
8532
    }
8533
8534
    /**
8535
     * Handle methods that have been deprecated
8536
     *
8537
     * @since 2.0
8538
     */
8539
    public function __call ( $name, $args ) {
8540
        $name = (string) $name;
8541
8542 View Code Duplication
        if ( !isset( $this->deprecated ) ) {
8543
            require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8544
            $this->deprecated = new PodsAPI_Deprecated( $this );
8545
        }
8546
8547
        if ( method_exists( $this->deprecated, $name ) )
8548
            return call_user_func_array( array( $this->deprecated, $name ), $args );
8549
        else
8550
            pods_deprecated( "PodsAPI::{$name}", '2.0' );
8551
    }
8552
8553
	/**
8554
	 * Filter an array of arrays without causing PHP notices/warnings.
8555
	 *
8556
	 * @param array $values
8557
	 *
8558
	 * @return array
8559
	 *
8560
	 * @since 2.6.10
8561
	 */
8562
	private function array_filter_walker( $values = array() ) {
8563
8564
		$values = (array) $values;
8565
8566
		foreach ( $values as $k => $v ){
8567
			if ( is_object( $v ) ) {
8568
				// Skip objects
8569
				continue;
8570
			} elseif ( is_array( $v ) ){
8571
				if ( empty( $v ) ) {
8572
					// Filter values with empty arrays
8573
					unset( $values[ $k ] );
8574
				}
8575
			} else {
8576
				if ( ! $v ) {
8577
					// Filter empty values
8578
					unset( $values[ $k ] );
8579
				}
8580
			}
8581
		}
8582
8583
		return $values;
8584
8585
	}
8586
8587
}
8588