Completed
Pull Request — 2.x (#4068)
by Jory
04:54
created

PodsField_Website   C

Complexity

Total Complexity 65

Size/Duplication

Total Lines 477
Duplicated Lines 14.26 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 68
loc 477
rs 5.7894
c 0
b 0
f 0
wmc 65
lcom 1
cbo 2

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A options() 0 60 1
A schema() 10 10 3
A display() 0 18 4
B input() 0 26 6
B validate() 23 23 6
B pre_save() 0 22 5
A ui() 0 5 1
D validate_url() 8 80 24
C strip_html() 27 27 7
A validate_target() 0 8 3
B build_url() 0 24 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like PodsField_Website often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PodsField_Website, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package Pods\Fields
4
 */
5
class PodsField_Website 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 = 'website';
22
23
	/**
24
	 * Field Type Label
25
	 *
26
	 * @var string
27
	 * @since 2.0
28
	 */
29
	public static $label = 'Website';
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
		self::$label = __( 'Website', 'pods' );
47
48
	}
49
50
	/**
51
	 * Add options and set defaults to
52
	 *
53
	 * @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...
54
	 *
55
	 * @since 2.0
56
	 */
57
	public function options () {
58
		$options = array(
59
			self::$type . '_repeatable' => array(
60
				'label' => __( 'Repeatable Field', 'pods' ),
61
				'default' => 0,
62
				'type' => 'boolean',
63
				'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' ),
64
				'boolean_yes_label' => '',
65
				'dependency' => true,
66
				'developer_mode' => true
67
			),
68
			self::$type . '_format' => array(
69
				'label' => __( 'Format', 'pods' ),
70
				'default' => 'normal',
71
				'type' => 'pick',
72
				'data' => array(
73
					'normal' => __( 'http://example.com/', 'pods' ),
74
					'no-www' => __( 'http://example.com/ (remove www)', 'pods' ),
75
					'force-www' => __( 'http://www.example.com/ (force www if no sub-domain provided)', 'pods' ),
76
					'no-http' => __( 'example.com', 'pods' ),
77
					'no-http-no-www' => __( 'example.com (force removal of www)', 'pods' ),
78
					'no-http-force-www' => __( 'www.example.com (force www if no sub-domain provided)', 'pods' )
79
				)
80
			),
81
			self::$type . '_clickable' => array(
82
				'label' => __( 'Output as a link?', 'pods' ),
83
				'default' => apply_filters( 'pods_form_ui_field_website_clickable', 0, self::$type ),
84
				'type' => 'boolean',
85
				'dependency' => true,
86
			),
87
			self::$type . '_new_window' => array(
88
				'label' => __( 'Open link in new window?', 'pods' ),
89
				'default' => apply_filters( 'pods_form_ui_field_website_new_window', 0, self::$type ),
90
				'type' => 'boolean',
91
				'depends-on' => array( self::$type . '_clickable' => true ),
92
			),
93
			self::$type . '_max_length' => array(
94
				'label' => __( 'Maximum Length', 'pods' ),
95
				'default' => 255,
96
				'type' => 'number',
97
				'help' => __( 'Set to -1 for no limit', 'pods' )
98
			),
99
			self::$type . '_html5' => array(
100
				'label' => __( 'Enable HTML5 Input Field?', 'pods' ),
101
				'default' => apply_filters( 'pods_form_ui_field_html5', 0, self::$type ),
102
				'type' => 'boolean'
103
			)/*,
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...
104
			self::$type . '_size' => array(
105
				'label' => __( 'Field Size', 'pods' ),
106
				'default' => 'medium',
107
				'type' => 'pick',
108
				'data' => array(
109
					'small' => __( 'Small', 'pods' ),
110
					'medium' => __( 'Medium', 'pods' ),
111
					'large' => __( 'Large', 'pods' )
112
				)
113
			)*/
114
		);
115
		return $options;
116
	}
117
118
	/**
119
	 * Define the current field's schema for DB table storage
120
	 *
121
	 * @param array $options
122
	 *
123
	 * @return array
124
	 * @since 2.0
125
	 */
126 View Code Duplication
	public function schema ( $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...
127
		$length = (int) pods_var( self::$type . '_max_length', $options, 255 );
128
129
		$schema = 'VARCHAR(' . $length . ')';
130
131
		if ( 255 < $length || $length < 1 )
132
			$schema = 'LONGTEXT';
133
134
		return $schema;
135
	}
136
137
	/**
138
	 * Change the way the value of the field is displayed with Pods::get
139
	 *
140
	 * @param mixed $value
141
	 * @param string $name
142
	 * @param array $options
143
	 * @param array $pod
144
	 * @param int $id
145
	 *
146
	 * @return mixed|null
147
	 * @since 2.0
148
	 */
149
	public function display ( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
150
		// Ensure proper format
151
		$value = $this->pre_save( $value, $id, $name, $options, null, $pod );
152
153
		if ( 1 == pods_v( self::$type . '_clickable', $options ) && 0 < strlen( $value ) ) {
154
			$link = '<a href="%s"%s>%s</a>';
155
156
			$atts = '';
157
158
			if ( 1 == pods_v( self::$type . '_new_window', $options ) ) {
159
				$atts .= ' target="_blank"';
160
			}
161
162
			$value = sprintf( $link, esc_url( $value ), $atts, esc_html( $value ) );
163
		}
164
165
		return $value;
166
	}
167
168
	/**
169
	 * Customize output of the form field
170
	 *
171
	 * @param string $name
172
	 * @param mixed $value
173
	 * @param array $options
174
	 * @param array $pod
175
	 * @param int $id
176
	 *
177
	 * @since 2.0
178
	 */
179
	public function input ( $name, $value = null, $options = null, $pod = null, $id = null ) {
180
		$options = (array) $options;
181
		$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...
182
183
		// Ensure proper format
184
		$value = $this->pre_save( $value, $id, $name, $options, null, $pod );
185
186
		$field_type = 'website';
187
188
		if ( isset( $options[ 'name' ] ) && false === PodsForm::permission( self::$type, $options[ 'name' ], $options, null, $pod, $id ) ) {
189
			if ( pods_var( 'read_only', $options, false ) ) {
190
				$options[ 'readonly' ] = true;
191
192
				$field_type = 'text';
193
			}
194
			else
195
				return;
196
		}
197
		elseif ( !pods_has_permissions( $options ) && pods_var( 'read_only', $options, false ) ) {
198
			$options[ 'readonly' ] = true;
199
200
			$field_type = 'text';
201
		}
202
203
		pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
204
	}
205
206
	/**
207
	 * Validate a value before it's saved
208
	 *
209
	 * @param mixed $value
210
	 * @param string $name
211
	 * @param array $options
212
	 * @param array $fields
213
	 * @param array $pod
214
	 * @param int $id
215
	 *
216
	 * @return bool|array
217
	 *
218
	 * @since 2.0
219
	 */
220 View Code Duplication
	public function validate ( $value, $name = null, $options = null, $fields = null, $pod = null, $id = 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...
221
		$errors = array();
222
223
		$label = strip_tags( pods_var_raw( 'label', $options, ucwords( str_replace( '_', ' ', $name ) ) ) );
224
225
		$check = $this->pre_save( $value, $id, $name, $options, $fields, $pod, $params );
226
227
		if ( is_array( $check ) )
228
			$errors = $check;
229
		else {
230
			if ( 0 < strlen( $value ) && strlen( $check ) < 1 ) {
231
				if ( 1 == pods_var( 'required', $options ) )
232
					$errors[] = sprintf( __( 'The %s field is required.', 'pods' ), $label );
233
				else
234
					$errors[] = sprintf( __( 'Invalid website provided for the field %s.', 'pods' ), $label );
235
			}
236
		}
237
238
		if ( !empty( $errors ) )
239
			return $errors;
240
241
		return true;
242
	}
243
244
	/**
245
	 * Change the value or perform actions after validation but before saving to the DB
246
	 *
247
	 * @param mixed $value
248
	 * @param int $id
249
	 * @param string $name
250
	 * @param array $options
251
	 * @param array $fields
252
	 * @param array $pod
253
	 * @param object $params
254
	 *
255
	 * @return string
256
	 *
257
	 * @since 2.0
258
	 */
259
	public function pre_save ( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
260
		$options = (array) $options;
261
262
		// Update from a array input field (like link) if the field updates
263
		if ( is_array( $value ) ) {
264
			if ( isset( $value['url'] ) ) {
265
				$value = $value['url'];
266
			} else {
267
				$value = implode( ' ', $value );
268
			}
269
		}
270
271
		$value = $this->validate_url( $value, $options );
272
273
		$length = (int) pods_var( self::$type . '_max_length', $options, 255 );
274
275
		if ( 0 < $length && $length < pods_mb_strlen( $value ) ) {
276
			$value = pods_mb_substr( $value, 0, $length );
277
		}
278
279
		return $value;
280
	}
281
282
	/**
283
	 * Customize the Pods UI manage table column output
284
	 *
285
	 * @param int $id
286
	 * @param mixed $value
287
	 * @param string $name
288
	 * @param array $options
289
	 * @param array $fields
290
	 * @param array $pod
291
	 *
292
	 * @return string
293
	 *
294
	 * @since 2.0
295
	 */
296
	public function ui ( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) {
297
		$value = $this->display( $value, $name, $options, $pod, $id );
298
299
		return $value;
300
	}
301
302
	/**
303
	 * Validate an URL with the options
304
	 *
305
	 * @param string $value
306
	 * @param array $options
307
	 *
308
	 * @return string
309
	 *
310
	 * @since 2.7
311
	 */
312
	public function validate_url( $value, $options = null ) {
313
		if ( empty( $value ) )
314
			return $value;
315
316
		if ( 'none' != pods_var( self::$type . '_format', $options ) ) {
317
			if ( is_array( $value ) ) {
318
				if ( isset( $value[ 'scheme' ] ) )
319
					$value = $this->build_url( $value );
320
				else
321
					$value = implode( '', $value );
322
			}
323
324
			if ( false === strpos( $value, '://' ) && 0 !== strpos( $value, '//' ) )
325
				$value = 'http://' . $value;
326
327
			$url = @parse_url( $value );
328
329
			if ( empty( $url ) || count( $url ) < 2 )
330
				$value = '';
331
			else {
332
				$defaults = array(
333
					'scheme' => 'http',
334
					'host' => '',
335
					'path' => '/',
336
					'query' => '',
337
					'fragment' => ''
338
				);
339
340
				$url = array_merge( $defaults, $url );
341
342
				if ( 'normal' == pods_var( self::$type . '_format', $options ) )
343
					$value = $this->build_url( $url );
344
				elseif ( 'no-www' == pods_var( self::$type . '_format', $options ) ) {
345 View Code Duplication
					if ( 0 === strpos( $url[ 'host' ], 'www.' ) )
346
						$url[ 'host' ] = substr( $url[ 'host' ], 4 );
347
348
					$value = $this->build_url( $url );
349
				}
350
				elseif ( 'force-www' == pods_var( self::$type . '_format', $options ) ) {
351 View Code Duplication
					if ( false !== strpos( $url[ 'host' ], '.' ) && false === strpos( $url[ 'host' ], '.', 1 ) )
352
						$url[ 'host' ] = 'www.' . $url[ 'host' ];
353
354
					$value = $this->build_url( $url );
355
				}
356
				elseif ( 'no-http' == pods_var( self::$type . '_format', $options ) ) {
357
					$value = $this->build_url( $url );
358
					$value = str_replace( trim( $url[ 'scheme' ] . '://', ':' ), '', $value );
359
360
					if ( '/' == $url[ 'path' ] )
361
						$value = trim( $value, '/' );
362
				}
363
				elseif ( 'no-http-no-www' == pods_var( self::$type . '_format', $options ) ) {
364 View Code Duplication
					if ( 0 === strpos( $url[ 'host' ], 'www.' ) )
365
						$url[ 'host' ] = substr( $url[ 'host' ], 4 );
366
367
					$value = $this->build_url( $url );
368
					$value = str_replace( trim( $url[ 'scheme' ] . '://', ':' ), '', $value );
369
370
					if ( '/' == $url[ 'path' ] )
371
						$value = trim( $value, '/' );
372
				}
373
				elseif ( 'no-http-force-www' == pods_var( self::$type . '_format', $options ) ) {
374 View Code Duplication
					if ( false !== strpos( $url[ 'host' ], '.' ) && false === strpos( $url[ 'host' ], '.', 1 ) )
375
						$url[ 'host' ] = 'www.' . $url[ 'host' ];
376
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
			}
384
		} else {
385
			$value = $this->strip_html( $value, $options );
386
		}
387
388
		$value = esc_url( $value );
389
390
		return $value;
391
	}
392
393
	/**
394
	 * Strip HTML based on options
395
	 *
396
	 * @param string $value
397
	 * @param array $options
398
	 *
399
	 * @return string
400
	 *
401
	 * @since 2.7
402
	 */
403 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...
404
		if ( is_array( $value ) )
405
			$value = @implode( ' ', $value );
406
407
		$value = trim( $value );
408
409
		if ( empty( $value ) )
410
			return $value;
411
412
		$options = (array) $options;
413
414
		if ( 1 == pods_var( self::$type . '_allow_html', $options, 0, null, true ) ) {
415
			$allowed_html_tags = '';
416
417
			if ( 0 < strlen( pods_var( self::$type . '_allowed_html_tags', $options ) ) ) {
418
				$allowed_html_tags = explode( ' ', trim( pods_var( self::$type . '_allowed_html_tags', $options ) ) );
419
				$allowed_html_tags = '<' . implode( '><', $allowed_html_tags ) . '>';
420
			}
421
422
			if ( !empty( $allowed_html_tags ) && '<>' != $allowed_html_tags )
423
				$value = strip_tags( $value, $allowed_html_tags );
424
		}
425
		else
426
			$value = strip_tags( $value );
427
428
		return $value;
429
	}
430
431
	/**
432
	 * Validate an target attribute with the options
433
	 *
434
	 * @param string $value
435
	 *
436
	 * @return string
437
	 *
438
	 * @since 2.7
439
	 */
440
	public function validate_target( $value ) {
441
		if ( ! empty( $value ) && $value == '_blank' ) {
442
			$value = '_blank';
443
		} else {
444
			$value = '';
445
		}
446
		return $value;
447
	}
448
449
	/**
450
	 * Build an url
451
	 *
452
	 * @param array|string $url
453
	 *
454
	 * @return string
455
	 */
456
	public function build_url ( $url ) {
457
		if ( function_exists( 'http_build_url' ) )
458
			return http_build_url( $url );
459
460
		$defaults = array(
461
			'scheme' => 'http',
462
			'host' => '',
463
			'path' => '/',
464
			'query' => '',
465
			'fragment' => ''
466
		);
467
468
		$url = array_merge( $defaults, (array) $url );
469
470
		$new_url = trim( $url[ 'scheme' ] . '://', ':' ) . $url[ 'host' ] . '/' . ltrim( $url[ 'path' ], '/' );
471
472
		if ( !empty( $url[ 'query' ] ) )
473
			$new_url .= '?' . ltrim( $url[ 'query' ], '?' );
474
475
		if ( !empty( $url[ 'fragment' ] ) )
476
			$new_url .= '#' . ltrim( $url[ 'fragment' ], '#' );
477
478
		return $new_url;
479
	}
480
481
}