Completed
Push — 2.x ( 4ed99b...cdb245 )
by Scott Kingsley
06:09
created

PodsForm::clean()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 14
nc 4
nop 3
dl 0
loc 26
rs 8.8571
c 1
b 0
f 0
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 field type 'db'
233
     *
234
     * Used for field names and other places where only [a-z0-9_] is accepted
235
     *
236
     * @since 2.0
237
     */
238 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...
239
        $form_field_type = self::$field_type;
240
241
        ob_start();
242
243
        pods_view( PODS_DIR . 'ui/fields/_db.php', compact( array_keys( get_defined_vars() ) ) );
244
245
        $output = ob_get_clean();
246
247
        return apply_filters( 'pods_form_ui_field_db', $output, $name, $value, $options );
248
    }
249
250
    /**
251
     * Output a hidden field
252
     */
253 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...
254
        $form_field_type = self::$field_type;
255
256
        ob_start();
257
258
        pods_view( PODS_DIR . 'ui/fields/_hidden.php', compact( array_keys( get_defined_vars() ) ) );
259
260
        $output = ob_get_clean();
261
262
        return apply_filters( 'pods_form_ui_field_hidden', $output, $name, $value, $options );
263
    }
264
265
	/**
266
	 * Returns a submit button, with provided text and appropriate class, copied from WP Core for use on the frontend
267
	 *
268
	 * @see get_submit_button
269
	 *
270
	 * @param string $text The text of the button (defaults to 'Save Changes')
271
	 * @param string $type The type of button. One of: primary, secondary, delete
272
	 * @param string $name The HTML name of the submit button. Defaults to "submit". If no id attribute
273
	 *               is given in $other_attributes below, $name will be used as the button's id.
274
	 * @param bool $wrap True if the output button should be wrapped in a paragraph tag,
275
	 * 			   false otherwise. Defaults to true
276
	 * @param array|string $other_attributes Other attributes that should be output with the button,
277
	 *                     mapping attributes to their values, such as array( 'tabindex' => '1' ).
278
	 *                     These attributes will be output as attribute="value", such as tabindex="1".
279
	 *                     Defaults to no other attributes. Other attributes can also be provided as a
280
	 *                     string such as 'tabindex="1"', though the array format is typically cleaner.
281
	 *
282
	 * @since 3.0
283
	 */
284
	public static function submit_button( $text = null, $type = 'primary large', $name = 'submit', $wrap = true, $other_attributes = null ) {
285
286
		if ( function_exists( 'get_submit_button' ) ) {
287
			return get_submit_button( $text, $type, $name, $wrap, $other_attributes );
288
		}
289
290
		if ( !is_array( $type ) ) {
291
			$type = explode( ' ', $type );
292
		}
293
294
		$button_shorthand = array(
295
			'primary',
296
			'small',
297
			'large'
298
		);
299
300
		$classes = array(
301
			'button'
302
		);
303
304
		foreach ( $type as $t ) {
305
			if ( 'secondary' === $t || 'button-secondary' === $t ) {
306
				continue;
307
			}
308
309
			$classes[] = in_array( $t, $button_shorthand ) ? 'button-' . $t : $t;
310
		}
311
312
		$class = implode( ' ', array_unique( $classes ) );
313
314
		if ( 'delete' === $type ) {
315
			$class = 'button-secondary delete';
316
		}
317
318
		$text = $text ? $text : __( 'Save Changes' );
319
320
		// Default the id attribute to $name unless an id was specifically provided in $other_attributes
321
		$id = $name;
322
323
		if ( is_array( $other_attributes ) && isset( $other_attributes[ 'id' ] ) ) {
324
			$id = $other_attributes[ 'id' ];
325
			unset( $other_attributes[ 'id' ] );
326
		}
327
328
		$attributes = '';
329
330
		if ( is_array( $other_attributes ) ) {
331
			foreach ( $other_attributes as $attribute => $value ) {
332
				$attributes .= $attribute . '="' . esc_attr( $value ) . '" '; // Trailing space is important
333
			}
334
		}
335
		elseif ( !empty( $other_attributes ) ) { // Attributes provided as a string
336
			$attributes = $other_attributes;
337
		}
338
339
		$button = '<input type="submit" name="' . esc_attr( $name ) . '" id="' . esc_attr( $id ) . '" class="' . esc_attr( $class );
340
		$button .= '" value="' . esc_attr( $text ) . '" ' . $attributes . ' />';
341
342
		if ( $wrap ) {
343
			$button = '<p class="submit">' . $button . '</p>';
344
		}
345
346
		return $button;
347
348
	}
349
350
    /**
351
     * Output a row (label, field, and comment)
352
     *
353
     * @param string $name Field name
354
     * @param mixed $value Field value
355
     * @param string $type Field type
356
     * @param array $options Field options
357
     * @param array $pod Pod data
358
     * @param int $id Item ID
359
     *
360
     * @return string Row HTML
361
     *
362
     * @since 2.0
363
     */
364
    public static function row( $name, $value, $type = 'text', $options = null, $pod = null, $id = null ) {
365
        $options = self::options( null, $options );
366
367
        ob_start();
368
369
        pods_view( PODS_DIR . 'ui/fields/_row.php', compact( array_keys( get_defined_vars() ) ) );
370
371
        $output = ob_get_clean();
372
373
        return apply_filters( 'pods_form_ui_field_row', $output, $name, $value, $options, $pod, $id );
374
    }
375
376
    /**
377
     * Output a field's attributes
378
     *
379
     * @since 2.0
380
     */
381
    public static function attributes( $attributes, $name = null, $type = null, $options = null ) {
382
        $attributes = (array) apply_filters( 'pods_form_ui_field_' . $type . '_attributes', $attributes, $name, $options );
383
384
        foreach ( $attributes as $attribute => $value ) {
385
            if ( null === $value )
386
                continue;
387
388
            echo ' ' . esc_attr( (string) $attribute ) . '="' . esc_attr( (string) $value ) . '"';
389
        }
390
    }
391
392
    /**
393
     * Output a field's data (for use with jQuery)
394
     *
395
     * @since 2.0
396
     */
397
    public static function data( $data, $name = null, $type = null, $options = null ) {
398
        $data = (array) apply_filters( 'pods_form_ui_field_' . $type . '_data', $data, $name, $options );
399
400
        foreach ( $data as $key => $value ) {
401
            if ( null === $value )
402
                continue;
403
404
            $key = sanitize_title( $key );
405
406
            if ( is_array( $value ) )
407
                $value = implode( ',', $value );
408
409
            echo ' data-' . esc_attr( (string) $key ) . '="' . esc_attr( (string) $value ) . '"';
410
        }
411
    }
412
413
    /**
414
     * Merge attributes and handle classes
415
     *
416
     * @since 2.0
417
     */
418
    public static function merge_attributes( $attributes, $name = null, $type = null, $options = null, $classes = '' ) {
419
        $options = (array) $options;
420
421
        if ( !in_array( $type, array( 'label', 'comment' ) ) ) {
422
            $name_clean = self::clean( $name );
423
            $name_more_clean = self::clean( $name, true );
424
            $_attributes = array();
425
            $_attributes[ 'name' ] = $name;
426
            $_attributes[ 'data-name-clean' ] = $name_more_clean;
427
428
            if ( 0 < strlen( pods_v( 'label', $options, '' ) ) )
429
                $_attributes[ 'data-label' ] = strip_tags( pods_v( 'label', $options ) );
430
431
            $_attributes[ 'id' ] = 'pods-form-ui-' . $name_clean;
432
            $_attributes[ 'class' ] = 'pods-form-ui-field-type-' . $type . ' pods-form-ui-field-name-' . $name_more_clean;
433
434
            if ( isset( $options[ 'dependency' ] ) && false !== $options[ 'dependency' ] )
435
                $_attributes[ 'class' ] .= ' pods-dependent-toggle';
436
437
            $attributes = array_merge( $_attributes, (array) $attributes );
438
439 View Code Duplication
            if ( isset( $options[ 'attributes' ] ) && is_array( $options[ 'attributes' ] ) && !empty( $options[ 'attributes' ] ) )
440
                $attributes = array_merge( $attributes, $options[ 'attributes' ] );
441
        }
442
        elseif ( isset( $options[ $type . '_attributes' ] ) && is_array( $options[ $type . '_attributes' ] ) && !empty( $options[ $type . '_attributes' ] ) )
443
            $attributes = array_merge( $attributes, $options[ $type . '_attributes' ] );
444
445
        if ( isset( $options[ 'class' ] ) && !empty( $options[ 'class' ] ) ) {
446
            if ( is_array( $options[ 'class' ] ) )
447
                $options[ 'class' ] = implode( ' ', $options[ 'class' ] );
448
449
            $options[ 'class' ] = (string) $options[ 'class' ];
450 View Code Duplication
            if ( isset( $attributes[ 'class' ] ) )
451
                $attributes[ 'class' ] = $attributes[ 'class' ] . ' ' . $options[ 'class' ];
452
            else
453
                $attributes[ 'class' ] = $options[ 'class' ];
454
455
            $attributes[ 'class' ] = trim( $attributes[ 'class' ] );
456
        }
457
458
        if ( !empty( $classes ) ) {
459 View Code Duplication
            if ( isset( $attributes[ 'class' ] ) )
460
                $attributes[ 'class' ] = $attributes[ 'class' ] . ' ' . $classes;
461
            else
462
                $attributes[ 'class' ] = $classes;
463
        }
464
465
        if ( isset( $options[ 'placeholder' ] ) && !empty( $options[ 'placeholder' ] ) ) {
466
            if ( is_array( $options[ 'placeholder' ] ) )
467
                $options[ 'placeholder' ] = implode( ' ', $options[ 'placeholder' ] );
468
469
            $options[ 'placeholder' ] = (string) $options[ 'placeholder' ];
470
			$attributes[ 'placeholder' ] = trim( $options[ 'placeholder' ] );
471
        }
472
473
        if ( 1 == pods_v( 'required', $options, 0 ) )
474
            $attributes[ 'class' ] .= ' pods-validate pods-validate-required';
475
476
        $max_length = (int) pods_var( 'maxlength', $options, pods_v( $type . '_max_length', $options, 0 ), null, true );
477
478
        if ( 0 < $max_length )
479
            $attributes[ 'maxlength' ] = $max_length;
480
481
        $attributes = (array) apply_filters( 'pods_form_ui_field_' . $type . '_merge_attributes', $attributes, $name, $options );
482
        return $attributes;
483
    }
484
485
    /**
486
     * Setup options for a field and store them for later use
487
     *
488
     * @param $type
489
     * @param $options
490
     *
491
     * @return array
492
     *
493
     * @static
494
     *
495
     * @since 2.0
496
     */
497
    public static function options( $type, $options ) {
498
        $options = (array) $options;
499
500
        if ( !is_object( $options ) && isset( $options[ 'options' ] ) ) {
501
            $options_temp = $options[ 'options' ];
502
503
            unset( $options[ 'options' ] );
504
505
            $options = array_merge( $options_temp, $options );
506
507
            $override = array(
508
                'class'
509
            );
510
511
            foreach ( $override as $check ) {
512
                if ( isset( $options_temp[ $check ] ) )
513
                    $options[ $check ] = $options_temp[ $check ];
514
            }
515
        }
516
517
        $defaults = self::options_setup( $type, $options );
518
519
        $core_defaults = array(
520
            'id' => 0,
521
            'label' => '',
522
            'description' => '',
523
            'help' => '',
524
            'default' => null,
525
            'attributes' => array(),
526
            'class' => '',
527
            'grouped' => 0,
528
        );
529
530
        $defaults = array_merge( $core_defaults, $defaults );
531
532
        foreach ( $defaults as $option => $settings ) {
533
            $default = $settings;
534
535
            if ( is_array( $settings ) && isset( $settings[ 'default' ] ) )
536
                $default = $settings[ 'default' ];
537
538
            if ( !isset( $options[ $option ] ) )
539
                $options[ $option ] = $default;
540
        }
541
542
        return $options;
543
    }
544
545
    /**
546
     * Get options for a field type and setup defaults
547
     *
548
     * @static
549
     *
550
     * @param $type
551
     *
552
     * @return array|null
553
     *
554
     * @since 2.0
555
     */
556
    public static function options_setup( $type = null, $options = null ) {
557
        $core_defaults = array(
558
            'id' => 0,
559
            'name' => '',
560
            'label' => '',
561
            'description' => '',
562
            'help' => '',
563
            'default' => null,
564
            'attributes' => array(),
565
            'class' => '',
566
            'type' => 'text',
567
            'group' => 0,
568
            'grouped' => 0,
569
            'developer_mode' => false,
570
            'dependency' => false,
571
            'depends-on' => array(),
572
            'excludes-on' => array(),
573
            'options' => array()
574
        );
575
576
        if ( !empty( $options ) && is_array( $options ) )
577
            $core_defaults = array_merge( $core_defaults, $options );
578
579
        if ( null === $type )
580
            return $core_defaults;
581
        else
582
            self::field_loader( $type );
583
584
        $options = apply_filters( 'pods_field_' . $type . '_options', (array) self::$loaded[ $type ]->options(), $type );
585
586
        $first_field = current( $options );
587
588
        if ( !empty( $options ) && !isset( $first_field[ 'name' ] ) && !isset( $first_field[ 'label' ] ) ) {
589
            $all_options = array();
590
591
            foreach ( $options as $group => $group_options ) {
592
                $all_options = array_merge( $all_options, self::fields_setup( $group_options, $core_defaults ) );
593
            }
594
595
            $options = $all_options;
596
        }
597
        else
598
            $options = self::fields_setup( $options, $core_defaults );
599
600
        return $options;
601
    }
602
603
    /**
604
     * Get Admin options for a field type and setup defaults
605
     *
606
     * @static
607
     *
608
     * @param $type
609
     *
610
     * @return array|null
611
     *
612
     * @since 2.0
613
     */
614
    public static function ui_options( $type ) {
615
        $core_defaults = array(
616
            'id' => 0,
617
            'name' => '',
618
            'label' => '',
619
            'description' => '',
620
            'help' => '',
621
            'default' => null,
622
            'attributes' => array(),
623
            'class' => '',
624
            'type' => 'text',
625
            'group' => 0,
626
            'grouped' => 0,
627
            'developer_mode' => false,
628
            'dependency' => false,
629
            'depends-on' => array(),
630
            'excludes-on' => array(),
631
            'options' => array()
632
        );
633
634
        self::field_loader( $type );
635
636
        $options = apply_filters( 'pods_field_' . $type . '_ui_options', (array) self::$loaded[ $type ]->ui_options(), $type );
637
638
        $first_field = current( $options );
639
640
        if ( !empty( $options ) && !isset( $first_field[ 'name' ] ) && !isset( $first_field[ 'label' ] ) ) {
641
            foreach ( $options as $group => $group_options ) {
642
                $options[ $group ] = self::fields_setup( $group_options, $core_defaults );
643
            }
644
        }
645
        else
646
            $options = self::fields_setup( $options, $core_defaults );
647
648
        return $options;
649
    }
650
651
    /**
652
     * Get options for a field and setup defaults
653
     *
654
     *
655
     * @param null $fields
656
     * @param null $core_defaults
657
     * @param bool $single
658
     *
659
     * @return array|null
660
     *
661
     * @static
662
     * @since 2.0
663
     */
664
    public static function fields_setup( $fields = null, $core_defaults = null, $single = false ) {
665
        if ( empty( $core_defaults ) ) {
666
            $core_defaults = array(
667
                'id' => 0,
668
                'name' => '',
669
                'label' => '',
670
                'description' => '',
671
                'help' => '',
672
                'default' => null,
673
                'attributes' => array(),
674
                'class' => '',
675
                'type' => 'text',
676
                'group' => 0,
677
                'grouped' => 0,
678
                'developer_mode' => false,
679
                'dependency' => false,
680
                'depends-on' => array(),
681
                'excludes-on' => array(),
682
                'options' => array()
683
            );
684
        }
685
686
        if ( $single )
687
            $fields = array( $fields );
688
689
        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...
690
            $fields[ $f ] = self::field_setup( $field, $core_defaults, pods_v( 'type', $field, 'text' ) );
691
692
            if ( !$single && strlen( $fields[ $f ][ 'name' ] ) < 1 )
693
                $fields[ $f ][ 'name' ] = $f;
694
        }
695
696
        if ( $single )
697
            $fields = $fields[ 0 ];
698
699
        return $fields;
700
    }
701
702
    /**
703
     * Get options for a field and setup defaults
704
     *
705
     * @static
706
     *
707
     * @param null $field
708
     * @param null $core_defaults
709
     * @param null $type
710
     *
711
     * @return array|null
712
     *
713
     * @since 2.0
714
     */
715
    public static function field_setup( $field = null, $core_defaults = null, $type = null ) {
716
        $options = array();
717
718
        if ( empty( $core_defaults ) ) {
719
            $core_defaults = array(
720
                'id' => 0,
721
                'name' => '',
722
                'label' => '',
723
                'description' => '',
724
                'help' => '',
725
                'default' => null,
726
                'attributes' => array(),
727
                'class' => '',
728
                'type' => 'text',
729
                'group' => 0,
730
                'grouped' => 0,
731
                'developer_mode' => false,
732
                'dependency' => false,
733
                'depends-on' => array(),
734
                'excludes-on' => array(),
735
                'options' => array()
736
            );
737
738
            if ( null !== $type ) {
739
                self::field_loader( $type );
740
741
                if ( method_exists( self::$loaded[ $type ], 'options' ) )
742
                    $options = apply_filters( 'pods_field_' . $type . '_options', (array) self::$loaded[ $type ]->options(), $type );
743
            }
744
        }
745
746
        if ( !is_array( $field ) )
747
            $field = array( 'default' => $field );
748
749
        if ( isset( $field[ 'group' ] ) && is_array( $field[ 'group' ] ) ) {
750
            foreach ( $field[ 'group' ] as $g => $group_option ) {
751
                $field[ 'group' ][ $g ] = array_merge( $core_defaults, $group_option );
752
753
                if ( strlen( $field[ 'group' ][ $g ][ 'name' ] ) < 1 )
754
                    $field[ 'group' ][ $g ][ 'name' ] = $g;
755
            }
756
        }
757
758
        $field = array_merge( $core_defaults, $field );
759
760
        foreach ( $options as $option => $settings ) {
761
            $v = null;
762
763
            if ( isset( $settings[ 'default' ] ) )
764
                $v = $settings[ 'default' ];
765
766
            if ( !isset( $field[ 'options' ][ $option ] ) )
767
                $field[ 'options' ][ $option ] = $v;
768
        }
769
770
        return $field;
771
    }
772
773
    /**
774
     * Setup dependency / exclusion classes
775
     *
776
     * @param array $options array( 'depends-on' => ..., 'excludes-on' => ...)
777
     * @param string $prefix
778
     *
779
     * @return string
780
     * @static
781
     * @since 2.0
782
     */
783
    public static function dependencies( $options, $prefix = '' ) {
784
        $options = (array) $options;
785
786
        $depends_on = $excludes_on = array();
787
        if ( isset( $options[ 'depends-on' ] ) )
788
            $depends_on = (array) $options[ 'depends-on' ];
789
790
        if ( isset( $options[ 'excludes-on' ] ) )
791
            $excludes_on = (array) $options[ 'excludes-on' ];
792
793
        $classes = array();
794
795 View Code Duplication
        if ( !empty( $depends_on ) ) {
796
            $classes[] = 'pods-depends-on';
797
798
            foreach ( $depends_on as $depends => $on ) {
799
                $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true );
800
801
                if ( !is_bool( $on ) ) {
802
                    $on = (array) $on;
803
804
                    foreach ( $on as $o ) {
805
                        $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true ) . '-' . self::clean( $o, true );
806
                    }
807
                }
808
            }
809
        }
810
811 View Code Duplication
        if ( !empty( $excludes_on ) ) {
812
            $classes[] = 'pods-excludes-on';
813
            foreach ( $excludes_on as $excludes => $on ) {
814
                $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true );
815
816
                $on = (array) $on;
817
818
                foreach ( $on as $o ) {
819
                    $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true ) . '-' . self::clean( $o, true );
820
                }
821
            }
822
        }
823
824
        $classes = implode( ' ', $classes );
825
826
        return $classes;
827
    }
828
829
    /**
830
     * Change the value of the field
831
     *
832
     * @param mixed $value
833
     * @param string $name
834
     * @param array $options
835
     * @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...
836
     * @param array $pod
837
     * @param int $id
838
     * @param array $traverse
839
     *
840
     * @since 2.3
841
     */
842
    public static function value( $type, $value = null, $name = null, $options = null, $pod = null, $id = null, $traverse = null ) {
843
        self::field_loader( $type );
844
845
        if ( in_array( $type, self::repeatable_field_types() ) && 1 == pods_v( $type . '_repeatable', $options, 0 ) && !is_array( $value ) ) {
846
            if ( 0 < strlen( $value ) ) {
847
                $simple = @json_decode( $value, true );
848
849
                if ( is_array( $simple ) )
850
                    $value = $simple;
851
                else
852
                    $value = (array) $value;
853
            }
854
            else
855
                $value = array();
856
        }
857
858
        if ( method_exists( self::$loaded[ $type ], 'value' ) ) {
859
            if ( is_array( $value ) && in_array( $type, self::tableless_field_types() ) ) {
860 View Code Duplication
                foreach ( $value as &$display_value ) {
861
                    $display_value = call_user_func_array( array( self::$loaded[ $type ], 'value' ), array( $display_value, $name, $options, $pod, $id, $traverse ) );
862
                }
863
            }
864 View Code Duplication
            else
865
                $value = call_user_func_array( array( self::$loaded[ $type ], 'value' ), array( $value, $name, $options, $pod, $id, $traverse ) );
866
        }
867
868
        return $value;
869
    }
870
871
    /**
872
     * Change the way the value of the field is displayed with Pods::get
873
     *
874
     * @param mixed $value
875
     * @param string $name
876
     * @param array $options
877
     * @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...
878
     * @param array $pod
879
     * @param int $id
880
     * @param array $traverse
881
     *
882
     * @since 2.0
883
     */
884
    public static function display( $type, $value = null, $name = null, $options = null, $pod = null, $id = null, $traverse = null ) {
885
        self::field_loader( $type );
886
887
        $tableless_field_types = self::tableless_field_types();
888
889
        if ( method_exists( self::$loaded[ $type ], 'display' ) ) {
890
            if ( is_array( $value ) && !in_array( $type, $tableless_field_types ) ) {
891 View Code Duplication
                foreach ( $value as $k => $display_value ) {
892
                    $value[ $k ] = call_user_func_array( array( self::$loaded[ $type ], 'display' ), array( $display_value, $name, $options, $pod, $id, $traverse ) );
893
                }
894
            }
895 View Code Duplication
            else
896
                $value = call_user_func_array( array( self::$loaded[ $type ], 'display' ), array( $value, $name, $options, $pod, $id, $traverse ) );
897
        }
898
899
        $value = apply_filters( 'pods_form_display_' . $type, $value, $name, $options, $pod, $id, $traverse );
900
901
        return $value;
902
    }
903
904
    /**
905
     * Setup regex for JS / PHP
906
     *
907
     * @static
908
     *
909
     * @param $type
910
     * @param $options
911
     *
912
     * @return mixed|void
913
     * @since 2.0
914
     */
915 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...
916
        self::field_loader( $type );
917
918
        $regex = false;
919
920
        if ( method_exists( self::$loaded[ $type ], 'regex' ) )
921
            $regex = self::$loaded[ $type ]->regex( $options );
922
923
        $regex = apply_filters( 'pods_field_' . $type . '_regex', $regex, $options, $type );
924
925
        return $regex;
926
    }
927
928
    /**
929
     * Setup value preparation for sprintf
930
     *
931
     * @static
932
     *
933
     * @param $type
934
     * @param $options
935
     *
936
     * @return mixed|void
937
     * @since 2.0
938
     */
939 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...
940
        self::field_loader( $type );
941
942
        $prepare = '%s';
943
944
        if ( method_exists( self::$loaded[ $type ], 'prepare' ) )
945
            $prepare = self::$loaded[ $type ]->prepare( $options );
946
947
        $prepare = apply_filters( 'pods_field_' . $type . '_prepare', $prepare, $options, $type );
948
949
        return $prepare;
950
    }
951
952
    /**
953
     * Validate a value before it's saved
954
     *
955
     * @param string $type
956
     * @param mixed $value
957
     * @param string $name
958
     * @param array $options
959
     * @param array $fields
960
     * @param array $pod
961
     * @param int $id
962
     * @param array|object $params
963
     *
964
     * @static
965
     *
966
     * @since 2.0
967
     */
968
    public static function validate( $type, $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
969
        self::field_loader( $type );
970
971
        $validate = true;
972
973
        if ( 1 == pods_v( 'pre_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'validate' ) )
974
            $validate = self::$loaded[ $type ]->validate( $value, $name, $options, $fields, $pod, $id, $params );
975
976
        $validate = apply_filters( 'pods_field_' . $type . '_validate', $validate, $value, $name, $options, $fields, $pod, $id, $type, $params );
977
978
        return $validate;
979
    }
980
981
    /**
982
     * Change the value or perform actions after validation but before saving to the DB
983
     *
984
     * @param string $type
985
     * @param mixed $value
986
     * @param int $id
987
     * @param string $name
988
     * @param array $options
989
     * @param array $fields
990
     * @param array $pod
991
     * @param object $params
992
     *
993
     * @static
994
     *
995
     * @since 2.0
996
     */
997 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...
998
        self::field_loader( $type );
999
1000
        if ( 1 == pods_v( 'field_pre_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'pre_save' ) )
1001
            $value = self::$loaded[ $type ]->pre_save( $value, $id, $name, $options, $fields, $pod, $params );
1002
1003
        return $value;
1004
    }
1005
1006
    /**
1007
     * Save the value to the DB
1008
     *
1009
     * @param string $type
1010
     * @param mixed $value
1011
     * @param int $id
1012
     * @param string $name
1013
     * @param array $options
1014
     * @param array $fields
1015
     * @param array $pod
1016
     * @param object $params
1017
     *
1018
     * @static
1019
     *
1020
     * @since 2.3
1021
     */
1022 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...
1023
        self::field_loader( $type );
1024
1025
        $saved = null;
1026
1027
        if ( 1 == pods_v( 'field_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'save' ) )
1028
            $saved = self::$loaded[ $type ]->save( $value, $id, $name, $options, $fields, $pod, $params );
1029
1030
        return $saved;
1031
    }
1032
1033
    /**
1034
     * Delete the value from the DB
1035
     *
1036
     * @param string $type
1037
     * @param int $id
1038
     * @param string $name
1039
     * @param array $options
1040
     * @param array $pod
1041
     *
1042
     * @static
1043
     *
1044
     * @since 2.3
1045
     */
1046 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...
1047
        self::field_loader( $type );
1048
1049
        $deleted = null;
1050
1051
        if ( 1 == pods_v( 'field_delete', $options, 1 ) && method_exists( self::$loaded[ $type ], 'delete' ) )
1052
            $deleted = self::$loaded[ $type ]->delete( $id, $name, $options, $pod );
1053
1054
        return $deleted;
1055
    }
1056
1057
    /**
1058
     * Check if a user has permission to be editing a field
1059
     *
1060
     * @param $type
1061
     * @param null $name
1062
     * @param null $options
1063
     * @param null $fields
1064
     * @param null $pod
1065
     * @param null $id
1066
     * @param null $params
1067
     *
1068
     * @static
1069
     *
1070
     * @since 2.0
1071
     */
1072
    public static function permission( $type, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
1073
        $permission = pods_permission( $options );
1074
1075
        $permission = (boolean) apply_filters( 'pods_form_field_permission', $permission, $type, $name, $options, $fields, $pod, $id, $params );
1076
1077
        return $permission;
1078
    }
1079
1080
    /**
1081
     * Parse the default the value
1082
     *
1083
     * @since 2.0
1084
     */
1085
    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...
1086
        $default_value = pods_v( 'default_value', $options );
1087
1088
		if ( '' === $default_value || null === $default_value ) {
1089
			$default_value = $value;
1090
		}
1091
1092
        $default = pods_v( 'default', $options, $default_value, true );
1093
1094
	    if ( is_string( $default ) ) {
1095
		    $default_value = str_replace( array( '{@', '}' ), '', trim( $default ) );
1096
	    }
1097
1098
        if ( $default != $default_value && 1 == (int) pods_v( 'default_evaluate_tags', $options, 1 ) )
1099
            $default = pods_evaluate_tags( $default );
1100
1101
        $default = pods_var_raw( pods_v( 'default_value_parameter', $options ), 'request', $default, null, true );
1102
1103
        if ( $default != $value )
1104
            $value = $default;
1105
1106
        if ( is_array( $value ) )
1107
            $value = pods_serial_comma( $value );
1108
1109
        return apply_filters( 'pods_form_field_default_value', $value, $default, $type, $options, $pod, $id );
1110
    }
1111
1112
    /**
1113
     * Clean a value for use in class / id
1114
     *
1115
     * @since 2.0
1116
     */
1117
    public static function clean( $input, $noarray = false, $db_field = false ) {
1118
1119
	    $output = trim( (string) $input );
1120
1121
        $output = str_replace( array( '--1', '__1' ), '00000', $output );
1122
1123
        if ( false !== $noarray ) {
1124
	        $output = preg_replace( '/\[\d*\]/', '-', $output );
1125
        }
1126
1127
        $output = str_replace( array( '[', ']' ), '-', $output );
1128
1129
	    $output = pods_clean_name( $output );
1130
1131
        $output = preg_replace( '/([^a-z0-9\-_])/', '', $output );
1132
	    $output = preg_replace( '/_{2,}/', '_', $output );
1133
	    $output = preg_replace( '/-{2,}/', '-', $output );
1134
1135
	    if ( $db_field ) {
1136
		    $output = str_replace( '_', '-', $output );
1137
	    }
1138
1139
        $output = str_replace( '00000', '--1', $output );
1140
1141
        return $output;
1142
    }
1143
1144
    /**
1145
     * Run admin_init methods for each field type
1146
     *
1147
     * @since 2.3
1148
     */
1149
    public function admin_init() {
1150
        $admin_field_types = pods_transient_get( 'pods_form_admin_init_field_types' );
1151
1152
        if ( empty( $admin_field_types ) ) {
1153
            $admin_field_types = array();
1154
1155
            $field_types = self::field_types();
1156
1157
            foreach ( $field_types as $field_type => $field_type_data ) {
1158
                $has_ajax = self::field_method( $field_type_data[ 'type' ], 'admin_init' );
1159
1160
                if ( false !== $has_ajax )
1161
                    $admin_field_types[] = $field_type;
1162
            }
1163
1164
            pods_transient_set( 'pods_form_admin_init_field_types', $admin_field_types );
1165
        }
1166
        else {
1167
            foreach ( $admin_field_types as $field_type ) {
1168
                self::field_method( $field_type, 'admin_init' );
1169
            }
1170
        }
1171
    }
1172
1173
    /**
1174
     * Autoload a Field Type's class
1175
     *
1176
     * @param string $field_type Field Type indentifier
1177
     * @param string $file The Field Type class file location
1178
     *
1179
     * @return string
1180
     * @access public
1181
     * @static
1182
     * @since 2.0
1183
     */
1184
    public static function field_loader( $field_type, $file = '' ) {
1185
        if ( isset( self::$loaded[ $field_type ] ) ) {
1186
            $class_vars = get_class_vars( get_class( self::$loaded[ $field_type ] ) ); // PHP 5.2.x workaround
1187
1188
            self::$field_group = ( isset( $class_vars[ 'group' ] ) ? $class_vars[ 'group' ] : '' );
1189
            self::$field_type = $class_vars[ 'type' ];
1190
1191
            if ( 'Unknown' != $class_vars[ 'label' ] )
1192
                return self::$loaded[ $field_type ];
1193
        }
1194
1195
        include_once PODS_DIR . 'classes/PodsField.php';
1196
1197
        $field_type = self::clean( $field_type, true, true );
1198
1199
        $class_name = ucfirst( $field_type );
1200
        $class_name = "PodsField_{$class_name}";
1201
1202
        $content_dir = realpath( WP_CONTENT_DIR );
1203
        $plugins_dir = realpath( WP_PLUGIN_DIR );
1204
        $muplugins_dir = realpath( WPMU_PLUGIN_DIR );
1205
        $abspath_dir = realpath( ABSPATH );
1206
1207
        if ( !class_exists( $class_name ) ) {
1208
            if ( isset( self::$field_types[ $field_type ] ) && !empty( self::$field_types[ $field_type ][ 'file' ] ) )
1209
                $file = realpath( self::$field_types[ $field_type ][ 'file' ] );
1210
1211
            if ( !empty( $file ) && 0 === strpos( $file, $abspath_dir ) && file_exists( $file ) )
1212
                include_once $file;
1213
            else {
1214
                $file = str_replace( '../', '', apply_filters( 'pods_form_field_include', PODS_DIR . 'classes/fields/' . basename( $field_type ) . '.php', $field_type ) );
1215
                $file = realpath( $file );
1216
1217
                if ( file_exists( $file ) && ( 0 === strpos( $file, $content_dir ) || 0 === strpos( $file, $plugins_dir ) || 0 === strpos( $file, $muplugins_dir ) || 0 === strpos( $file, $abspath_dir ) ) )
1218
                    include_once $file;
1219
            }
1220
        }
1221
1222
        if ( class_exists( $class_name ) )
1223
            $class = new $class_name();
1224
        else {
1225
            $class = new PodsField();
1226
            $class_name = 'PodsField';
1227
        }
1228
1229
        $class_vars = get_class_vars( $class_name ); // PHP 5.2.x workaround
1230
1231
        self::$field_group = ( isset( $class_vars[ 'group' ] ) ? $class_vars[ 'group' ] : '' );
1232
        self::$field_type = $class_vars[ 'type' ];
1233
1234
        self::$loaded[ $field_type ] =& $class;
1235
1236
        return self::$loaded[ $field_type ];
1237
    }
1238
1239
    /**
1240
     * Run a method from a Field Type's class
1241
     *
1242
     * @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...
1243
     * @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...
1244
     * @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...
1245
     *
1246
     * @return mixed
1247
     * @access public
1248
     * @static
1249
     * @since 2.0
1250
     */
1251
    public static function field_method() {
1252
        $args = func_get_args();
1253
1254
        if ( empty( $args ) && count( $args ) < 2 )
1255
            return false;
1256
1257
        $field_type = array_shift( $args );
1258
        $method = array_shift( $args );
1259
1260
        $class = self::field_loader( $field_type );
1261
1262
        if ( method_exists( $class, $method ) )
1263
            return call_user_func_array( array( $class, $method ), $args );
1264
1265
        return false;
1266
    }
1267
1268
    /**
1269
     * Add a new Pod field type
1270
     *
1271
     * @param string $type The new field type identifier
1272
     * @param string $file The new field type class file location
1273
     *
1274
     * @return array Field Type data
1275
     *
1276
     * @since 2.3
1277
     */
1278
    public static function register_field_type( $type, $file = null ) {
1279
        $field_type = pods_transient_get( 'pods_field_type_' . $type );
1280
1281
        if ( empty( $field_type ) || $field_type[ 'type' ] != $type || $field_type[ 'file' ] != $file ) {
1282
            self::field_loader( $type, $file );
1283
1284
            $class_vars = get_class_vars( get_class( self::$loaded[ $type ] ) ); // PHP 5.2.x workaround
1285
1286
            self::$field_types[ $type ] = $class_vars;
1287
            self::$field_types[ $type ][ 'file' ] = $file;
1288
1289
            pods_transient_set( 'pods_field_type_' . $type, self::$field_types[ $type ] );
1290
        }
1291
        else
1292
            self::$field_types[ $type ] = $field_type;
1293
1294
        return self::$field_types[ $type ];
1295
    }
1296
1297
    /**
1298
     * Get a list of all available field types and include
1299
     *
1300
     * @return array Registered Field Types data
1301
     *
1302
     * @since 2.3
1303
     */
1304
    public static function field_types() {
1305
        $field_types = array(
1306
            'text',
1307
            'website',
1308
            'phone',
1309
            'email',
1310
            'password',
1311
            'paragraph',
1312
            'wysiwyg',
1313
            'code',
1314
            'datetime',
1315
            'date',
1316
            'time',
1317
            'number',
1318
            'currency',
1319
            'file',
1320
            'avatar',
1321
            'pick',
1322
            'boolean',
1323
            'color',
1324
            'slug'
1325
        );
1326
1327
        $field_types = array_merge( $field_types, array_keys( self::$field_types ) );
1328
1329
        $field_types = array_filter( array_unique( $field_types ) );
1330
1331
        $types = apply_filters( 'pods_api_field_types', $field_types );
1332
1333
        $field_types = pods_transient_get( 'pods_field_types' );
1334
1335
        if ( empty( $field_types ) || count( $types ) != count( $field_types ) ) {
1336
            $field_types = array();
1337
1338
            foreach ( $types as $field_type ) {
1339
                $file = null;
1340
1341
                if ( isset( self::$field_types[ $field_type ] ) )
1342
                    $file = self::$field_types[ $field_type ][ 'file' ];
1343
1344
                self::field_loader( $field_type, $file );
1345
1346
                if ( !isset( self::$loaded[ $field_type ] ) || !is_object( self::$loaded[ $field_type ] ) )
1347
                    continue;
1348
1349
                $class_vars = get_class_vars( get_class( self::$loaded[ $field_type ] ) ); // PHP 5.2.x workaround
1350
1351
                $field_types[ $field_type ] = $class_vars;
1352
                $field_types[ $field_type ][ 'file' ] = $file;
1353
            }
1354
1355
            self::$field_types = $field_types;
1356
1357
            pods_transient_set( 'pods_field_types', self::$field_types );
1358
        }
1359
        else
1360
            self::$field_types = array_merge( $field_types, self::$field_types );
1361
1362
        return self::$field_types;
1363
    }
1364
1365
    /**
1366
     * Get list of available tableless field types
1367
     *
1368
     * @return array Tableless field types
1369
     *
1370
     * @since 2.3
1371
     */
1372 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...
1373
	    static $field_types = null;
1374
1375
	    if ( null === $field_types ) {
1376
		    $field_types = array( 'pick', 'file', 'avatar', 'taxonomy' );
1377
1378
		    $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1379
	    }
1380
	    return $field_types;
1381
    }
1382
1383
    /**
1384
     * Get list of available file field types
1385
     *
1386
     * @return array File field types
1387
     *
1388
     * @since 2.3
1389
     */
1390 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...
1391
	    static $field_types = null;
1392
1393
	    if ( null === $field_types ) {
1394
		    $field_types = array( 'file', 'avatar' );
1395
1396
		    $field_types = apply_filters( 'pods_file_field_types', $field_types );
1397
	    }
1398
	    return $field_types;
1399
    }
1400
1401
    /**
1402
     * Get list of available repeatable field types
1403
     *
1404
     * @return array Repeatable field types
1405
     *
1406
     * @since 2.3
1407
     */
1408
    public static function repeatable_field_types() {
1409
	    static $field_types = null;
1410
1411
	    if ( null === $field_types ) {
1412
		    $field_types = array(
1413
			    'code',
1414
			    'color',
1415
			    'currency',
1416
			    'date',
1417
			    'datetime',
1418
			    'email',
1419
			    'number',
1420
			    'paragraph',
1421
			    'phone',
1422
			    'text',
1423
			    'time',
1424
			    'website',
1425
			    'wysiwyg'
1426
		    );
1427
1428
		    $field_types = apply_filters( 'pods_repeatable_field_types', $field_types );
1429
	    }
1430
	    return $field_types;
1431
    }
1432
1433
    /**
1434
     * Get list of available number field types
1435
     *
1436
     * @return array Number field types
1437
     *
1438
     * @since 2.3
1439
     */
1440 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...
1441
	    static $field_types = null;
1442
1443
	    if ( null === $field_types ) {
1444
		    $field_types = array( 'currency', 'number' );
1445
1446
		    $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1447
	    }
1448
	    return $field_types;
1449
    }
1450
1451
    /**
1452
     * Get list of available date field types
1453
     *
1454
     * @return array Date field types
1455
     *
1456
     * @since 2.3
1457
     */
1458 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...
1459
	    static $field_types = null;
1460
1461
	    if ( null === $field_types ) {
1462
		    $field_types = array( 'date', 'datetime', 'time' );
1463
1464
		    $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1465
	    }
1466
	    return $field_types;
1467
    }
1468
1469
    /**
1470
     * Get list of available text field types
1471
     *
1472
     * @return array Text field types
1473
     *
1474
     * @since 2.3
1475
     */
1476
    public static function text_field_types() {
1477
	    static $field_types = null;
1478
1479
	    if ( null === $field_types ) {
1480
		    $field_types = array( 'code', 'paragraph', 'slug', 'password', 'text', 'wysiwyg' );
1481
1482
		    $field_types = apply_filters( 'pods_text_field_types', $field_types );
1483
	    }
1484
	    return $field_types;
1485
    }
1486
1487
    /**
1488
     * Get list of available text field types
1489
     *
1490
     * @return array Text field types
1491
     *
1492
     * @since 2.3
1493
     */
1494
    public static function block_field_types() {
1495
	    static $field_types = null;
1496
1497
	    if ( null === $field_types ) {
1498
		    $field_types = array( 'heading', 'html' );
1499
1500
		    /**
1501
		     * Returns the available text field types
1502
		     *
1503
		     * @since unknown
1504
		     *
1505
		     * @param object $field_types Outputs the field types
1506
		     */
1507
1508
		    $field_types = apply_filters( 'pods_block_field_types', $field_types );
1509
	    }
1510
	    return $field_types;
1511
    }
1512
1513
	/**
1514
	 * Get list of available text field types
1515
	 *
1516
	 * @return array Text field types
1517
	 *
1518
	 * @since 2.3
1519
	 */
1520
	public static function simple_tableless_objects() {
1521
		static $object_types = null;
1522
1523
		if ( null === $object_types ) {
1524
			$object_types = PodsForm::field_method( 'pick', 'simple_objects' );
1525
		}
1526
		return $object_types;
1527
	}
1528
1529
	}
1530