Completed
Pull Request — 2.x (#3260)
by Phil
09:43 queued 03:11
created

PodsForm::delete()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 10
Ratio 100 %
Metric Value
dl 10
loc 10
rs 9.4286
cc 3
eloc 6
nc 2
nop 5
1
<?php
2
/**
3
 * @package Pods
4
 */
5
class PodsForm {
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
6
7
    /**
8
     * @var PodsForm
9
     */
10
    protected static $instance = null;
11
12
    /**
13
     * @var string
14
     */
15
    static $field = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $field.

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
     * @var string
19
     */
20
    static $field_group = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $field_group.

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...
21
22
    /**
23
     * @var string
24
     */
25
    static $field_type = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $field_type.

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...
26
27
    /**
28
     * @var array
29
     */
30
    static $field_types = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $field_types.

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...
31
32
    /**
33
     * @var array
34
     */
35
    static $loaded = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $loaded.

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...
36
37
    /**
38
     * @var int
39
     */
40
    static $form_counter = 0;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $form_counter.

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...
41
42
    /**
43
     * Singleton handling for a basic pods_form() request
44
     *
45
     * @return \PodsForm
46
     *
47
     * @since 2.3.5
48
     */
49
    public static function init () {
50
        if ( !is_object( self::$instance ) )
51
            self::$instance = new PodsForm();
52
53
        return self::$instance;
54
    }
55
56
    /**
57
     * Master handler for all field / form methods
58
     *
59
     * @return \PodsForm
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...
60
     *
61
     * @license http://www.gnu.org/licenses/gpl-2.0.html
62
     * @since 2.0
63
     */
64
    private function __construct() {
65
        add_action( 'admin_init', array( $this, 'admin_init' ), 14 );
66
    }
67
68
    /**
69
     * Prevent clones
70
     *
71
     * @since 2.3
72
     */
73
    private function __clone() {
74
        // Hulk smash
75
    }
76
77
    /**
78
     * Output a field's label
79
     *
80
     * @since 2.0
81
     */
82
83
    /**
84
     * Output a field's label
85
     *
86
     * @param string $name Field name
87
     * @param string $label Label text
88
     * @param string $help Help text
89
     * @param array $options Field options
90
     *
91
     * @return string Label HTML
92
     *
93
     * @since 2.0
94
     */
95
    public static function label( $name, $label, $help = '', $options = null ) {
96
        if ( is_array( $label ) || is_object( $label ) ) {
97
            $options = $label;
98
            $label = $options[ 'label' ];
99
100
            if ( empty( $label ) )
101
                $label = ucwords( str_replace( '_', ' ', $name ) );
102
103
            $help = $options[ 'help' ];
104
        }
105
        else
106
            $options = self::options( null, $options );
107
108
        $label = apply_filters( 'pods_form_ui_label_text', $label, $name, $help, $options );
109
        $help = apply_filters( 'pods_form_ui_label_help', $help, $name, $label, $options );
110
111
        ob_start();
112
113
        $name_clean = self::clean( $name );
114
        $name_more_clean = self::clean( $name, true );
115
116
        $type = 'label';
117
        $attributes = array();
118
        $attributes[ 'class' ] = 'pods-form-ui-' . $type . ' pods-form-ui-' . $type . '-' . $name_more_clean;
119
        $attributes[ 'for' ] = ( false === strpos( $name_clean, 'pods-form-ui-' ) ? 'pods-form-ui-' : '' ) . $name_clean;
120
        $attributes = self::merge_attributes( $attributes, $name, $type, $options, false );
121
122
        pods_view( PODS_DIR . 'ui/fields/_label.php', compact( array_keys( get_defined_vars() ) ) );
123
124
        $output = ob_get_clean();
125
126
        return apply_filters( 'pods_form_ui_' . $type, $output, $name, $label, $help, $attributes, $options );
127
    }
128
129
    /**
130
     * Output a Field Comment Paragraph
131
     *
132
     * @param string $name Field name
133
     * @param string $message Field comments
134
     * @param array $options Field options
135
     *
136
     * @return string Comment HTML
137
     *
138
     * @since 2.0
139
     */
140
    public static function comment( $name, $message = null, $options = null ) {
141
        $options = self::options( null, $options );
142
143
        $name_more_clean = self::clean( $name, true );
144
145
        if ( isset( $options[ 'description' ] ) && !empty( $options[ 'description' ] ) )
146
            $message = $options[ 'description' ];
147
        elseif ( empty( $message ) )
148
            return '';
149
150
        $message = apply_filters( 'pods_form_ui_comment_text', $message, $name, $options );
151
152
        ob_start();
153
154
        $type = 'comment';
155
        $attributes = array();
156
        $attributes[ 'class' ] = 'pods-form-ui-' . $type . ' pods-form-ui-' . $type . '-' . $name_more_clean;
157
        $attributes = self::merge_attributes( $attributes, $name, $type, $options, false );
158
159
        pods_view( PODS_DIR . 'ui/fields/_comment.php', compact( array_keys( get_defined_vars() ) ) );
160
161
        $output = ob_get_clean();
162
163
        return apply_filters( 'pods_form_ui_' . $type, $output, $name, $message, $attributes, $options );
164
    }
165
166
    /**
167
     * Output a field
168
     *
169
     * @param string $name Field name
170
     * @param mixed $value Field value
171
     * @param string $type Field type
172
     * @param array $options Field options
173
     * @param array $pod Pod data
174
     * @param int $id Item ID
175
     *
176
     * @return string Field HTML
177
     *
178
     * @since 2.0
179
     */
180
    public static function field( $name, $value, $type = 'text', $options = null, $pod = null, $id = null ) {
181
		// Take a field array
182
		if ( is_array( $name ) || is_object( $name ) ) {
183
			$options = $name;
184
185
			if ( is_object( $type ) ) {
186
				$pod = $type;
187
				$id = $options;
188
			}
189
190
			$name = pods_v( 'name', $options );
191
			$type = pods_v( 'type', $options );
192
		}
193
194
        $options = self::options( $type, $options );
195
196
        if ( null === $value || ( '' === $value && 'boolean' == $type ) || ( !empty( $pod ) && empty( $id ) ) )
197
            $value = self::default_value( $value, $type, $name, $options, $pod, $id );
198
199
        if ( false === self::permission( $type, $name, $options, null, $pod, $id ) )
200
            return false;
201
202
        $value = apply_filters( 'pods_form_ui_field_' . $type . '_value', $value, $name, $options, $pod, $id );
203
        $form_field_type = self::$field_type;
204
205
        ob_start();
206
207
        $helper = false;
208
209
        if ( 0 < strlen( pods_v( 'input_helper', $options ) ) )
210
            $helper = pods_api()->load_helper( array( 'name' => $options[ 'input_helper' ] ) );
211
212
        if ( ( !isset( $options[ 'data' ] ) || empty( $options[ 'data' ] ) ) && is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'data' ) )
213
            $data = $options[ 'data' ] = self::$loaded[ $type ]->data( $name, $value, $options, $pod, $id, true );
214
215
        if ( true === apply_filters( 'pods_form_ui_field_' . $type . '_override', false, $name, $value, $options, $pod, $id ) )
216
            do_action( 'pods_form_ui_field_' . $type, $name, $value, $options, $pod, $id );
217
        elseif ( !empty( $helper ) && 0 < strlen( pods_v( 'code', $helper ) ) && false === strpos( $helper[ 'code' ], '$this->' ) && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
218
            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...
219
        elseif ( method_exists( get_class(), 'field_' . $type ) )
220
            echo call_user_func( array( get_class(), 'field_' . $type ), $name, $value, $options );
221
        elseif ( is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'input' ) )
222
            self::$loaded[ $type ]->input( $name, $value, $options, $pod, $id );
223
        else
224
            do_action( 'pods_form_ui_field_' . $type, $name, $value, $options, $pod, $id );
225
226
        $output = ob_get_clean();
227
228
        return apply_filters( 'pods_form_ui_field_' . $type, $output, $name, $value, $options, $pod, $id );
229
    }
230
231
    /**
232
     * Output a flexible relationship button
233
     *
234
     * @todo  : support other content types
235
     * @todo  : replace thickbox
236
     *
237
     * @param array $field Field options array
238
     *
239
     * @param int   $item_id
240
     *
241
     * @return string Button HTML
242
     *
243
     * @since 2.7
244
     */
245
    public static function flex_relationship( $field, $item_id ) {
246
247
        $output = '';
248
249
        // Early exit if this isn't a flexible relationship enabled field
250
        if ( 'pick' != $field[ 'type' ] || !$field[ 'options' ][ 'pick_flexible' ] ) {
251
            return $output;
252
        }
253
254
        // @todo: early exit if we're already in a modal
255
256
        // Set the file name and args based on the content type of the relationship
257
        switch ( $field[ 'pick_object' ] ) {
258
            case 'post_type':
259
                $file_name = 'post-new.php';
260
                $query_args = array(
261
                    'post_type' => $field[ 'pick_val' ],
262
                );
263
                break;
264
265
            case 'user':
266
                $file_name = 'user-new.php';
267
                $query_args = array();
268
                break;
269
270
            // Something unsupported
271
            default:
272
                return $output;
273
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
274
        }
275
276
        // Add args we always need
277
        $query_args = array_merge(
278
            $query_args,
279
            array(
280
                'pods_modal' => '1', // @todo: No hard-coded constants, create a constant for the purpose
281
                'TB_iframe'  => 'true',
282
                'width'      => '753',
283
                'height'     => '798',
284
            )
285
        );
286
287
        // Assemble the URL
288
        $url = add_query_arg(
289
            $query_args,
290
            admin_url( $file_name )
291
        );
292
293
        ob_start();
294
        ?>
295
        <a href="<?php echo $url; ?>"
296
            id="pods-related-edit-<?php echo $field[ 'name' ]; ?>"
297
            class="button pods-related-edit"
298
            data-pod-id="<?php echo $field[ 'pod_id' ]; ?>"
299
            data-field-id="<?php echo $field[ 'id' ]; ?>"
300
            data-item-id="<?php echo $item_id; ?>"> Add New</a>
301
        <?php
302
303
        $output = ob_get_clean();
304
305
        // @todo: add a filter
306
        return $output;
307
    }
308
309
    /**
310
     * Output field type 'db'
311
     *
312
     * Used for field names and other places where only [a-z0-9_] is accepted
313
     *
314
     * @since 2.0
315
     */
316 View Code Duplication
    protected static function field_db( $name, $value = null, $options = 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...
317
        $form_field_type = self::$field_type;
318
319
        ob_start();
320
321
        pods_view( PODS_DIR . 'ui/fields/_db.php', compact( array_keys( get_defined_vars() ) ) );
322
323
        $output = ob_get_clean();
324
325
        return apply_filters( 'pods_form_ui_field_db', $output, $name, $value, $options );
326
    }
327
328
    /**
329
     * Output a hidden field
330
     */
331 View Code Duplication
    protected static function field_hidden( $name, $value = null, $options = 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...
332
        $form_field_type = self::$field_type;
333
334
        ob_start();
335
336
        pods_view( PODS_DIR . 'ui/fields/_hidden.php', compact( array_keys( get_defined_vars() ) ) );
337
338
        $output = ob_get_clean();
339
340
        return apply_filters( 'pods_form_ui_field_hidden', $output, $name, $value, $options );
341
    }
342
343
	/**
344
	 * Returns a submit button, with provided text and appropriate class, copied from WP Core for use on the frontend
345
	 *
346
	 * @see get_submit_button
347
	 *
348
	 * @param string $text The text of the button (defaults to 'Save Changes')
349
	 * @param string $type The type of button. One of: primary, secondary, delete
350
	 * @param string $name The HTML name of the submit button. Defaults to "submit". If no id attribute
351
	 *               is given in $other_attributes below, $name will be used as the button's id.
352
	 * @param bool $wrap True if the output button should be wrapped in a paragraph tag,
353
	 * 			   false otherwise. Defaults to true
354
	 * @param array|string $other_attributes Other attributes that should be output with the button,
355
	 *                     mapping attributes to their values, such as array( 'tabindex' => '1' ).
356
	 *                     These attributes will be output as attribute="value", such as tabindex="1".
357
	 *                     Defaults to no other attributes. Other attributes can also be provided as a
358
	 *                     string such as 'tabindex="1"', though the array format is typically cleaner.
359
	 *
360
	 * @since 3.0
361
	 */
362
	public static function submit_button( $text = null, $type = 'primary large', $name = 'submit', $wrap = true, $other_attributes = null ) {
363
364
		if ( function_exists( 'get_submit_button' ) ) {
365
			return get_submit_button( $text, $type, $name, $wrap, $other_attributes );
366
		}
367
368
		if ( !is_array( $type ) ) {
369
			$type = explode( ' ', $type );
370
		}
371
372
		$button_shorthand = array(
373
			'primary',
374
			'small',
375
			'large'
376
		);
377
378
		$classes = array(
379
			'button'
380
		);
381
382
		foreach ( $type as $t ) {
383
			if ( 'secondary' === $t || 'button-secondary' === $t ) {
384
				continue;
385
			}
386
387
			$classes[] = in_array( $t, $button_shorthand ) ? 'button-' . $t : $t;
388
		}
389
390
		$class = implode( ' ', array_unique( $classes ) );
391
392
		if ( 'delete' === $type ) {
393
			$class = 'button-secondary delete';
394
		}
395
396
		$text = $text ? $text : __( 'Save Changes' );
397
398
		// Default the id attribute to $name unless an id was specifically provided in $other_attributes
399
		$id = $name;
400
401
		if ( is_array( $other_attributes ) && isset( $other_attributes[ 'id' ] ) ) {
402
			$id = $other_attributes[ 'id' ];
403
			unset( $other_attributes[ 'id' ] );
404
		}
405
406
		$attributes = '';
407
408
		if ( is_array( $other_attributes ) ) {
409
			foreach ( $other_attributes as $attribute => $value ) {
410
				$attributes .= $attribute . '="' . esc_attr( $value ) . '" '; // Trailing space is important
411
			}
412
		}
413
		elseif ( !empty( $other_attributes ) ) { // Attributes provided as a string
414
			$attributes = $other_attributes;
415
		}
416
417
		$button = '<input type="submit" name="' . esc_attr( $name ) . '" id="' . esc_attr( $id ) . '" class="' . esc_attr( $class );
418
		$button .= '" value="' . esc_attr( $text ) . '" ' . $attributes . ' />';
419
420
		if ( $wrap ) {
421
			$button = '<p class="submit">' . $button . '</p>';
422
		}
423
424
		return $button;
425
426
	}
427
428
    /**
429
     * Output a row (label, field, and comment)
430
     *
431
     * @param string $name Field name
432
     * @param mixed $value Field value
433
     * @param string $type Field type
434
     * @param array $options Field options
435
     * @param array $pod Pod data
436
     * @param int $id Item ID
437
     *
438
     * @return string Row HTML
439
     *
440
     * @since 2.0
441
     */
442
    public static function row( $name, $value, $type = 'text', $options = null, $pod = null, $id = null ) {
443
        $options = self::options( null, $options );
444
445
        ob_start();
446
447
        pods_view( PODS_DIR . 'ui/fields/_row.php', compact( array_keys( get_defined_vars() ) ) );
448
449
        $output = ob_get_clean();
450
451
        return apply_filters( 'pods_form_ui_field_row', $output, $name, $value, $options, $pod, $id );
452
    }
453
454
    /**
455
     * Output a field's attributes
456
     *
457
     * @since 2.0
458
     */
459
    public static function attributes( $attributes, $name = null, $type = null, $options = null ) {
460
        $attributes = (array) apply_filters( 'pods_form_ui_field_' . $type . '_attributes', $attributes, $name, $options );
461
462
        foreach ( $attributes as $attribute => $value ) {
463
            if ( null === $value )
464
                continue;
465
466
            echo ' ' . esc_attr( (string) $attribute ) . '="' . esc_attr( (string) $value ) . '"';
467
        }
468
    }
469
470
    /**
471
     * Output a field's data (for use with jQuery)
472
     *
473
     * @since 2.0
474
     */
475
    public static function data( $data, $name = null, $type = null, $options = null ) {
476
        $data = (array) apply_filters( 'pods_form_ui_field_' . $type . '_data', $data, $name, $options );
477
478
        foreach ( $data as $key => $value ) {
479
            if ( null === $value )
480
                continue;
481
482
            $key = sanitize_title( $key );
483
484
            if ( is_array( $value ) )
485
                $value = implode( ',', $value );
486
487
            echo ' data-' . esc_attr( (string) $key ) . '="' . esc_attr( (string) $value ) . '"';
488
        }
489
    }
490
491
    /**
492
     * Merge attributes and handle classes
493
     *
494
     * @since 2.0
495
     */
496
    public static function merge_attributes( $attributes, $name = null, $type = null, $options = null, $classes = '' ) {
497
        $options = (array) $options;
498
499
        if ( !in_array( $type, array( 'label', 'comment' ) ) ) {
500
            $name_clean = self::clean( $name );
501
            $name_more_clean = self::clean( $name, true );
502
            $_attributes = array();
503
            $_attributes[ 'name' ] = $name;
504
            $_attributes[ 'data-name-clean' ] = $name_more_clean;
505
506
            if ( 0 < strlen( pods_v( 'label', $options, '' ) ) )
507
                $_attributes[ 'data-label' ] = strip_tags( pods_v( 'label', $options ) );
508
509
            $_attributes[ 'id' ] = 'pods-form-ui-' . $name_clean;
510
            $_attributes[ 'class' ] = 'pods-form-ui-field-type-' . $type . ' pods-form-ui-field-name-' . $name_more_clean;
511
512
            if ( isset( $options[ 'dependency' ] ) && false !== $options[ 'dependency' ] )
513
                $_attributes[ 'class' ] .= ' pods-dependent-toggle';
514
515
            $attributes = array_merge( $_attributes, (array) $attributes );
516
517 View Code Duplication
            if ( isset( $options[ 'attributes' ] ) && is_array( $options[ 'attributes' ] ) && !empty( $options[ 'attributes' ] ) )
518
                $attributes = array_merge( $attributes, $options[ 'attributes' ] );
519
        }
520
        elseif ( isset( $options[ $type . '_attributes' ] ) && is_array( $options[ $type . '_attributes' ] ) && !empty( $options[ $type . '_attributes' ] ) )
521
            $attributes = array_merge( $attributes, $options[ $type . '_attributes' ] );
522
523
        if ( isset( $options[ 'class' ] ) && !empty( $options[ 'class' ] ) ) {
524
            if ( is_array( $options[ 'class' ] ) )
525
                $options[ 'class' ] = implode( ' ', $options[ 'class' ] );
526
527
            $options[ 'class' ] = (string) $options[ 'class' ];
528 View Code Duplication
            if ( isset( $attributes[ 'class' ] ) )
529
                $attributes[ 'class' ] = $attributes[ 'class' ] . ' ' . $options[ 'class' ];
530
            else
531
                $attributes[ 'class' ] = $options[ 'class' ];
532
533
            $attributes[ 'class' ] = trim( $attributes[ 'class' ] );
534
        }
535
536
        if ( !empty( $classes ) ) {
537 View Code Duplication
            if ( isset( $attributes[ 'class' ] ) )
538
                $attributes[ 'class' ] = $attributes[ 'class' ] . ' ' . $classes;
539
            else
540
                $attributes[ 'class' ] = $classes;
541
        }
542
543
        if ( isset( $options[ 'placeholder' ] ) && !empty( $options[ 'placeholder' ] ) ) {
544
            if ( is_array( $options[ 'placeholder' ] ) )
545
                $options[ 'placeholder' ] = implode( ' ', $options[ 'placeholder' ] );
546
547
            $options[ 'placeholder' ] = (string) $options[ 'placeholder' ];
548
			$attributes[ 'placeholder' ] = trim( $options[ 'placeholder' ] );
549
        }
550
551
        if ( 1 == pods_v( 'required', $options, 0 ) )
552
            $attributes[ 'class' ] .= ' pods-validate pods-validate-required';
553
554
        $max_length = (int) pods_var( 'maxlength', $options, pods_v( $type . '_max_length', $options, 0 ), null, true );
555
556
        if ( 0 < $max_length )
557
            $attributes[ 'maxlength' ] = $max_length;
558
559
        $attributes = (array) apply_filters( 'pods_form_ui_field_' . $type . '_merge_attributes', $attributes, $name, $options );
560
        return $attributes;
561
    }
562
563
    /**
564
     * Setup options for a field and store them for later use
565
     *
566
     * @param $type
567
     * @param $options
568
     *
569
     * @return array
570
     *
571
     * @static
572
     *
573
     * @since 2.0
574
     */
575
    public static function options( $type, $options ) {
576
        $options = (array) $options;
577
578
        if ( !is_object( $options ) && isset( $options[ 'options' ] ) ) {
579
            $options_temp = $options[ 'options' ];
580
581
            unset( $options[ 'options' ] );
582
583
            $options = array_merge( $options_temp, $options );
584
585
            $override = array(
586
                'class'
587
            );
588
589
            foreach ( $override as $check ) {
590
                if ( isset( $options_temp[ $check ] ) )
591
                    $options[ $check ] = $options_temp[ $check ];
592
            }
593
        }
594
595
        $defaults = self::options_setup( $type, $options );
596
597
        $core_defaults = array(
598
            'id' => 0,
599
            'label' => '',
600
            'description' => '',
601
            'help' => '',
602
            'default' => null,
603
            'attributes' => array(),
604
            'class' => '',
605
            'grouped' => 0,
606
        );
607
608
        $defaults = array_merge( $core_defaults, $defaults );
609
610
        foreach ( $defaults as $option => $settings ) {
611
            $default = $settings;
612
613
            if ( is_array( $settings ) && isset( $settings[ 'default' ] ) )
614
                $default = $settings[ 'default' ];
615
616
            if ( !isset( $options[ $option ] ) )
617
                $options[ $option ] = $default;
618
        }
619
620
        return $options;
621
    }
622
623
    /**
624
     * Get options for a field type and setup defaults
625
     *
626
     * @static
627
     *
628
     * @param $type
629
     *
630
     * @return array|null
631
     *
632
     * @since 2.0
633
     */
634
    public static function options_setup( $type = null, $options = null ) {
635
        $core_defaults = array(
636
            'id' => 0,
637
            'name' => '',
638
            'label' => '',
639
            'description' => '',
640
            'help' => '',
641
            'default' => null,
642
            'attributes' => array(),
643
            'class' => '',
644
            'type' => 'text',
645
            'group' => 0,
646
            'grouped' => 0,
647
            'developer_mode' => false,
648
            'dependency' => false,
649
            'depends-on' => array(),
650
            'excludes-on' => array(),
651
            'options' => array()
652
        );
653
654
        if ( !empty( $options ) && is_array( $options ) )
655
            $core_defaults = array_merge( $core_defaults, $options );
656
657
        if ( null === $type )
658
            return $core_defaults;
659
        else
660
            self::field_loader( $type );
661
662
        $options = apply_filters( 'pods_field_' . $type . '_options', (array) self::$loaded[ $type ]->options(), $type );
663
664
        $first_field = current( $options );
665
666
        if ( !empty( $options ) && !isset( $first_field[ 'name' ] ) && !isset( $first_field[ 'label' ] ) ) {
667
            $all_options = array();
668
669
            foreach ( $options as $group => $group_options ) {
670
                $all_options = array_merge( $all_options, self::fields_setup( $group_options, $core_defaults ) );
671
            }
672
673
            $options = $all_options;
674
        }
675
        else
676
            $options = self::fields_setup( $options, $core_defaults );
677
678
        return $options;
679
    }
680
681
    /**
682
     * Get Admin options for a field type and setup defaults
683
     *
684
     * @static
685
     *
686
     * @param $type
687
     *
688
     * @return array|null
689
     *
690
     * @since 2.0
691
     */
692
    public static function ui_options( $type ) {
693
        $core_defaults = array(
694
            'id' => 0,
695
            'name' => '',
696
            'label' => '',
697
            'description' => '',
698
            'help' => '',
699
            'default' => null,
700
            'attributes' => array(),
701
            'class' => '',
702
            'type' => 'text',
703
            'group' => 0,
704
            'grouped' => 0,
705
            'developer_mode' => false,
706
            'dependency' => false,
707
            'depends-on' => array(),
708
            'excludes-on' => array(),
709
            'options' => array()
710
        );
711
712
        self::field_loader( $type );
713
714
        $options = apply_filters( 'pods_field_' . $type . '_ui_options', (array) self::$loaded[ $type ]->ui_options(), $type );
715
716
        $first_field = current( $options );
717
718
        if ( !empty( $options ) && !isset( $first_field[ 'name' ] ) && !isset( $first_field[ 'label' ] ) ) {
719
            foreach ( $options as $group => $group_options ) {
720
                $options[ $group ] = self::fields_setup( $group_options, $core_defaults );
721
            }
722
        }
723
        else
724
            $options = self::fields_setup( $options, $core_defaults );
725
726
        return $options;
727
    }
728
729
    /**
730
     * Get options for a field and setup defaults
731
     *
732
     *
733
     * @param null $fields
734
     * @param null $core_defaults
735
     * @param bool $single
736
     *
737
     * @return array|null
738
     *
739
     * @static
740
     * @since 2.0
741
     */
742
    public static function fields_setup( $fields = null, $core_defaults = null, $single = false ) {
743
        if ( empty( $core_defaults ) ) {
744
            $core_defaults = array(
745
                'id' => 0,
746
                'name' => '',
747
                'label' => '',
748
                'description' => '',
749
                'help' => '',
750
                'default' => null,
751
                'attributes' => array(),
752
                'class' => '',
753
                'type' => 'text',
754
                'group' => 0,
755
                'grouped' => 0,
756
                'developer_mode' => false,
757
                'dependency' => false,
758
                'depends-on' => array(),
759
                'excludes-on' => array(),
760
                'options' => array()
761
            );
762
        }
763
764
        if ( $single )
765
            $fields = array( $fields );
766
767
        foreach ( $fields as $f => $field ) {
0 ignored issues
show
Bug introduced by
The expression $fields of type array<integer,null,{"0":"null"}>|null 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...
768
            $fields[ $f ] = self::field_setup( $field, $core_defaults, pods_v( 'type', $field, 'text' ) );
769
770
            if ( !$single && strlen( $fields[ $f ][ 'name' ] ) < 1 )
771
                $fields[ $f ][ 'name' ] = $f;
772
        }
773
774
        if ( $single )
775
            $fields = $fields[ 0 ];
776
777
        return $fields;
778
    }
779
780
    /**
781
     * Get options for a field and setup defaults
782
     *
783
     * @static
784
     *
785
     * @param null $field
786
     * @param null $core_defaults
787
     * @param null $type
788
     *
789
     * @return array|null
790
     *
791
     * @since 2.0
792
     */
793
    public static function field_setup( $field = null, $core_defaults = null, $type = null ) {
794
        $options = array();
795
796
        if ( empty( $core_defaults ) ) {
797
            $core_defaults = array(
798
                'id' => 0,
799
                'name' => '',
800
                'label' => '',
801
                'description' => '',
802
                'help' => '',
803
                'default' => null,
804
                'attributes' => array(),
805
                'class' => '',
806
                'type' => 'text',
807
                'group' => 0,
808
                'grouped' => 0,
809
                'developer_mode' => false,
810
                'dependency' => false,
811
                'depends-on' => array(),
812
                'excludes-on' => array(),
813
                'options' => array()
814
            );
815
816
            if ( null !== $type ) {
817
                self::field_loader( $type );
818
819
                if ( method_exists( self::$loaded[ $type ], 'options' ) )
820
                    $options = apply_filters( 'pods_field_' . $type . '_options', (array) self::$loaded[ $type ]->options(), $type );
821
            }
822
        }
823
824
        if ( !is_array( $field ) )
825
            $field = array( 'default' => $field );
826
827
        if ( isset( $field[ 'group' ] ) && is_array( $field[ 'group' ] ) ) {
828
            foreach ( $field[ 'group' ] as $g => $group_option ) {
829
                $field[ 'group' ][ $g ] = array_merge( $core_defaults, $group_option );
830
831
                if ( strlen( $field[ 'group' ][ $g ][ 'name' ] ) < 1 )
832
                    $field[ 'group' ][ $g ][ 'name' ] = $g;
833
            }
834
        }
835
836
        $field = array_merge( $core_defaults, $field );
837
838
        foreach ( $options as $option => $settings ) {
839
            $v = null;
840
841
            if ( isset( $settings[ 'default' ] ) )
842
                $v = $settings[ 'default' ];
843
844
            if ( !isset( $field[ 'options' ][ $option ] ) )
845
                $field[ 'options' ][ $option ] = $v;
846
        }
847
848
        return $field;
849
    }
850
851
    /**
852
     * Setup dependency / exclusion classes
853
     *
854
     * @param array $options array( 'depends-on' => ..., 'excludes-on' => ...)
855
     * @param string $prefix
856
     *
857
     * @return string
858
     * @static
859
     * @since 2.0
860
     */
861
    public static function dependencies( $options, $prefix = '' ) {
862
        $options = (array) $options;
863
864
        $depends_on = $excludes_on = array();
865
        if ( isset( $options[ 'depends-on' ] ) )
866
            $depends_on = (array) $options[ 'depends-on' ];
867
868
        if ( isset( $options[ 'excludes-on' ] ) )
869
            $excludes_on = (array) $options[ 'excludes-on' ];
870
871
        $classes = array();
872
873 View Code Duplication
        if ( !empty( $depends_on ) ) {
874
            $classes[] = 'pods-depends-on';
875
876
            foreach ( $depends_on as $depends => $on ) {
877
                $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true );
878
879
                if ( !is_bool( $on ) ) {
880
                    $on = (array) $on;
881
882
                    foreach ( $on as $o ) {
883
                        $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true ) . '-' . self::clean( $o, true );
884
                    }
885
                }
886
            }
887
        }
888
889 View Code Duplication
        if ( !empty( $excludes_on ) ) {
890
            $classes[] = 'pods-excludes-on';
891
            foreach ( $excludes_on as $excludes => $on ) {
892
                $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true );
893
894
                $on = (array) $on;
895
896
                foreach ( $on as $o ) {
897
                    $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true ) . '-' . self::clean( $o, true );
898
                }
899
            }
900
        }
901
902
        $classes = implode( ' ', $classes );
903
904
        return $classes;
905
    }
906
907
    /**
908
     * Change the value of the field
909
     *
910
     * @param mixed $value
911
     * @param string $name
912
     * @param array $options
913
     * @param array $fields
0 ignored issues
show
Bug introduced by
There is no parameter named $fields. 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...
914
     * @param array $pod
915
     * @param int $id
916
     * @param array $traverse
917
     *
918
     * @since 2.3
919
     */
920
    public static function value( $type, $value = null, $name = null, $options = null, $pod = null, $id = null, $traverse = null ) {
921
        self::field_loader( $type );
922
923
        if ( in_array( $type, self::repeatable_field_types() ) && 1 == pods_v( $type . '_repeatable', $options, 0 ) && !is_array( $value ) ) {
924
            if ( 0 < strlen( $value ) ) {
925
                $simple = @json_decode( $value, true );
1 ignored issue
show
Unused Code introduced by
The call to json_decode() has too many arguments starting with true.

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...
926
927
                if ( is_array( $simple ) )
928
                    $value = $simple;
929
                else
930
                    $value = (array) $value;
931
            }
932
            else
933
                $value = array();
934
        }
935
936
        if ( method_exists( self::$loaded[ $type ], 'value' ) ) {
937
            if ( is_array( $value ) && in_array( $type, self::tableless_field_types() ) ) {
938 View Code Duplication
                foreach ( $value as &$display_value ) {
939
                    $display_value = call_user_func_array( array( self::$loaded[ $type ], 'value' ), array( $display_value, $name, $options, $pod, $id, $traverse ) );
940
                }
941
            }
942 View Code Duplication
            else
943
                $value = call_user_func_array( array( self::$loaded[ $type ], 'value' ), array( $value, $name, $options, $pod, $id, $traverse ) );
944
        }
945
946
        return $value;
947
    }
948
949
    /**
950
     * Change the way the value of the field is displayed with Pods::get
951
     *
952
     * @param mixed $value
953
     * @param string $name
954
     * @param array $options
955
     * @param array $fields
0 ignored issues
show
Bug introduced by
There is no parameter named $fields. 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...
956
     * @param array $pod
957
     * @param int $id
958
     * @param array $traverse
959
     *
960
     * @since 2.0
961
     */
962
    public static function display( $type, $value = null, $name = null, $options = null, $pod = null, $id = null, $traverse = null ) {
963
        self::field_loader( $type );
964
965
        $tableless_field_types = self::tableless_field_types();
966
967
        if ( method_exists( self::$loaded[ $type ], 'display' ) ) {
968
            if ( is_array( $value ) && !in_array( $type, $tableless_field_types ) ) {
969 View Code Duplication
                foreach ( $value as $k => $display_value ) {
970
                    $value[ $k ] = call_user_func_array( array( self::$loaded[ $type ], 'display' ), array( $display_value, $name, $options, $pod, $id, $traverse ) );
971
                }
972
            }
973 View Code Duplication
            else
974
                $value = call_user_func_array( array( self::$loaded[ $type ], 'display' ), array( $value, $name, $options, $pod, $id, $traverse ) );
975
        }
976
977
        $value = apply_filters( 'pods_form_display_' . $type, $value, $name, $options, $pod, $id, $traverse );
978
979
        return $value;
980
    }
981
982
    /**
983
     * Setup regex for JS / PHP
984
     *
985
     * @static
986
     *
987
     * @param $type
988
     * @param $options
989
     *
990
     * @return mixed|void
991
     * @since 2.0
992
     */
993 View Code Duplication
    public static function regex( $type, $options ) {
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...
994
        self::field_loader( $type );
995
996
        $regex = false;
997
998
        if ( method_exists( self::$loaded[ $type ], 'regex' ) )
999
            $regex = self::$loaded[ $type ]->regex( $options );
1000
1001
        $regex = apply_filters( 'pods_field_' . $type . '_regex', $regex, $options, $type );
1002
1003
        return $regex;
1004
    }
1005
1006
    /**
1007
     * Setup value preparation for sprintf
1008
     *
1009
     * @static
1010
     *
1011
     * @param $type
1012
     * @param $options
1013
     *
1014
     * @return mixed|void
1015
     * @since 2.0
1016
     */
1017 View Code Duplication
    public static function prepare( $type, $options ) {
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...
1018
        self::field_loader( $type );
1019
1020
        $prepare = '%s';
1021
1022
        if ( method_exists( self::$loaded[ $type ], 'prepare' ) )
1023
            $prepare = self::$loaded[ $type ]->prepare( $options );
1024
1025
        $prepare = apply_filters( 'pods_field_' . $type . '_prepare', $prepare, $options, $type );
1026
1027
        return $prepare;
1028
    }
1029
1030
    /**
1031
     * Validate a value before it's saved
1032
     *
1033
     * @param string $type
1034
     * @param mixed $value
1035
     * @param string $name
1036
     * @param array $options
1037
     * @param array $fields
1038
     * @param array $pod
1039
     * @param int $id
1040
     * @param array|object $params
1041
     *
1042
     * @static
1043
     *
1044
     * @since 2.0
1045
     */
1046
    public static function validate( $type, $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
1047
        self::field_loader( $type );
1048
1049
        $validate = true;
1050
1051
        if ( 1 == pods_v( 'pre_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'validate' ) )
1052
            $validate = self::$loaded[ $type ]->validate( $value, $name, $options, $fields, $pod, $id, $params );
1053
1054
        $validate = apply_filters( 'pods_field_' . $type . '_validate', $validate, $value, $name, $options, $fields, $pod, $id, $type, $params );
1055
1056
        return $validate;
1057
    }
1058
1059
    /**
1060
     * Change the value or perform actions after validation but before saving to the DB
1061
     *
1062
     * @param string $type
1063
     * @param mixed $value
1064
     * @param int $id
1065
     * @param string $name
1066
     * @param array $options
1067
     * @param array $fields
1068
     * @param array $pod
1069
     * @param object $params
1070
     *
1071
     * @static
1072
     *
1073
     * @since 2.0
1074
     */
1075 View Code Duplication
    public static function pre_save( $type, $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $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...
1076
        self::field_loader( $type );
1077
1078
        if ( 1 == pods_v( 'field_pre_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'pre_save' ) )
1079
            $value = self::$loaded[ $type ]->pre_save( $value, $id, $name, $options, $fields, $pod, $params );
1080
1081
        return $value;
1082
    }
1083
1084
    /**
1085
     * Save the value to the DB
1086
     *
1087
     * @param string $type
1088
     * @param mixed $value
1089
     * @param int $id
1090
     * @param string $name
1091
     * @param array $options
1092
     * @param array $fields
1093
     * @param array $pod
1094
     * @param object $params
1095
     *
1096
     * @static
1097
     *
1098
     * @since 2.3
1099
     */
1100 View Code Duplication
    public static function save( $type, $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $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...
1101
        self::field_loader( $type );
1102
1103
        $saved = null;
1104
1105
        if ( 1 == pods_v( 'field_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'save' ) )
1106
            $saved = self::$loaded[ $type ]->save( $value, $id, $name, $options, $fields, $pod, $params );
1107
1108
        return $saved;
1109
    }
1110
1111
    /**
1112
     * Delete the value from the DB
1113
     *
1114
     * @param string $type
1115
     * @param int $id
1116
     * @param string $name
1117
     * @param array $options
1118
     * @param array $pod
1119
     *
1120
     * @static
1121
     *
1122
     * @since 2.3
1123
     */
1124 View Code Duplication
    public static function delete( $type, $id = null, $name = null, $options = null, $pod = 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...
1125
        self::field_loader( $type );
1126
1127
        $deleted = null;
1128
1129
        if ( 1 == pods_v( 'field_delete', $options, 1 ) && method_exists( self::$loaded[ $type ], 'delete' ) )
1130
            $deleted = self::$loaded[ $type ]->delete( $id, $name, $options, $pod );
1131
1132
        return $deleted;
1133
    }
1134
1135
    /**
1136
     * Check if a user has permission to be editing a field
1137
     *
1138
     * @param $type
1139
     * @param null $name
1140
     * @param null $options
1141
     * @param null $fields
1142
     * @param null $pod
1143
     * @param null $id
1144
     * @param null $params
1145
     *
1146
     * @static
1147
     *
1148
     * @since 2.0
1149
     */
1150
    public static function permission( $type, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
1151
        $permission = pods_permission( $options );
1152
1153
        $permission = (boolean) apply_filters( 'pods_form_field_permission', $permission, $type, $name, $options, $fields, $pod, $id, $params );
1154
1155
        return $permission;
1156
    }
1157
1158
    /**
1159
     * Parse the default the value
1160
     *
1161
     * @since 2.0
1162
     */
1163
    public static function default_value( $value, $type = 'text', $name = null, $options = null, $pod = null, $id = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

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

Loading history...
1164
        $default_value = pods_v( 'default_value', $options );
1165
1166
		if ( '' === $default_value || null === $default_value ) {
1167
			$default_value = $value;
1168
		}
1169
1170
        $default = pods_v( 'default', $options, $default_value, true );
1171
1172
	    if ( is_string( $default ) ) {
1173
		    $default_value = str_replace( array( '{@', '}' ), '', trim( $default ) );
1174
	    }
1175
1176
        if ( $default != $default_value && 1 == (int) pods_v( 'default_evaluate_tags', $options, 1 ) )
1177
            $default = pods_evaluate_tags( $default );
1178
1179
        $default = pods_var_raw( pods_v( 'default_value_parameter', $options ), 'request', $default, null, true );
1180
1181
        if ( $default != $value )
1182
            $value = $default;
1183
1184
        if ( is_array( $value ) )
1185
            $value = pods_serial_comma( $value );
1186
1187
        return apply_filters( 'pods_form_field_default_value', $value, $default, $type, $options, $pod, $id );
1188
    }
1189
1190
    /**
1191
     * Clean a value for use in class / id
1192
     *
1193
     * @since 2.0
1194
     */
1195
    public static function clean( $input, $noarray = false, $db_field = false ) {
1196
        $input = str_replace( array( '--1', '__1' ), '00000', (string) $input );
1197
        if ( false !== $noarray )
1198
            $input = preg_replace( '/\[\d*\]/', '-', $input );
1199
        $output = str_replace( array( '[', ']' ), '-', strtolower( $input ) );
1200
        $output = preg_replace( '/([^a-z0-9\-_])/', '', $output );
1201
        $output = trim( str_replace( array( '__', '_', '--' ), '-', $output ), '-' );
1202
        $output = str_replace( '00000', '--1', $output );
1203
        if ( false !== $db_field )
1204
            $output = str_replace( '-', '_', $output );
1205
        return $output;
1206
    }
1207
1208
    /**
1209
     * Run admin_init methods for each field type
1210
     *
1211
     * @since 2.3
1212
     */
1213
    public function admin_init() {
1214
        $admin_field_types = pods_transient_get( 'pods_form_admin_init_field_types' );
1215
1216
        if ( empty( $admin_field_types ) ) {
1217
            $admin_field_types = array();
1218
1219
            $field_types = self::field_types();
1220
1221
            foreach ( $field_types as $field_type => $field_type_data ) {
1222
                $has_ajax = self::field_method( $field_type_data[ 'type' ], 'admin_init' );
1223
1224
                if ( false !== $has_ajax )
1225
                    $admin_field_types[] = $field_type;
1226
            }
1227
1228
            pods_transient_set( 'pods_form_admin_init_field_types', $admin_field_types );
1229
        }
1230
        else {
1231
            foreach ( $admin_field_types as $field_type ) {
1232
                self::field_method( $field_type, 'admin_init' );
1233
            }
1234
        }
1235
    }
1236
1237
    /**
1238
     * Autoload a Field Type's class
1239
     *
1240
     * @param string $field_type Field Type indentifier
1241
     * @param string $file The Field Type class file location
1242
     *
1243
     * @return string
1244
     * @access public
1245
     * @static
1246
     * @since 2.0
1247
     */
1248
    public static function field_loader( $field_type, $file = '' ) {
1249
        if ( isset( self::$loaded[ $field_type ] ) ) {
1250
            $class_vars = get_class_vars( get_class( self::$loaded[ $field_type ] ) ); // PHP 5.2.x workaround
1251
1252
            self::$field_group = ( isset( $class_vars[ 'group' ] ) ? $class_vars[ 'group' ] : '' );
1253
            self::$field_type = $class_vars[ 'type' ];
1254
1255
            if ( 'Unknown' != $class_vars[ 'label' ] )
1256
                return self::$loaded[ $field_type ];
1257
        }
1258
1259
        include_once PODS_DIR . 'classes/PodsField.php';
1260
1261
        $field_type = self::clean( $field_type, true, true );
1262
1263
        $class_name = ucfirst( $field_type );
1264
        $class_name = "PodsField_{$class_name}";
1265
1266
        $content_dir = realpath( WP_CONTENT_DIR );
1267
        $plugins_dir = realpath( WP_PLUGIN_DIR );
1268
        $muplugins_dir = realpath( WPMU_PLUGIN_DIR );
1269
        $abspath_dir = realpath( ABSPATH );
1270
1271
        if ( !class_exists( $class_name ) ) {
1272
            if ( isset( self::$field_types[ $field_type ] ) && !empty( self::$field_types[ $field_type ][ 'file' ] ) )
1273
                $file = realpath( self::$field_types[ $field_type ][ 'file' ] );
1274
1275
            if ( !empty( $file ) && 0 === strpos( $file, $abspath_dir ) && file_exists( $file ) )
1276
                include_once $file;
1277
            else {
1278
                $file = str_replace( '../', '', apply_filters( 'pods_form_field_include', PODS_DIR . 'classes/fields/' . basename( $field_type ) . '.php', $field_type ) );
1279
                $file = realpath( $file );
1280
1281
                if ( file_exists( $file ) && ( 0 === strpos( $file, $content_dir ) || 0 === strpos( $file, $plugins_dir ) || 0 === strpos( $file, $muplugins_dir ) || 0 === strpos( $file, $abspath_dir ) ) )
1282
                    include_once $file;
1283
            }
1284
        }
1285
1286
        if ( class_exists( $class_name ) )
1287
            $class = new $class_name();
1288
        else {
1289
            $class = new PodsField();
1290
            $class_name = 'PodsField';
1291
        }
1292
1293
        $class_vars = get_class_vars( $class_name ); // PHP 5.2.x workaround
1294
1295
        self::$field_group = ( isset( $class_vars[ 'group' ] ) ? $class_vars[ 'group' ] : '' );
1296
        self::$field_type = $class_vars[ 'type' ];
1297
1298
        self::$loaded[ $field_type ] =& $class;
1299
1300
        return self::$loaded[ $field_type ];
1301
    }
1302
1303
    /**
1304
     * Run a method from a Field Type's class
1305
     *
1306
     * @param string $field_type Field Type indentifier
0 ignored issues
show
Bug introduced by
There is no parameter named $field_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...
1307
     * @param string $method Method name
0 ignored issues
show
Bug introduced by
There is no parameter named $method. 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...
1308
     * @param mixed $arg More arguments
0 ignored issues
show
Bug introduced by
There is no parameter named $arg. 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...
1309
     *
1310
     * @return mixed
1311
     * @access public
1312
     * @static
1313
     * @since 2.0
1314
     */
1315
    public static function field_method() {
1316
        $args = func_get_args();
1317
1318
        if ( empty( $args ) && count( $args ) < 2 )
1319
            return false;
1320
1321
        $field_type = array_shift( $args );
1322
        $method = array_shift( $args );
1323
1324
        $class = self::field_loader( $field_type );
1325
1326
        if ( method_exists( $class, $method ) )
1327
            return call_user_func_array( array( $class, $method ), $args );
1328
1329
        return false;
1330
    }
1331
1332
    /**
1333
     * Add a new Pod field type
1334
     *
1335
     * @param string $type The new field type identifier
1336
     * @param string $file The new field type class file location
1337
     *
1338
     * @return array Field Type data
1339
     *
1340
     * @since 2.3
1341
     */
1342
    public static function register_field_type( $type, $file = null ) {
1343
        $field_type = pods_transient_get( 'pods_field_type_' . $type );
1344
1345
        if ( empty( $field_type ) || $field_type[ 'type' ] != $type || $field_type[ 'file' ] != $file ) {
1346
            self::field_loader( $type, $file );
1347
1348
            $class_vars = get_class_vars( get_class( self::$loaded[ $type ] ) ); // PHP 5.2.x workaround
1349
1350
            self::$field_types[ $type ] = $class_vars;
1351
            self::$field_types[ $type ][ 'file' ] = $file;
1352
1353
            pods_transient_set( 'pods_field_type_' . $type, self::$field_types[ $type ] );
1354
        }
1355
        else
1356
            self::$field_types[ $type ] = $field_type;
1357
1358
        return self::$field_types[ $type ];
1359
    }
1360
1361
    /**
1362
     * Get a list of all available field types and include
1363
     *
1364
     * @return array Registered Field Types data
1365
     *
1366
     * @since 2.3
1367
     */
1368
    public static function field_types() {
1369
        $field_types = array(
1370
            'text',
1371
            'website',
1372
            'phone',
1373
            'email',
1374
            'password',
1375
            'paragraph',
1376
            'wysiwyg',
1377
            'code',
1378
            'datetime',
1379
            'date',
1380
            'time',
1381
            'number',
1382
            'currency',
1383
            'file',
1384
            'avatar',
1385
            'pick',
1386
            'boolean',
1387
            'color',
1388
            'slug'
1389
        );
1390
1391
        $field_types = array_merge( $field_types, array_keys( self::$field_types ) );
1392
1393
        $field_types = array_filter( array_unique( $field_types ) );
1394
1395
        $types = apply_filters( 'pods_api_field_types', $field_types );
1396
1397
        $field_types = pods_transient_get( 'pods_field_types' );
1398
1399
        if ( empty( $field_types ) || count( $types ) != count( $field_types ) ) {
1400
            $field_types = array();
1401
1402
            foreach ( $types as $field_type ) {
1403
                $file = null;
1404
1405
                if ( isset( self::$field_types[ $field_type ] ) )
1406
                    $file = self::$field_types[ $field_type ][ 'file' ];
1407
1408
                self::field_loader( $field_type, $file );
1409
1410
                if ( !isset( self::$loaded[ $field_type ] ) || !is_object( self::$loaded[ $field_type ] ) )
1411
                    continue;
1412
1413
                $class_vars = get_class_vars( get_class( self::$loaded[ $field_type ] ) ); // PHP 5.2.x workaround
1414
1415
                $field_types[ $field_type ] = $class_vars;
1416
                $field_types[ $field_type ][ 'file' ] = $file;
1417
            }
1418
1419
            self::$field_types = $field_types;
1420
1421
            pods_transient_set( 'pods_field_types', self::$field_types );
1422
        }
1423
        else
1424
            self::$field_types = array_merge( $field_types, self::$field_types );
1425
1426
        return self::$field_types;
1427
    }
1428
1429
    /**
1430
     * Get list of available tableless field types
1431
     *
1432
     * @return array Tableless field types
1433
     *
1434
     * @since 2.3
1435
     */
1436 View Code Duplication
    public static function tableless_field_types() {
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...
1437
	    static $field_types = null;
1438
1439
	    if ( null === $field_types ) {
1440
		    $field_types = array( 'pick', 'file', 'avatar', 'taxonomy' );
1441
1442
		    $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1443
	    }
1444
	    return $field_types;
1445
    }
1446
1447
    /**
1448
     * Get list of available file field types
1449
     *
1450
     * @return array File field types
1451
     *
1452
     * @since 2.3
1453
     */
1454 View Code Duplication
    public static function file_field_types() {
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...
1455
	    static $field_types = null;
1456
1457
	    if ( null === $field_types ) {
1458
		    $field_types = array( 'file', 'avatar' );
1459
1460
		    $field_types = apply_filters( 'pods_file_field_types', $field_types );
1461
	    }
1462
	    return $field_types;
1463
    }
1464
1465
    /**
1466
     * Get list of available repeatable field types
1467
     *
1468
     * @return array Repeatable field types
1469
     *
1470
     * @since 2.3
1471
     */
1472
    public static function repeatable_field_types() {
1473
	    static $field_types = null;
1474
1475
	    if ( null === $field_types ) {
1476
		    $field_types = array(
1477
			    'code',
1478
			    'color',
1479
			    'currency',
1480
			    'date',
1481
			    'datetime',
1482
			    'email',
1483
			    'number',
1484
			    'paragraph',
1485
			    'phone',
1486
			    'text',
1487
			    'time',
1488
			    'website',
1489
			    'wysiwyg'
1490
		    );
1491
1492
		    $field_types = apply_filters( 'pods_repeatable_field_types', $field_types );
1493
	    }
1494
	    return $field_types;
1495
    }
1496
1497
    /**
1498
     * Get list of available number field types
1499
     *
1500
     * @return array Number field types
1501
     *
1502
     * @since 2.3
1503
     */
1504 View Code Duplication
    public static function number_field_types() {
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...
1505
	    static $field_types = null;
1506
1507
	    if ( null === $field_types ) {
1508
		    $field_types = array( 'currency', 'number' );
1509
1510
		    $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1511
	    }
1512
	    return $field_types;
1513
    }
1514
1515
    /**
1516
     * Get list of available date field types
1517
     *
1518
     * @return array Date field types
1519
     *
1520
     * @since 2.3
1521
     */
1522 View Code Duplication
    public static function date_field_types() {
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...
1523
	    static $field_types = null;
1524
1525
	    if ( null === $field_types ) {
1526
		    $field_types = array( 'date', 'datetime', 'time' );
1527
1528
		    $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1529
	    }
1530
	    return $field_types;
1531
    }
1532
1533
    /**
1534
     * Get list of available text field types
1535
     *
1536
     * @return array Text field types
1537
     *
1538
     * @since 2.3
1539
     */
1540
    public static function text_field_types() {
1541
	    static $field_types = null;
1542
1543
	    if ( null === $field_types ) {
1544
		    $field_types = array( 'code', 'paragraph', 'slug', 'password', 'text', 'wysiwyg' );
1545
1546
		    $field_types = apply_filters( 'pods_text_field_types', $field_types );
1547
	    }
1548
	    return $field_types;
1549
    }
1550
1551
    /**
1552
     * Get list of available text field types
1553
     *
1554
     * @return array Text field types
1555
     *
1556
     * @since 2.3
1557
     */
1558
    public static function block_field_types() {
1559
	    static $field_types = null;
1560
1561
	    if ( null === $field_types ) {
1562
		    $field_types = array( 'heading', 'html' );
1563
1564
		    /**
1565
		     * Returns the available text field types
1566
		     *
1567
		     * @since unknown
1568
		     *
1569
		     * @param object $field_types Outputs the field types
1570
		     */
1571
1572
		    $field_types = apply_filters( 'pods_block_field_types', $field_types );
1573
	    }
1574
	    return $field_types;
1575
    }
1576
1577
	/**
1578
	 * Get list of available text field types
1579
	 *
1580
	 * @return array Text field types
1581
	 *
1582
	 * @since 2.3
1583
	 */
1584
	public static function simple_tableless_objects() {
1585
		static $object_types = null;
1586
1587
		if ( null === $object_types ) {
1588
			$object_types = PodsForm::field_method( 'pick', 'simple_objects' );
1589
		}
1590
		return $object_types;
1591
	}
1592
1593
	}
1594