Completed
Pull Request — 2.x (#3683)
by
unknown
05:45
created

PodsForm::field()   C

Complexity

Conditions 24
Paths 126

Size

Total Lines 51
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 24
eloc 34
c 1
b 0
f 0
nc 126
nop 6
dl 0
loc 51
rs 5.1481

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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