Completed
Pull Request — 2.x (#3588)
by
unknown
06:31
created

PodsField_Link::validate()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 15
c 1
b 0
f 0
nc 8
nop 7
dl 0
loc 23
rs 8.5906
1
<?php
2
/**
3
 * @package Pods\Fields
4
 */
5
class PodsField_Link extends PodsField {
6
7
    /**
8
     * Field Type Group
9
     *
10
     * @var string
11
     * @since 2.0
12
     */
13
    public static $group = 'Text';
14
15
    /**
16
     * Field Type Identifier
17
     *
18
     * @var string
19
     * @since 2.0
20
     */
21
    public static $type = 'link';
22
23
    /**
24
     * Field Type Label
25
     *
26
     * @var string
27
     * @since 2.0
28
     */
29
    public static $label = 'Link';
30
31
    /**
32
     * Field Type Preparation
33
     *
34
     * @var string
35
     * @since 2.0
36
     */
37
    public static $prepare = '%s';
38
39
    /**
40
     * Do things like register/enqueue scripts and stylesheets
41
     *
42
     * @since 2.0
43
     */
44
    public function __construct () {
45
		
46
    }
47
	
48
    /**
49
     * Add options and set defaults to
50
     *
51
     * @param array $options
0 ignored issues
show
Bug introduced by
There is no parameter named $options. 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...
52
     *
53
     * @since 2.0
54
     */
55
    public function options () {
56
        $options = array(
57
            self::$type . '_repeatable' => array(
58
                'label' => __( 'Repeatable Field', 'pods' ),
59
                'default' => 0,
60
                'type' => 'boolean',
61
                'help' => __( 'Making a field repeatable will add controls next to the field which allows users to Add/Remove/Reorder additional values. These values are saved in the database as an array, so searching and filtering by them may require further adjustments".', 'pods' ),
62
                'boolean_yes_label' => '',
63
                'dependency' => true,
64
                'developer_mode' => true
65
            ),
66
            self::$type . '_format' => array(
67
                'label' => __( 'Format', 'pods' ),
68
                'default' => 'normal',
69
                'type' => 'pick',
70
                'data' => array(
71
                    'none' => __( 'No URL format restrictions', 'pods' ),
72
                    'normal' => __( 'http://example.com/', 'pods' ),
73
                    'no-www' => __( 'http://example.com/ (remove www)', 'pods' ),
74
                    'force-www' => __( 'http://www.example.com/ (force www if no sub-domain provided)', 'pods' ),
75
                    'no-http' => __( 'example.com', 'pods' ),
76
                    'no-http-no-www' => __( 'example.com (force removal of www)', 'pods' ),
77
                    'no-http-force-www' => __( 'www.example.com (force www if no sub-domain provided)', 'pods' )
78
                )
79
            ),
80
            'output_options' => array(
81
                'label' => __( 'Output Options', 'pods' ),
82
                'group' => array(
83
                    self::$type . '_allow_shortcode' => array(
84
                        'label' => __( 'Allow Shortcodes?', 'pods' ),
85
                        'default' => 0,
86
                        'type' => 'boolean',
87
                        'dependency' => true
88
                    ),
89
                    self::$type . '_allow_html' => array(
90
                        'label' => __( 'Allow HTML?', 'pods' ),
91
                        'default' => 0,
92
                        'type' => 'boolean',
93
                        'dependency' => true
94
                    )
95
                )
96
            ),
97
            self::$type . '_allowed_html_tags' => array(
98
                'label' => __( 'Allowed HTML Tags', 'pods' ),
99
                'depends-on' => array( self::$type . '_allow_html' => true ),
100
                'default' => 'strong em a ul ol li b i',
101
                'type' => 'text'
102
            ),
103
            /*self::$type . '_max_length' => array(
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
104
                'label' => __( 'Maximum Length', 'pods' ),
105
                'default' => 255,
106
                'type' => 'number',
107
                'help' => __( 'Set to -1 for no limit', 'pods' )
108
            ),*/
109
            self::$type . '_html5' => array(
110
                'label' => __( 'Enable HTML5 Input Field?', 'pods' ),
111
                'default' => apply_filters( 'pods_form_ui_field_html5', 0, self::$type ),
112
                'type' => 'boolean'
113
            )/*,
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
114
            self::$type . '_size' => array(
115
                'label' => __( 'Field Size', 'pods' ),
116
                'default' => 'medium',
117
                'type' => 'pick',
118
                'data' => array(
119
                    'small' => __( 'Small', 'pods' ),
120
                    'medium' => __( 'Medium', 'pods' ),
121
                    'large' => __( 'Large', 'pods' )
122
                )
123
            )*/
124
        );
125
        return $options;
126
    }
127
128
    /**
129
     * Define the current field's schema for DB table storage
130
     *
131
     * @param array $options
132
     *
133
     * @return array
134
     * @since 2.0
135
     */
136
    public function schema ( $options = null ) {
137
        $schema = 'LONGTEXT';
138
        return $schema;
139
    }
140
    
141
	/**
142
	 * Change the value of the field
143
	 *
144
	 * @param mixed $value
145
	 * @param string $name
146
	 * @param array $options
147
	 * @param array $pod
148
	 * @param int $id
149
	 *
150
	 * @return mixed|null|string
151
	 * @since 2.3
152
	 */
153
	public function value ( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
154
		return $value;
155
	}
156
	
157
    /**
158
     * Change the way the value of the field is displayed with Pods::get
159
     *
160
     * @param mixed $value
161
     * @param string $name
162
     * @param array $options
163
     * @param array $pod
164
     * @param int $id
165
     *
166
     * @return mixed|null|string
167
     * @since 2.0
168
     */
169
    public function display ( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
170
171
        // Validate for an array because display is also used for the get_post_meta filters along the function chain
172
        if ( ! is_array( $value ) ) {
173
            return $value;
174
        }
175
176
        // Ensure proper format
177
        $value = $this->pre_save( $value, $id, $name, $options, null, $pod );
178
        
179
        if ( isset( $value['url'] ) ) {
180
181
            $link = '<a href="%s"%s>%s</a>';
182
183
            // Build the URL
184
            $url = $this->build_url( parse_url( $value['url'] ) );
185
186
            // Display URL as text by default. If text provided, use the text input
187
            $text = $url;
188
            if ( isset( $value['text'] ) && ! empty( $value['text'] ) ) {
189
                $text = $this->strip_html( $value['text'], $options );
190
            }
191
192
            $atts = '';
193
            if ( ! empty( $value['target'] ) ) {
194
                // Possible support for other targets in future
195
                $atts .= ' target="' . esc_attr( $value['target'] ) . '"';
196
            }
197
198
            // Do shortcodes if this is enabled
199
            if ( 1 == pods_var( self::$type . '_allow_shortcode', $options ) ) {
200
                $url = do_shortcode( $url );
201
                $text = do_shortcode( $text );
202
            }
203
204
            // Return the value
205
            $value = sprintf( $link, esc_url( $url ), $atts, $text );
206
207
        } elseif ( isset( $value['text'] ) ) {
208
            // No URL data found (probably database error), return text is this is available
209
            $value = $this->strip_html( $value['text'], $options );
210
        }
211
212
        // Return database value or display value if above conditions are met
213
        return $value;
214
    }
215
216
    /**
217
     * Customize output of the form field
218
     *
219
     * @param string $name
220
     * @param mixed $value
221
     * @param array $options
222
     * @param array $pod
223
     * @param int $id
224
     *
225
     * @since 2.0
226
     */
227
    public function input ( $name, $value = null, $options = null, $pod = null, $id = null ) {
228
        $options = (array) $options;
229
        $form_field_type = PodsForm::$field_type;
0 ignored issues
show
Bug introduced by
The property field_type cannot be accessed from this context as it is declared private in class PodsForm.

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

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

Loading history...
230
        $field_type = 'link';
231
        pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
232
    }
233
234
    /**
235
     * Validate a value before it's saved
236
     *
237
     * @param mixed $value
238
     * @param string $name
239
     * @param array $options
240
     * @param array $fields
241
     * @param array $pod
242
     * @param int $id
243
     *
244
     * @since 2.0
245
     */
246
    public function validate ( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
247
        $errors = array();
248
		
249
        $label = strip_tags( pods_var_raw( 'label', $options, ucwords( str_replace( '_', ' ', $name ) ) ) );
250
251
        $check = $this->pre_save( $value, $id, $name, $options, $fields, $pod, $params );
252
		
253
        if ( is_array( $check['url'] ) )
254
            $errors = $check['url'];
255
        else {
256
            if ( 0 < strlen( $value['url'] ) && strlen( $check['url'] ) < 1 ) {
257
                if ( 1 == pods_var( 'required', $options ) )
258
                    $errors[] = sprintf( __( 'The %s field is required.', 'pods' ), $label );
259
                else
260
                    $errors[] = sprintf( __( 'Invalid link provided for the field %s.', 'pods' ), $label );
261
            }
262
        }
263
264
        if ( !empty( $errors ) )
265
            return $errors;
266
		
267
        return true;
268
    }
269
270
    /**
271
     * Change the value or perform actions after validation but before saving to the DB
272
     *
273
     * @param mixed $value
274
     * @param int $id
275
     * @param string $name
276
     * @param array $options
277
     * @param array $fields
278
     * @param array $pod
279
     * @param object $params
280
     *
281
     * @since 2.0
282
     */
283
    public function pre_save ( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
284
        $options = (array) $options;
285
		
286
		// Start URL format
287
        if ( isset ($value['url']) ) {
288
	       $value['url'] = $this->validate_url( $value['url'], $options );
289
        }
290
		
291
		// Start Title format
292
        if ( isset ($value['text']) ) {
293
            $value['text'] = $this->strip_html( $value['text'], $options );
294
        }
295
296
		// Start Target format
297
        if ( isset ($value['target']) ) {
298
           $value['target'] = $this->validate_target( $value['target'], $options );
299
        }
300
		
301
        return $value;
302
    }
303
	
304
    /**
305
     * Customize the Pods UI manage table column output
306
     *
307
     * @param int $id
308
     * @param mixed $value
309
     * @param string $name
310
     * @param array $options
311
     * @param array $fields
312
     * @param array $pod
313
     *
314
     * @since 2.0
315
     */
316
    public function ui ( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) {
317
        if ( 'link' == pods_var( self::$type . '_format_type', $options ) && 0 < strlen( pods_var( self::$type . '_format', $options ) ) )
318
            $value = make_clickable( $value );
319
320
        return $value;
321
    }
322
323
    /**
324
     * Validate an URL with the options
325
     *
326
     * @param string $value
327
     * @param array $options
328
     *
329
     * @since 2.0
330
     */
331
    public function validate_url( $value, $options = null ) {
332
        if ( empty( $value ) )
333
            return $value;
334
        
335
        if ( 'none' != pods_var( self::$type . '_format', $options ) ) {
336
            
337 View Code Duplication
            if ( is_array( $value ) ) {
338
                if ( isset( $value[ 'scheme' ] ) )
339
                    $value = $this->build_url( $value );
340
                else
341
                    $value = implode( '', $value );
342
            }
343
    
344 View Code Duplication
            if ( false === strpos( $value, '://' ) && 0 !== strpos( $value, '//' ) )
345
                $value = 'http://' . $value;
346
    
347
            $url = @parse_url( $value );
348
    
349 View Code Duplication
            if ( empty( $url ) || count( $url ) < 2 )
350
                $value = '';
351
            else {
352
                $defaults = array(
353
                    'scheme' => 'http',
354
                    'host' => '',
355
                    'path' => '/',
356
                    'query' => '',
357
                    'fragment' => ''
358
                );
359
    
360
                $url = array_merge( $defaults, $url );
361
    
362
                if ( 'normal' == pods_var( self::$type . '_format', $options ) )
363
                    $value = $this->build_url( $url );
364
                elseif ( 'no-www' == pods_var( self::$type . '_format', $options ) ) {
365
                    if ( 0 === strpos( $url[ 'host' ], 'www.' ) )
366
                        $url[ 'host' ] = substr( $url[ 'host' ], 4 );
367
    
368
                    $value = $this->build_url( $url );
369
                }
370
                elseif ( 'force-www' == pods_var( self::$type . '_format', $options ) ) {
371
                    if ( false !== strpos( $url[ 'host' ], '.' ) && false === strpos( $url[ 'host' ], '.', 1 ) )
372
                        $url[ 'host' ] = 'www.' . $url[ 'host' ];
373
    
374
                    $value = $this->build_url( $url );
375
                }
376
                elseif ( 'no-http' == pods_var( self::$type . '_format', $options ) ) {
377
                    $value = $this->build_url( $url );
378
                    $value = str_replace( trim( $url[ 'scheme' ] . '://', ':' ), '', $value );
379
    
380
                    if ( '/' == $url[ 'path' ] )
381
                        $value = trim( $value, '/' );
382
                }
383
                elseif ( 'no-http-no-www' == pods_var( self::$type . '_format', $options ) ) {
384
                    if ( 0 === strpos( $url[ 'host' ], 'www.' ) )
385
                        $url[ 'host' ] = substr( $url[ 'host' ], 4 );
386
    
387
                    $value = $this->build_url( $url );
388
                    $value = str_replace( trim( $url[ 'scheme' ] . '://', ':' ), '', $value );
389
    
390
                    if ( '/' == $url[ 'path' ] )
391
                        $value = trim( $value, '/' );
392
                }
393
                elseif ( 'no-http-force-www' == pods_var( self::$type . '_format', $options ) ) {
394
                    if ( false !== strpos( $url[ 'host' ], '.' ) && false === strpos( $url[ 'host' ], '.', 1 ) )
395
                        $url[ 'host' ] = 'www.' . $url[ 'host' ];
396
    
397
                    $value = $this->build_url( $url );
398
                    $value = str_replace( trim( $url[ 'scheme' ] . '://', ':' ), '', $value );
399
    
400
                    if ( '/' == $url[ 'path' ] )
401
                        $value = trim( $value, '/' );
402
                }
403
            }
404
        } else {
405
            $value = $this->strip_html( $value, $options );
406
        }
407
408
        $value = esc_url( $value );
409
410
        return $value;
411
    }
412
413
    /**
414
     * Validate an targit attribute with the options
415
     *
416
     * @param string $value
417
     * @param array $options
418
     *
419
     * @since 2.0
420
     */
421
    public function validate_target( $value, $options = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $options 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...
422
        if ( ! empty( $value ) && $value == '_blank' ) {
423
            $value = '_blank';
424
        } else {
425
            $value = '';
426
        }
427
        return $value;
428
    }
429
430
    /**
431
     * Build an url
432
     *
433
     * @param array|string $url
434
     *
435
     * @return string
436
     */
437 View Code Duplication
    public function build_url ( $url ) {
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...
438
        if ( function_exists( 'http_build_url' ) )
439
            return http_build_url( $url );
440
441
        $defaults = array(
442
            'scheme' => 'http',
443
            'host' => '',
444
            'path' => '/',
445
            'query' => '',
446
            'fragment' => ''
447
        );
448
449
        $url = array_merge( $defaults, (array) $url );
450
451
        $new_url = trim( $url[ 'scheme' ] . '://', ':' ) . $url[ 'host' ] . '/' . ltrim( $url[ 'path' ], '/' );
452
453
        if ( !empty( $url[ 'query' ] ) )
454
            $new_url .= '?' . ltrim( $url[ 'query' ], '?' );
455
456
        if ( !empty( $url[ 'fragment' ] ) )
457
            $new_url .= '#' . ltrim( $url[ 'fragment' ], '#' );
458
459
        return $new_url;
460
    }
461
	
462
463
    /**
464
     * Strip HTML based on options
465
     *
466
     * @param string $value
467
     * @param array $options
468
     *
469
     * @return string
470
     */
471 View Code Duplication
    public function strip_html ( $value, $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...
472
        if ( is_array( $value ) )
473
            $value = @implode( ' ', $value );
474
475
        $value = trim( $value );
476
477
        if ( empty( $value ) )
478
            return $value;
479
480
        $options = (array) $options;
481
482
        if ( 1 == pods_var( self::$type . '_allow_html', $options, 0, null, true ) ) {
483
            $allowed_html_tags = '';
484
485
            if ( 0 < strlen( pods_var( self::$type . '_allowed_html_tags', $options ) ) ) {
486
                $allowed_html_tags = explode( ' ', trim( pods_var( self::$type . '_allowed_html_tags', $options ) ) );
487
                $allowed_html_tags = '<' . implode( '><', $allowed_html_tags ) . '>';
488
            }
489
490
            if ( !empty( $allowed_html_tags ) && '<>' != $allowed_html_tags )
491
                $value = strip_tags( $value, $allowed_html_tags );
492
        }
493
        else
494
            $value = strip_tags( $value );
495
496
        return $value;
497
    }
498
499
}
500