Passed
Push — master ( de7162...f256de )
by Brian
739:27 queued 623:54
created

AUI_Component_Input::input()   F

Complexity

Conditions 39
Paths > 20000

Size

Total Lines 191
Code Lines 101

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 39
eloc 101
c 1
b 0
f 1
nc 13271041
nop 1
dl 0
loc 191
rs 0

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
if ( ! defined( 'ABSPATH' ) ) {
4
	exit; // Exit if accessed directly
5
}
6
7
/**
8
 * A component class for rendering a bootstrap alert.
9
 *
10
 * @since 1.0.0
11
 */
12
class AUI_Component_Input {
13
14
	/**
15
	 * Build the component.
16
	 *
17
	 * @param array $args
18
	 *
19
	 * @return string The rendered component.
20
	 */
21
	public static function input($args = array()){
22
		$defaults = array(
23
			'type'       => 'text',
24
			'name'       => '',
25
			'class'      => '',
26
			'id'         => '',
27
			'placeholder'=> '',
28
			'title'      => '',
29
			'value'      => '',
30
			'required'   => false,
31
			'label'      => '',
32
			'label_after'=> false,
33
			'label_class'=> '',
34
			'validation_text'   => '',
35
			'validation_pattern' => '',
36
			'no_wrap'    => false,
37
			'input_group_right' => '',
38
			'input_group_left' => '',
39
			'input_group_right_inside' => false, // forces the input group inside the input
40
			'input_group_left_inside' => false, // forces the input group inside the input
41
			'step'       => '',
42
			'switch'     => false, // to show checkbox as a switch
43
			'checked'   => false, // set a checkbox or radio as selected
44
			'password_toggle' => true, // toggle view/hide password
45
			'extra_attributes'  => array() // an array of extra attributes
46
		);
47
48
		/**
49
		 * Parse incoming $args into an array and merge it with $defaults
50
		 */
51
		$args   = wp_parse_args( $args, $defaults );
52
		$output = '';
53
		if ( ! empty( $args['type'] ) ) {
54
			$type = sanitize_html_class( $args['type'] );
55
			$label_args = array('title'=>$args['label'],'for'=>$args['id'],'class' => $args['label_class']." ");
56
			
57
			// Some special sauce for files
58
			if($type=='file' ){
59
				$args['label_after'] = true; // if type file we need the label after
60
				$args['class'] .= ' custom-file-input ';
61
			}elseif($type=='checkbox'){
62
				$args['label_after'] = true; // if type file we need the label after
63
				$args['class'] .= ' custom-control-input ';
64
			}
65
66
67
			// label before
68
			if(!empty($args['label']) && !$args['label_after']){
69
				if($type == 'file'){$label_args['class'] .= 'custom-file-label';}
70
				$output .= self::label( $label_args, $type );
71
			}
72
73
			// open/type
74
			$output .= '<input type="' . $type . '" ';
75
76
			// name
77
			if(!empty($args['name'])){
78
				$output .= ' name="'.sanitize_html_class($args['name']).'" ';
79
			}
80
81
			// id
82
			if(!empty($args['id'])){
83
				$output .= ' id="'.sanitize_html_class($args['id']).'" ';
84
			}
85
86
			// placeholder
87
			if(!empty($args['placeholder'])){
88
				$output .= ' placeholder="'.esc_attr($args['placeholder']).'" ';
89
			}
90
91
			// title
92
			if(!empty($args['title'])){
93
				$output .= ' title="'.esc_attr($args['title']).'" ';
94
			}
95
96
			// value
97
			if(!empty($args['value'])){
98
				$output .= ' value="'.sanitize_text_field($args['value']).'" ';
99
			}
100
101
			// checked, for radio and checkboxes
102
			if( ( $type == 'checkbox' || $type == 'radio' ) && $args['checked'] ){
103
				$output .= ' checked ';
104
			}
105
106
			// validation text
107
			if(!empty($args['validation_text'])){
108
				$output .= ' oninvalid="setCustomValidity(\''.esc_attr($args['validation_text']).'\')" ';
109
				$output .= ' onchange="try{setCustomValidity(\'\')}catch(e){}" ';
110
			}
111
112
			// validation_pattern
113
			if(!empty($args['validation_pattern'])){
114
				$output .= ' pattern="'.$args['validation_pattern'].'" ';
115
			}
116
117
			// step (for numbers)
118
			if(!empty($args['step'])){
119
				$output .= ' step="'.$args['step'].'" ';
120
			}
121
122
			// required
123
			if(!empty($args['required'])){
124
				$output .= ' required ';
125
			}
126
127
			// class
128
			$class = !empty($args['class']) ? $args['class'] : '';
129
			$output .= ' class="form-control '.$class.'" ';
130
131
			// data-attributes
132
			$output .= AUI_Component_Helper::data_attributes($args);
133
134
			// extra attributes
135
			if(!empty($args['extra_attributes'])){
136
				$output .= AUI_Component_Helper::extra_attributes($args['extra_attributes']);
137
			}
138
139
			// close
140
			$output .= ' >';
141
142
			// label after
143
			if(!empty($args['label']) && $args['label_after']){
144
				if($type == 'file'){$label_args['class'] .= 'custom-file-label';}
145
				elseif($type == 'checkbox'){$label_args['class'] .= 'custom-control-label';}
146
				$output .= self::label( $label_args, $type );
147
			}
148
149
			
150
			// some input types need a separate wrap
151
			if($type == 'file') {
152
				$output = self::wrap( array(
153
					'content' => $output,
154
					'class'   => 'form-group custom-file'
155
				) );
156
			}elseif($type == 'checkbox'){
157
				$wrap_class = $args['switch'] ? 'custom-switch' : 'custom-checkbox';
158
				$output = self::wrap( array(
159
					'content' => $output,
160
					'class'   => 'custom-control '.$wrap_class
161
				) );
162
			}elseif($type == 'password' && $args['password_toggle'] && !$args['input_group_right']){
163
164
165
				// allow password field to toggle view
166
				$args['input_group_right'] = '<span class="input-group-text c-pointer px-3" 
167
onclick="var $el = jQuery(this).find(\'i\');$el.toggleClass(\'fa-eye fa-eye-slash\');
168
var $eli = jQuery(this).parent().parent().find(\'input\');
169
if($el.hasClass(\'fa-eye\'))
170
{$eli.attr(\'type\',\'text\');}
171
else{$eli.attr(\'type\',\'password\');}"
172
><i class="far fa-fw fa-eye-slash"></i></span>';
173
			}
174
175
			// input group wraps
176
			if($args['input_group_left'] || $args['input_group_right']){
177
				$w100 = strpos($args['class'], 'w-100') !== false ? ' w-100' : '';
178
				if($args['input_group_left']){
179
					$output = self::wrap( array(
180
						'content' => $output,
181
						'class'   => $args['input_group_left_inside'] ? 'input-group-inside'.$w100  : 'input-group',
182
						'input_group_left' => $args['input_group_left'],
183
						'input_group_left_inside'    => $args['input_group_left_inside']
184
					) );
185
				}
186
				if($args['input_group_right']){
187
					$output = self::wrap( array(
188
						'content' => $output,
189
						'class'   => $args['input_group_right_inside'] ? 'input-group-inside'.$w100 : 'input-group',
190
						'input_group_right' => $args['input_group_right'],
191
						'input_group_right_inside'    => $args['input_group_right_inside']
192
					) );
193
				}
194
195
				// Labels need to be on the outside of the wrap
196
				$label = self::label( $label_args, $type );
197
				$output = $label . str_replace($label,"",$output);
198
			}
199
200
			// wrap
201
			if(!$args['no_wrap']){
202
				$output = self::wrap(array(
203
					'content' => $output,
204
				));
205
			}
206
207
208
209
		}
210
211
		return $output;
212
	}
213
214
	/**
215
	 * Build the component.
216
	 *
217
	 * @param array $args
218
	 *
219
	 * @return string The rendered component.
220
	 */
221
	public static function textarea($args = array()){
222
		$defaults = array(
223
			'name'       => '',
224
			'class'      => '',
225
			'id'         => '',
226
			'placeholder'=> '',
227
			'title'      => '',
228
			'value'      => '',
229
			'required'   => false,
230
			'label'      => '',
231
			'validation_text'   => '',
232
			'validation_pattern' => '',
233
			'no_wrap'    => false,
234
			'rows'      => '',
235
			'wysiwyg'   => false,
236
		);
237
238
		/**
239
		 * Parse incoming $args into an array and merge it with $defaults
240
		 */
241
		$args   = wp_parse_args( $args, $defaults );
242
		$output = '';
243
244
		// label
245
		if(!empty($args['label']) && is_array($args['label'])){
246
		}elseif(!empty($args['label'])){
247
			$output .= self::label(array('title'=>$args['label'],'for'=>$args['id']));
248
		}
249
250
		if(!empty($args['wysiwyg'])){
251
			ob_start();
252
			$content = $args['value'];
253
			$editor_id = !empty($args['id']) ? sanitize_html_class($args['id']) : 'wp_editor';
254
			$settings = array(
255
				'textarea_rows' => !empty(absint($args['rows'])) ? absint($args['rows']) : 4,
256
				'quicktags'     => false,
257
				'media_buttons' => false,
258
				'editor_class'  => 'form-control',
259
				'textarea_name' => !empty($args['name']) ? sanitize_html_class($args['name']) : sanitize_html_class($args['id']),
260
				'teeny'         => true,
261
			);
262
263
			// maybe set settings if array
264
			if(is_array($args['wysiwyg'])){
265
				$settings  = wp_parse_args( $args['wysiwyg'], $settings );
266
			}
267
268
			wp_editor( $content, $editor_id, $settings );
269
			$output .= ob_get_clean();
270
		}else{
271
272
			// open
273
			$output .= '<textarea ';
274
275
			// name
276
			if(!empty($args['name'])){
277
				$output .= ' name="'.sanitize_html_class($args['name']).'" ';
278
			}
279
280
			// id
281
			if(!empty($args['id'])){
282
				$output .= ' id="'.sanitize_html_class($args['id']).'" ';
283
			}
284
285
			// placeholder
286
			if(!empty($args['placeholder'])){
287
				$output .= ' placeholder="'.esc_attr($args['placeholder']).'" ';
288
			}
289
290
			// title
291
			if(!empty($args['title'])){
292
				$output .= ' title="'.esc_attr($args['title']).'" ';
293
			}
294
295
			// validation text
296
			if(!empty($args['validation_text'])){
297
				$output .= ' oninvalid="setCustomValidity(\''.esc_attr($args['validation_text']).'\')" ';
298
				$output .= ' onchange="try{setCustomValidity(\'\')}catch(e){}" ';
299
			}
300
301
			// validation_pattern
302
			if(!empty($args['validation_pattern'])){
303
				$output .= ' pattern="'.$args['validation_pattern'].'" ';
304
			}
305
306
			// required
307
			if(!empty($args['required'])){
308
				$output .= ' required ';
309
			}
310
311
			// rows
312
			if(!empty($args['rows'])){
313
				$output .= ' rows="'.absint($args['rows']).'" ';
314
			}
315
316
317
			// class
318
			$class = !empty($args['class']) ? $args['class'] : '';
319
			$output .= ' class="form-control '.$class.'" ';
320
321
322
			// close tag
323
			$output .= ' >';
324
325
			// value
326
			if(!empty($args['value'])){
327
				$output .= sanitize_textarea_field($args['value']);
328
			}
329
330
			// closing tag
331
			$output .= '</textarea>';
332
333
		}
334
335
336
		// wrap
337
		if(!$args['no_wrap']){
338
			$output = self::wrap(array(
339
				'content' => $output,
340
			));
341
		}
342
343
344
345
346
347
		return $output;
348
	}
349
350
	public static function label($args = array(), $type = ''){
351
		//<label for="exampleInputEmail1">Email address</label>
352
		$defaults = array(
353
			'title'       => 'div',
354
			'for'      => '',
355
			'class'      => '',
356
		);
357
358
		/**
359
		 * Parse incoming $args into an array and merge it with $defaults
360
		 */
361
		$args   = wp_parse_args( $args, $defaults );
362
		$output = '';
363
364
		if($args['title']){
365
366
			// maybe hide labels //@todo set a global option for visibility class
367
			if($type == 'file' || $type == 'checkbox'){
368
				$class = $args['class'];
369
			}else{
370
				$class = 'sr-only '.$args['class'];
371
			}
372
373
374
			// open
375
			$output .= '<label ';
376
377
			// for
378
			if(!empty($args['for'])){
379
				$output .= ' for="'.sanitize_text_field($args['for']).'" ';
380
			}
381
382
			// class
383
			$output .= ' class="'.$class.'" ';
384
385
			// close
386
			$output .= '>';
387
388
389
			// title
390
			if(!empty($args['title'])){
391
				$output .= esc_attr($args['title']);
392
			}
393
394
			// close wrap
395
			$output .= '</label>';
396
397
398
		}
399
400
401
		return $output;
402
	}
403
404
	public static function wrap($args = array()){
405
		$defaults = array(
406
			'type'       => 'div',
407
			'class'      => 'form-group',
408
			'content'   => '',
409
			'input_group_left' => '',
410
			'input_group_right' => '',
411
			'input_group_left_inside' => false,
412
			'input_group_right_inside' => false,
413
		);
414
415
		/**
416
		 * Parse incoming $args into an array and merge it with $defaults
417
		 */
418
		$args   = wp_parse_args( $args, $defaults );
419
		$output = '';
420
		if($args['type']){
421
422
			// open
423
			$output .= '<'.sanitize_html_class($args['type']);
424
425
			// class
426
			$class = !empty($args['class']) ? $args['class'] : '';
427
			$output .= ' class="'.$class.'" ';
428
429
			// close wrap
430
			$output .= ' >';
431
432
433
			// Input group left
434
			if(!empty($args['input_group_left'])){
435
				$position_class = !empty($args['input_group_left_inside']) ? 'position-absolute' : '';
436
				$input_group_left = strpos($args['input_group_left'], '<') !== false ? $args['input_group_left'] : '<span class="input-group-text">'.$args['input_group_left'].'</span>';
437
				$output .= '<div class="input-group-prepend '.$position_class.'">'.$input_group_left.'</div>';
438
			}
439
440
			// content
441
			$output .= $args['content'];
442
443
			// Input group right
444
			if(!empty($args['input_group_right'])){
445
				$position_class = !empty($args['input_group_left_inside']) ? 'position-absolute' : '';
446
				$input_group_right = strpos($args['input_group_right'], '<') !== false ? $args['input_group_right'] : '<span class="input-group-text">'.$args['input_group_right'].'</span>';
447
				$output .= '<div class="input-group-append '.$position_class.'">'.$input_group_right.'</div>';
448
			}
449
450
451
			// close wrap
452
			$output .= '</'.sanitize_html_class($args['type']).'>';
453
454
455
		}else{
456
			$output = $args['content'];
457
		}
458
459
		return $output;
460
	}
461
462
	/**
463
	 * Build the component.
464
	 *
465
	 * @param array $args
466
	 *
467
	 * @return string The rendered component.
468
	 */
469
	public static function select($args = array()){
470
		$defaults = array(
471
			'class'      => '',
472
			'id'         => '',
473
			'title'      => '',
474
			'value'      => '', // can be an array or a string
475
			'required'   => false,
476
			'label'      => '',
477
			'placeholder'=> '',
478
			'options'    => array(),
479
			'icon'       => '',
480
			'multiple'   => false,
481
			'select2'    => false,
482
			'no_wrap'    => false,
483
		);
484
485
		/**
486
		 * Parse incoming $args into an array and merge it with $defaults
487
		 */
488
		$args   = wp_parse_args( $args, $defaults );
489
		$output = '';
490
491
		// Maybe setup select2
492
		$is_select2 = false;
493
		if(!empty($args['select2'])){
494
			$args['class'] .= ' aui-select2';
495
			$is_select2 = true;
496
		}elseif( strpos($args['class'], 'aui-select2') !== false){
497
			$is_select2 = true;
498
		}
499
500
		// select2 tags
501
		if( !empty($args['select2']) && $args['select2'] === 'tags'){ // triple equlas needed here for some reason
502
			$args['data-tags'] = 'true';
503
			$args['data-token-separators'] = "[',']";
504
			$args['multiple'] = true;
505
		}
506
507
		// select2 placeholder
508
		if($is_select2 && !empty($args['placeholder']) && empty($args['data-placeholder'])){
509
			$args['data-placeholder'] = esc_attr($args['placeholder']);
510
			$args['data-allow-clear'] = empty($args['data-allow-clear']) ? true : esc_attr($args['data-allow-clear']);
511
		}
512
513
		// label
514
		if(!empty($args['label']) && is_array($args['label'])){
515
		}elseif(!empty($args['label'])){
516
			$output .= self::label(array('title'=>$args['label'],'for'=>$args['id']));
517
		}
518
519
		// open/type
520
		$output .= '<select ';
521
522
		// class
523
		$class = !empty($args['class']) ? $args['class'] : '';
524
		$output .= AUI_Component_Helper::class_attr('custom-select '.$class);
525
526
		// name
527
		if(!empty($args['name'])){
528
			$output .= AUI_Component_Helper::name($args['name'],$args['multiple']);
529
		}
530
531
		// id
532
		if(!empty($args['id'])){
533
			$output .= AUI_Component_Helper::id($args['id']);
534
		}
535
536
		// title
537
		if(!empty($args['title'])){
538
			$output .= AUI_Component_Helper::title($args['title']);
539
		}
540
541
		// data-attributes
542
		$output .= AUI_Component_Helper::data_attributes($args);
543
544
		// aria-attributes
545
		$output .= AUI_Component_Helper::aria_attributes($args);
546
547
		// required
548
		if(!empty($args['required'])){
549
			$output .= ' required ';
550
		}
551
552
		// multiple
553
		if(!empty($args['multiple'])){
554
			$output .= ' multiple ';
555
		}
556
557
		// close opening tag
558
		$output .= ' >';
559
560
		// placeholder
561
		if(!empty($args['placeholder']) && !$is_select2){
562
			$output .= '<option value="" disabled selected hidden>'.esc_attr($args['placeholder']).'</option>';
563
		}
564
565
		// Options
566
		if(!empty($args['options'])){
567
			foreach($args['options'] as $val => $name){
568
				if(is_array($name)){
569
					if (isset($name['optgroup']) && ($name['optgroup'] == 'start' || $name['optgroup'] == 'end')) {
570
						$option_label = isset($name['label']) ? $name['label'] : '';
571
572
						$output .= $name['optgroup'] == 'start' ? '<optgroup label="' . esc_attr($option_label) . '">' : '</optgroup>';
573
					} else {
574
						$option_label = isset($name['label']) ? $name['label'] : '';
575
						$option_value = isset($name['value']) ? $name['value'] : '';
576
577
						if(!empty($args['multiple']) && !empty($args['value'])){
578
							$selected = in_array($option_value, stripslashes_deep($args['value'])) ? "selected" : "";
0 ignored issues
show
Bug introduced by
It seems like stripslashes_deep($args['value']) can also be of type object; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

578
							$selected = in_array($option_value, /** @scrutinizer ignore-type */ stripslashes_deep($args['value'])) ? "selected" : "";
Loading history...
579
						} else {
580
							$selected = selected($option_value,stripslashes_deep($args['value']), false);
581
						}
582
583
						$output .= '<option value="' . esc_attr($option_value) . '" ' . $selected . '>' . $option_label . '</option>';
584
					}
585
				}else{
586
					$selected = '';
587
					if(!empty($args['value'])){
588
						if(is_array($args['value'])){
589
							$selected = in_array($val,$args['value']) ? 'selected="selected"' : '';
590
						}else{
591
							$selected = selected( $args['value'], $val, false);
592
						}
593
					}
594
					$output .= '<option value="'.esc_attr($val).'" '.$selected.'>'.esc_attr($name).'</option>';	
595
				}
596
			}
597
598
		}
599
600
		// closing tag
601
		$output .= '</select>';
602
603
		// wrap
604
		if(!$args['no_wrap']){
605
			$output = self::wrap(array(
606
				'content' => $output,
607
			));
608
		}
609
610
611
		return $output;
612
	}
613
614
}