Passed
Push — master ( 32890d...b6d11a )
by Brian
13:10
created

AUI_Component_Input   F

Complexity

Total Complexity 201

Size/Duplication

Total Lines 1052
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 543
dl 0
loc 1052
rs 2
c 0
b 0
f 0
wmc 201

7 Methods

Rating   Name   Duplication   Size   Complexity  
B label() 0 58 11
F wrap() 0 75 12
F textarea() 0 195 37
F input() 0 249 52
F radio_option() 0 104 17
F select() 0 231 61
C radio() 0 84 11

How to fix   Complexity   

Complex Class

Complex classes like AUI_Component_Input 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.

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 AUI_Component_Input, and based on these observations, apply Extract Interface, too.

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
			'wrap_class' => '',
27
			'id'         => '',
28
			'placeholder'=> '',
29
			'title'      => '',
30
			'value'      => '',
31
			'required'   => false,
32
			'label'      => '',
33
			'label_after'=> false,
34
			'label_class'=> '',
35
			'label_type' => '', // sets the label type, default: hidden. Options: hidden, top, horizontal, floating
36
			'help_text'  => '',
37
			'validation_text'   => '',
38
			'validation_pattern' => '',
39
			'no_wrap'    => false,
40
			'input_group_right' => '',
41
			'input_group_left' => '',
42
			'input_group_right_inside' => false, // forces the input group inside the input
43
			'input_group_left_inside' => false, // forces the input group inside the input
44
			'step'       => '',
45
			'switch'     => false, // to show checkbox as a switch
46
			'checked'   => false, // set a checkbox or radio as selected
47
			'password_toggle' => true, // toggle view/hide password
48
			'element_require'   => '', // [%element_id%] == "1"
49
			'extra_attributes'  => array(), // an array of extra attributes
50
			'wrap_attributes' => array()
51
		);
52
53
		/**
54
		 * Parse incoming $args into an array and merge it with $defaults
55
		 */
56
		$args   = wp_parse_args( $args, $defaults );
57
		$output = '';
58
		if ( ! empty( $args['type'] ) ) {
59
			// hidden label option needs to be empty
60
			$args['label_type'] = $args['label_type'] == 'hidden' ? '' : $args['label_type'];
61
62
			$type = sanitize_html_class( $args['type'] );
63
64
			$help_text = '';
65
			$label = '';
66
			$label_after = $args['label_after'];
67
			$label_args = array(
68
				'title'=> $args['label'],
69
				'for'=> $args['id'],
70
				'class' => $args['label_class']." ",
71
				'label_type' => $args['label_type']
72
			);
73
74
			// floating labels need label after
75
			if( $args['label_type'] == 'floating' && $type != 'checkbox' ){
76
				$label_after = true;
77
				$args['placeholder'] = ' '; // set the placeholder not empty so the floating label works.
78
			}
79
80
			// Some special sauce for files
81
			if($type=='file' ){
82
				$label_after = true; // if type file we need the label after
83
				$args['class'] .= ' custom-file-input ';
84
			}elseif($type=='checkbox'){
85
				$label_after = true; // if type file we need the label after
86
				$args['class'] .= ' custom-control-input ';
87
			}elseif($type=='datepicker' || $type=='timepicker'){
88
				$type = 'text';
89
				//$args['class'] .= ' aui-flatpickr bg-initial ';
90
				$args['class'] .= ' bg-initial ';
91
92
				$args['extra_attributes']['data-aui-init'] = 'flatpickr';
93
				// enqueue the script
94
				$aui_settings = AyeCode_UI_Settings::instance();
95
				$aui_settings->enqueue_flatpickr();
96
			}
97
98
99
			// open/type
100
			$output .= '<input type="' . $type . '" ';
101
102
			// name
103
			if(!empty($args['name'])){
104
				$output .= ' name="'.esc_attr($args['name']).'" ';
105
			}
106
107
			// id
108
			if(!empty($args['id'])){
109
				$output .= ' id="'.sanitize_html_class($args['id']).'" ';
110
			}
111
112
			// placeholder
113
			if(isset($args['placeholder']) && '' != $args['placeholder'] ){
114
				$output .= ' placeholder="'.esc_attr($args['placeholder']).'" ';
115
			}
116
117
			// title
118
			if(!empty($args['title'])){
119
				$output .= ' title="'.esc_attr($args['title']).'" ';
120
			}
121
122
			// value
123
			if(!empty($args['value'])){
124
				$output .= AUI_Component_Helper::value($args['value']);
125
			}
126
127
			// checked, for radio and checkboxes
128
			if( ( $type == 'checkbox' || $type == 'radio' ) && $args['checked'] ){
129
				$output .= ' checked ';
130
			}
131
132
			// validation text
133
			if(!empty($args['validation_text'])){
134
				$output .= ' oninvalid="setCustomValidity(\''.esc_attr($args['validation_text']).'\')" ';
135
				$output .= ' onchange="try{setCustomValidity(\'\')}catch(e){}" ';
136
			}
137
138
			// validation_pattern
139
			if(!empty($args['validation_pattern'])){
140
				$output .= ' pattern="'.$args['validation_pattern'].'" ';
141
			}
142
143
			// step (for numbers)
144
			if(!empty($args['step'])){
145
				$output .= ' step="'.$args['step'].'" ';
146
			}
147
148
			// required
149
			if(!empty($args['required'])){
150
				$output .= ' required ';
151
			}
152
153
			// class
154
			$class = !empty($args['class']) ? AUI_Component_Helper::esc_classes( $args['class'] ) : '';
155
			$output .= ' class="form-control '.$class.'" ';
156
157
			// data-attributes
158
			$output .= AUI_Component_Helper::data_attributes($args);
159
160
			// extra attributes
161
			if(!empty($args['extra_attributes'])){
162
				$output .= AUI_Component_Helper::extra_attributes($args['extra_attributes']);
163
			}
164
165
			// close
166
			$output .= ' >';
167
168
169
			// label
170
			if(!empty($args['label'])){
171
				if($type == 'file'){$label_args['class'] .= 'custom-file-label';}
172
				elseif($type == 'checkbox'){$label_args['class'] .= 'custom-control-label';}
173
				$label = self::label( $label_args, $type );
174
			}
175
176
			// help text
177
			if(!empty($args['help_text'])){
178
				$help_text = AUI_Component_Helper::help_text($args['help_text']);
179
			}
180
181
182
			// set help text in the correct possition
183
			if($label_after){
184
				$output .= $label . $help_text;
185
			}
186
187
			// some input types need a separate wrap
188
			if($type == 'file') {
189
				$output = self::wrap( array(
190
					'content' => $output,
191
					'class'   => 'form-group custom-file'
192
				) );
193
			}elseif($type == 'checkbox'){
194
				$wrap_class = $args['switch'] ? 'custom-switch' : 'custom-checkbox';
195
				$output = self::wrap( array(
196
					'content' => $output,
197
					'class'   => 'custom-control '.$wrap_class
198
				) );
199
200
				if($args['label_type']=='horizontal'){
201
					$output = '<div class="col-sm-2 col-form-label"></div><div class="col-sm-10">' . $output . '</div>';
202
				}
203
			}elseif($type == 'password' && $args['password_toggle'] && !$args['input_group_right']){
204
205
206
				// allow password field to toggle view
207
				$args['input_group_right'] = '<span class="input-group-text c-pointer px-3" 
208
onclick="var $el = jQuery(this).find(\'i\');$el.toggleClass(\'fa-eye fa-eye-slash\');
209
var $eli = jQuery(this).parent().parent().find(\'input\');
210
if($el.hasClass(\'fa-eye\'))
211
{$eli.attr(\'type\',\'text\');}
212
else{$eli.attr(\'type\',\'password\');}"
213
><i class="far fa-fw fa-eye-slash"></i></span>';
214
			}
215
216
			// input group wraps
217
			if($args['input_group_left'] || $args['input_group_right']){
218
				$w100 = strpos($args['class'], 'w-100') !== false ? ' w-100' : '';
219
				if($args['input_group_left']){
220
					$output = self::wrap( array(
221
						'content' => $output,
222
						'class'   => $args['input_group_left_inside'] ? 'input-group-inside position-relative'.$w100  : 'input-group',
223
						'input_group_left' => $args['input_group_left'],
224
						'input_group_left_inside'    => $args['input_group_left_inside']
225
					) );
226
				}
227
				if($args['input_group_right']){
228
					$output = self::wrap( array(
229
						'content' => $output,
230
						'class'   => $args['input_group_right_inside'] ? 'input-group-inside position-relative'.$w100 : 'input-group',
231
						'input_group_right' => $args['input_group_right'],
232
						'input_group_right_inside'    => $args['input_group_right_inside']
233
					) );
234
				}
235
236
			}
237
238
			if(!$label_after){
239
				$output .= $help_text;
240
			}
241
242
243
			if($args['label_type']=='horizontal' && $type != 'checkbox'){
244
				$output = self::wrap( array(
245
					'content' => $output,
246
					'class'   => 'col-sm-10',
247
				) );
248
			}
249
250
			if(!$label_after){
251
				$output = $label . $output;
252
			}
253
254
			// wrap
255
			if ( ! $args['no_wrap'] ) {
256
				$form_group_class = $args['label_type']=='floating' && $type != 'checkbox' ? 'form-label-group' : 'form-group';
257
				$wrap_class = $args['label_type']=='horizontal' ? $form_group_class . ' row' : $form_group_class;
258
				$wrap_class = !empty($args['wrap_class']) ? $wrap_class." ".$args['wrap_class'] : $wrap_class;
259
				$output = self::wrap(array(
260
					'content' => $output,
261
					'class'   => $wrap_class,
262
					'element_require'   => $args['element_require'],
263
					'argument_id'  => $args['id'],
264
					'wrap_attributes' => $args['wrap_attributes'],
265
				));
266
			}
267
		}
268
269
		return $output;
270
	}
271
272
	/**
273
	 * Build the component.
274
	 *
275
	 * @param array $args
276
	 *
277
	 * @return string The rendered component.
278
	 */
279
	public static function textarea($args = array()){
280
		$defaults = array(
281
			'name'       => '',
282
			'class'      => '',
283
			'wrap_class' => '',
284
			'id'         => '',
285
			'placeholder'=> '',
286
			'title'      => '',
287
			'value'      => '',
288
			'required'   => false,
289
			'label'      => '',
290
			'label_after'=> false,
291
			'label_class'      => '',
292
			'label_type' => '', // sets the label type, default: hidden. Options: hidden, top, horizontal, floating
293
			'help_text'  => '',
294
			'validation_text'   => '',
295
			'validation_pattern' => '',
296
			'no_wrap'    => false,
297
			'rows'      => '',
298
			'wysiwyg'   => false,
299
			'allow_tags' => false, // Allow HTML tags
300
			'element_require'   => '', // [%element_id%] == "1"
301
			'extra_attributes'  => array(), // an array of extra attributes
302
			'wrap_attributes'   => array(),
303
		);
304
305
		/**
306
		 * Parse incoming $args into an array and merge it with $defaults
307
		 */
308
		$args   = wp_parse_args( $args, $defaults );
309
		$output = '';
310
311
		// hidden label option needs to be empty
312
		$args['label_type'] = $args['label_type'] == 'hidden' ? '' : $args['label_type'];
313
314
		// floating labels don't work with wysiwyg so set it as top
315
		if($args['label_type'] == 'floating' && !empty($args['wysiwyg'])){
316
			$args['label_type'] = 'top';
317
		}
318
319
		$label_after = $args['label_after'];
320
321
		// floating labels need label after
322
		if( $args['label_type'] == 'floating' && empty($args['wysiwyg']) ){
323
			$label_after = true;
324
			$args['placeholder'] = ' '; // set the placeholder not empty so the floating label works.
325
		}
326
327
		// label
328
		if(!empty($args['label']) && is_array($args['label'])){
329
		}elseif(!empty($args['label']) && !$label_after){
330
			$label_args = array(
331
				'title'=> $args['label'],
332
				'for'=> $args['id'],
333
				'class' => $args['label_class']." ",
334
				'label_type' => $args['label_type']
335
			);
336
			$output .= self::label( $label_args );
337
		}
338
339
		// maybe horizontal label
340
		if($args['label_type']=='horizontal'){
341
			$output .= '<div class="col-sm-10">';
342
		}
343
344
		if(!empty($args['wysiwyg'])){
345
			ob_start();
346
			$content = $args['value'];
347
			$editor_id = !empty($args['id']) ? sanitize_html_class($args['id']) : 'wp_editor';
348
			$settings = array(
349
				'textarea_rows' => !empty(absint($args['rows'])) ? absint($args['rows']) : 4,
350
				'quicktags'     => false,
351
				'media_buttons' => false,
352
				'editor_class'  => 'form-control',
353
				'textarea_name' => !empty($args['name']) ? sanitize_html_class($args['name']) : sanitize_html_class($args['id']),
354
				'teeny'         => true,
355
			);
356
357
			// maybe set settings if array
358
			if(is_array($args['wysiwyg'])){
359
				$settings  = wp_parse_args( $args['wysiwyg'], $settings );
360
			}
361
362
			wp_editor( $content, $editor_id, $settings );
363
			$output .= ob_get_clean();
364
		}else{
365
366
			// open
367
			$output .= '<textarea ';
368
369
			// name
370
			if(!empty($args['name'])){
371
				$output .= ' name="'.esc_attr($args['name']).'" ';
372
			}
373
374
			// id
375
			if(!empty($args['id'])){
376
				$output .= ' id="'.sanitize_html_class($args['id']).'" ';
377
			}
378
379
			// placeholder
380
			if(isset($args['placeholder']) && '' != $args['placeholder']){
381
				$output .= ' placeholder="'.esc_attr($args['placeholder']).'" ';
382
			}
383
384
			// title
385
			if(!empty($args['title'])){
386
				$output .= ' title="'.esc_attr($args['title']).'" ';
387
			}
388
389
			// validation text
390
			if(!empty($args['validation_text'])){
391
				$output .= ' oninvalid="setCustomValidity(\''.esc_attr($args['validation_text']).'\')" ';
392
				$output .= ' onchange="try{setCustomValidity(\'\')}catch(e){}" ';
393
			}
394
395
			// validation_pattern
396
			if(!empty($args['validation_pattern'])){
397
				$output .= ' pattern="'.$args['validation_pattern'].'" ';
398
			}
399
400
			// required
401
			if(!empty($args['required'])){
402
				$output .= ' required ';
403
			}
404
405
			// rows
406
			if(!empty($args['rows'])){
407
				$output .= ' rows="'.absint($args['rows']).'" ';
408
			}
409
410
411
			// class
412
			$class = !empty($args['class']) ? $args['class'] : '';
413
			$output .= ' class="form-control '.$class.'" ';
414
415
			// extra attributes
416
			if(!empty($args['extra_attributes'])){
417
				$output .= AUI_Component_Helper::extra_attributes($args['extra_attributes']);
418
			}
419
420
			// close tag
421
			$output .= ' >';
422
423
			// value
424
			if ( ! empty( $args['value'] ) ) {
425
				if ( ! empty( $args['allow_tags'] ) ) {
426
					$output .= AUI_Component_Helper::sanitize_html_field( $args['value'], $args ); // Sanitize HTML.
427
				} else {
428
					$output .= sanitize_textarea_field( $args['value'] );
429
				}
430
			}
431
432
			// closing tag
433
			$output .= '</textarea>';
434
435
		}
436
437
		if(!empty($args['label']) && $label_after){
438
			$label_args = array(
439
				'title'=> $args['label'],
440
				'for'=> $args['id'],
441
				'class' => $args['label_class']." ",
442
				'label_type' => $args['label_type']
443
			);
444
			$output .= self::label( $label_args );
445
		}
446
447
		// help text
448
		if(!empty($args['help_text'])){
449
			$output .= AUI_Component_Helper::help_text($args['help_text']);
450
		}
451
452
		// maybe horizontal label
453
		if($args['label_type']=='horizontal'){
454
			$output .= '</div>';
455
		}
456
457
458
		// wrap
459
		if(!$args['no_wrap']){
460
			$form_group_class = $args['label_type']=='floating' ? 'form-label-group' : 'form-group';
461
			$wrap_class = $args['label_type']=='horizontal' ? $form_group_class . ' row' : $form_group_class;
462
			$wrap_class = !empty($args['wrap_class']) ? $wrap_class." ".$args['wrap_class'] : $wrap_class;
463
			$output = self::wrap(array(
464
				'content' => $output,
465
				'class'   => $wrap_class,
466
				'element_require'   => $args['element_require'],
467
				'argument_id'  => $args['id'],
468
				'wrap_attributes' => $args['wrap_attributes'],
469
			));
470
		}
471
472
473
		return $output;
474
	}
475
476
	public static function label($args = array(), $type = ''){
477
		//<label for="exampleInputEmail1">Email address</label>
478
		$defaults = array(
479
			'title'       => 'div',
480
			'for'      => '',
481
			'class'      => '',
482
			'label_type'    => '', // empty = hidden, top, horizontal
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
		if($args['title']){
492
493
			// maybe hide labels //@todo set a global option for visibility class
494
			if($type == 'file' || $type == 'checkbox' || $type == 'radio' || !empty($args['label_type']) ){
495
				$class = $args['class'];
496
			}else{
497
				$class = 'sr-only '.$args['class'];
498
			}
499
500
			// maybe horizontal
501
			if($args['label_type']=='horizontal' && $type != 'checkbox'){
502
				$class .= ' col-sm-2 col-form-label';
503
			}
504
505
			// open
506
			$output .= '<label ';
507
508
			// for
509
			if(!empty($args['for'])){
510
				$output .= ' for="'.esc_attr($args['for']).'" ';
511
			}
512
513
			// class
514
			$class = $class ? AUI_Component_Helper::esc_classes( $class ) : '';
515
			$output .= ' class="'.$class.'" ';
516
517
			// close
518
			$output .= '>';
519
520
521
			// title, don't escape fully as can contain html
522
			if(!empty($args['title'])){
523
				$output .= wp_kses_post($args['title']);
524
			}
525
526
			// close wrap
527
			$output .= '</label>';
528
529
530
		}
531
532
533
		return $output;
534
	}
535
536
	/**
537
	 * Wrap some content in a HTML wrapper.
538
	 *
539
	 * @param array $args
540
	 *
541
	 * @return string
542
	 */
543
	public static function wrap($args = array()){
544
		$defaults = array(
545
			'type'       => 'div',
546
			'class'      => 'form-group',
547
			'content'   => '',
548
			'input_group_left' => '',
549
			'input_group_right' => '',
550
			'input_group_left_inside' => false,
551
			'input_group_right_inside' => false,
552
			'element_require'   => '',
553
			'argument_id'   => '',
554
			'wrap_attributes' => array()
555
		);
556
557
		/**
558
		 * Parse incoming $args into an array and merge it with $defaults
559
		 */
560
		$args   = wp_parse_args( $args, $defaults );
561
		$output = '';
562
		if($args['type']){
563
564
			// open
565
			$output .= '<'.sanitize_html_class($args['type']);
566
567
			// element require
568
			if(!empty($args['element_require'])){
569
				$output .= AUI_Component_Helper::element_require($args['element_require']);
570
				$args['class'] .= " aui-conditional-field";
571
			}
572
573
			// argument_id
574
			if( !empty($args['argument_id']) ){
575
				$output .= ' data-argument="'.esc_attr($args['argument_id']).'"';
576
			}
577
578
			// class
579
			$class = !empty($args['class']) ? AUI_Component_Helper::esc_classes( $args['class'] ) : '';
580
			$output .= ' class="'.$class.'" ';
581
582
			// Attributes
583
			if ( ! empty( $args['wrap_attributes'] ) ) {
584
				$output .= AUI_Component_Helper::extra_attributes( $args['wrap_attributes'] );
585
			}
586
587
			// close wrap
588
			$output .= ' >';
589
590
591
			// Input group left
592
			if(!empty($args['input_group_left'])){
593
				$position_class = !empty($args['input_group_left_inside']) ? 'position-absolute h-100' : '';
594
				$input_group_left = strpos($args['input_group_left'], '<') !== false ? $args['input_group_left'] : '<span class="input-group-text">'.$args['input_group_left'].'</span>';
595
				$output .= '<div class="input-group-prepend '.$position_class.'">'.$input_group_left.'</div>';
596
			}
597
598
			// content
599
			$output .= $args['content'];
600
601
			// Input group right
602
			if(!empty($args['input_group_right'])){
603
				$position_class = !empty($args['input_group_left_inside']) ? 'position-absolute h-100' : '';
604
				$input_group_right = strpos($args['input_group_right'], '<') !== false ? $args['input_group_right'] : '<span class="input-group-text">'.$args['input_group_right'].'</span>';
605
				$output .= '<div class="input-group-append '.$position_class.'">'.$input_group_right.'</div>';
606
			}
607
608
609
			// close wrap
610
			$output .= '</'.sanitize_html_class($args['type']).'>';
611
612
613
		}else{
614
			$output = $args['content'];
615
		}
616
617
		return $output;
618
	}
619
620
	/**
621
	 * Build the component.
622
	 *
623
	 * @param array $args
624
	 *
625
	 * @return string The rendered component.
626
	 */
627
	public static function select($args = array()){
628
		$defaults = array(
629
			'class'      => '',
630
			'wrap_class' => '',
631
			'id'         => '',
632
			'title'      => '',
633
			'value'      => '', // can be an array or a string
634
			'required'   => false,
635
			'label'      => '',
636
			'label_after'=> false,
637
			'label_type' => '', // sets the label type, default: hidden. Options: hidden, top, horizontal, floating
638
			'label_class'      => '',
639
			'help_text'  => '',
640
			'placeholder'=> '',
641
			'options'    => array(), // array or string
642
			'icon'       => '',
643
			'multiple'   => false,
644
			'select2'    => false,
645
			'no_wrap'    => false,
646
			'element_require'   => '', // [%element_id%] == "1"
647
			'extra_attributes'  => array(), // an array of extra attributes
648
			'wrap_attributes'   => array(),
649
		);
650
651
		/**
652
		 * Parse incoming $args into an array and merge it with $defaults
653
		 */
654
		$args   = wp_parse_args( $args, $defaults );
655
		$output = '';
656
657
		// for now lets hide floating labels
658
		if( $args['label_type'] == 'floating' ){$args['label_type'] = 'hidden';}
659
660
		// hidden label option needs to be empty
661
		$args['label_type'] = $args['label_type'] == 'hidden' ? '' : $args['label_type'];
662
663
664
		$label_after = $args['label_after'];
665
666
		// floating labels need label after
667
		if( $args['label_type'] == 'floating' ){
668
			$label_after = true;
669
			$args['placeholder'] = ' '; // set the placeholder not empty so the floating label works.
670
		}
671
672
		// Maybe setup select2
673
		$is_select2 = false;
674
		if(!empty($args['select2'])){
675
			$args['class'] .= ' aui-select2';
676
			$is_select2 = true;
677
		}elseif( strpos($args['class'], 'aui-select2') !== false){
678
			$is_select2 = true;
679
		}
680
681
		// select2 tags
682
		if( !empty($args['select2']) && $args['select2'] === 'tags'){ // triple equals needed here for some reason
683
			$args['data-tags'] = 'true';
684
			$args['data-token-separators'] = "[',']";
685
			$args['multiple'] = true;
686
		}
687
688
		// select2 placeholder
689
		if($is_select2 && isset($args['placeholder']) && '' != $args['placeholder'] && empty($args['data-placeholder'])){
690
			$args['data-placeholder'] = esc_attr($args['placeholder']);
691
			$args['data-allow-clear'] = isset($args['data-allow-clear']) ? (bool) $args['data-allow-clear'] : true;
692
		}
693
694
		// label
695
		if(!empty($args['label']) && is_array($args['label'])){
696
		}elseif(!empty($args['label']) && !$label_after){
697
			$label_args = array(
698
				'title'=> $args['label'],
699
				'for'=> $args['id'],
700
				'class' => $args['label_class']." ",
701
				'label_type' => $args['label_type']
702
			);
703
			$output .= self::label($label_args);
704
		}
705
706
		// maybe horizontal label
707
		if($args['label_type']=='horizontal'){
708
			$output .= '<div class="col-sm-10">';
709
		}
710
711
		// Set hidden input to save empty value for multiselect.
712
		if ( ! empty( $args['multiple'] ) && ! empty( $args['name'] ) ) {
713
			$output .= '<input type="hidden" ' . AUI_Component_Helper::name( $args['name'] ) . ' value=""/>';
714
		}
715
716
		// open/type
717
		$output .= '<select ';
718
719
		// style
720
		if($is_select2){
721
			$output .= " style='width:100%;' ";
722
		}
723
724
		// element require
725
		if(!empty($args['element_require'])){
726
			$output .= AUI_Component_Helper::element_require($args['element_require']);
727
			$args['class'] .= " aui-conditional-field";
728
		}
729
730
		// class
731
		$class = !empty($args['class']) ? $args['class'] : '';
732
		$output .= AUI_Component_Helper::class_attr('custom-select '.$class);
733
734
		// name
735
		if(!empty($args['name'])){
736
			$output .= AUI_Component_Helper::name($args['name'],$args['multiple']);
737
		}
738
739
		// id
740
		if(!empty($args['id'])){
741
			$output .= AUI_Component_Helper::id($args['id']);
742
		}
743
744
		// title
745
		if(!empty($args['title'])){
746
			$output .= AUI_Component_Helper::title($args['title']);
747
		}
748
749
		// data-attributes
750
		$output .= AUI_Component_Helper::data_attributes($args);
751
752
		// aria-attributes
753
		$output .= AUI_Component_Helper::aria_attributes($args);
754
755
		// extra attributes
756
		if(!empty($args['extra_attributes'])){
757
			$output .= AUI_Component_Helper::extra_attributes($args['extra_attributes']);
758
		}
759
760
		// required
761
		if(!empty($args['required'])){
762
			$output .= ' required ';
763
		}
764
765
		// multiple
766
		if(!empty($args['multiple'])){
767
			$output .= ' multiple ';
768
		}
769
770
		// close opening tag
771
		$output .= ' >';
772
773
		// placeholder
774
		if(isset($args['placeholder']) && '' != $args['placeholder'] && !$is_select2){
775
			$output .= '<option value="" disabled selected hidden>'.esc_attr($args['placeholder']).'</option>';
776
		}elseif($is_select2 && !empty($args['placeholder'])){
777
			$output .= "<option></option>"; // select2 needs an empty select to fill the placeholder
778
		}
779
780
		// Options
781
		if(!empty($args['options'])){
782
783
			if(!is_array($args['options'])){
784
				$output .= $args['options']; // not the preferred way but an option
785
			}else{
786
				foreach($args['options'] as $val => $name){
787
					$selected = '';
788
					if(is_array($name)){
789
						if (isset($name['optgroup']) && ($name['optgroup'] == 'start' || $name['optgroup'] == 'end')) {
790
							$option_label = isset($name['label']) ? $name['label'] : '';
791
792
							$output .= $name['optgroup'] == 'start' ? '<optgroup label="' . esc_attr($option_label) . '">' : '</optgroup>';
793
						} else {
794
							$option_label = isset($name['label']) ? $name['label'] : '';
795
							$option_value = isset($name['value']) ? $name['value'] : '';
796
							if(!empty($args['multiple']) && !empty($args['value']) && is_array($args['value']) ){
797
								$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

797
								$selected = in_array($option_value, /** @scrutinizer ignore-type */ stripslashes_deep($args['value'])) ? "selected" : "";
Loading history...
798
							} elseif(!empty($args['value'])) {
799
								$selected = selected($option_value,stripslashes_deep($args['value']), false);
800
							}
801
802
							$output .= '<option value="' . esc_attr($option_value) . '" ' . $selected . '>' . $option_label . '</option>';
803
						}
804
					}else{
805
						if(!empty($args['value'])){
806
							if(is_array($args['value'])){
807
								$selected = in_array($val,$args['value']) ? 'selected="selected"' : '';
808
							} elseif(!empty($args['value'])) {
809
								$selected = selected( $args['value'], $val, false);
810
							}
811
						}
812
						$output .= '<option value="'.esc_attr($val).'" '.$selected.'>'.esc_attr($name).'</option>';
813
					}
814
				}
815
			}
816
817
		}
818
819
		// closing tag
820
		$output .= '</select>';
821
822
		if(!empty($args['label']) && $label_after){
823
			$label_args = array(
824
				'title'=> $args['label'],
825
				'for'=> $args['id'],
826
				'class' => $args['label_class']." ",
827
				'label_type' => $args['label_type']
828
			);
829
			$output .= self::label($label_args);
830
		}
831
832
		// help text
833
		if(!empty($args['help_text'])){
834
			$output .= AUI_Component_Helper::help_text($args['help_text']);
835
		}
836
837
		// maybe horizontal label
838
		if($args['label_type']=='horizontal'){
839
			$output .= '</div>';
840
		}
841
842
843
		// wrap
844
		if(!$args['no_wrap']){
845
			$wrap_class = $args['label_type']=='horizontal' ? 'form-group row' : 'form-group';
846
			$wrap_class = !empty($args['wrap_class']) ? $wrap_class." ".$args['wrap_class'] : $wrap_class;
847
			$output = self::wrap(array(
848
				'content' => $output,
849
				'class'   => $wrap_class,
850
				'element_require'   => $args['element_require'],
851
				'argument_id'  => $args['id'],
852
				'wrap_attributes' => $args['wrap_attributes'],
853
			));
854
		}
855
856
857
		return $output;
858
	}
859
860
	/**
861
	 * Build the component.
862
	 *
863
	 * @param array $args
864
	 *
865
	 * @return string The rendered component.
866
	 */
867
	public static function radio($args = array()){
868
		$defaults = array(
869
			'class'      => '',
870
			'wrap_class' => '',
871
			'id'         => '',
872
			'title'      => '',
873
			'horizontal' => false, // sets the lable horizontal
874
			'value'      => '',
875
			'label'      => '',
876
			'label_class'=> '',
877
			'label_type' => '', // sets the label type, default: hidden. Options: hidden, top, horizontal, floating
878
			'help_text'  => '',
879
			'inline'     => true,
880
			'required'   => false,
881
			'options'    => array(),
882
			'icon'       => '',
883
			'no_wrap'    => false,
884
			'element_require'   => '', // [%element_id%] == "1"
885
			'extra_attributes'  => array(), // an array of extra attributes
886
			'wrap_attributes'   => array()
887
		);
888
889
		/**
890
		 * Parse incoming $args into an array and merge it with $defaults
891
		 */
892
		$args   = wp_parse_args( $args, $defaults );
893
894
		// for now lets use horizontal for floating
895
		if( $args['label_type'] == 'floating' ){$args['label_type'] = 'horizontal';}
896
897
		$label_args = array(
898
			'title'=> $args['label'],
899
			'class' => $args['label_class']." pt-0 ",
900
			'label_type' => $args['label_type']
901
		);
902
903
		$output = '';
904
905
906
907
		// label before
908
		if(!empty($args['label'])){
909
			$output .= self::label( $label_args, 'radio' );
910
		}
911
912
		// maybe horizontal label
913
		if($args['label_type']=='horizontal'){
914
			$output .= '<div class="col-sm-10">';
915
		}
916
917
		if(!empty($args['options'])){
918
			$count = 0;
919
			foreach($args['options'] as $value => $label){
920
				$option_args = $args;
921
				$option_args['value'] = $value;
922
				$option_args['label'] = $label;
923
				$option_args['checked'] = $value == $args['value'] ? true : false;
924
				$output .= self::radio_option($option_args,$count);
925
				$count++;
926
			}
927
		}
928
929
		// help text
930
		$help_text = ! empty( $args['help_text'] ) ? AUI_Component_Helper::help_text( $args['help_text'] ) : '';
931
		$output .= $help_text;
932
933
		// maybe horizontal label
934
		if($args['label_type']=='horizontal'){
935
			$output .= '</div>';
936
		}
937
938
		// wrap
939
		$wrap_class = $args['label_type']=='horizontal' ? 'form-group row' : 'form-group';
940
		$wrap_class = !empty($args['wrap_class']) ? $wrap_class." ".$args['wrap_class'] : $wrap_class;
941
		$output = self::wrap(array(
942
			'content' => $output,
943
			'class'   => $wrap_class,
944
			'element_require'   => $args['element_require'],
945
			'argument_id'  => $args['id'],
946
			'wrap_attributes' => $args['wrap_attributes'],
947
		));
948
949
950
		return $output;
951
	}
952
953
	/**
954
	 * Build the component.
955
	 *
956
	 * @param array $args
957
	 *
958
	 * @return string The rendered component.
959
	 */
960
	public static function radio_option($args = array(),$count = ''){
961
		$defaults = array(
962
			'class'      => '',
963
			'id'         => '',
964
			'title'      => '',
965
			'value'      => '',
966
			'required'   => false,
967
			'inline'     => true,
968
			'label'      => '',
969
			'options'    => array(),
970
			'icon'       => '',
971
			'no_wrap'    => false,
972
			'extra_attributes'  => array() // an array of extra attributes
973
		);
974
975
		/**
976
		 * Parse incoming $args into an array and merge it with $defaults
977
		 */
978
		$args   = wp_parse_args( $args, $defaults );
979
980
		$output = '';
981
982
		// open/type
983
		$output .= '<input type="radio"';
984
985
		// class
986
		$output .= ' class="form-check-input" ';
987
988
		// name
989
		if(!empty($args['name'])){
990
			$output .= AUI_Component_Helper::name($args['name']);
991
		}
992
993
		// id
994
		if(!empty($args['id'])){
995
			$output .= AUI_Component_Helper::id($args['id'].$count);
996
		}
997
998
		// title
999
		if(!empty($args['title'])){
1000
			$output .= AUI_Component_Helper::title($args['title']);
1001
		}
1002
1003
		// value
1004
		if(isset($args['value'])){
1005
			$output .= AUI_Component_Helper::value($args['value']);
1006
		}
1007
1008
		// checked, for radio and checkboxes
1009
		if( $args['checked'] ){
1010
			$output .= ' checked ';
1011
		}
1012
1013
		// data-attributes
1014
		$output .= AUI_Component_Helper::data_attributes($args);
1015
1016
		// aria-attributes
1017
		$output .= AUI_Component_Helper::aria_attributes($args);
1018
1019
		// extra attributes
1020
		if(!empty($args['extra_attributes'])){
1021
			$output .= AUI_Component_Helper::extra_attributes($args['extra_attributes']);
1022
		}
1023
1024
		// required
1025
		if(!empty($args['required'])){
1026
			$output .= ' required ';
1027
		}
1028
1029
		// close opening tag
1030
		$output .= ' >';
1031
1032
		// label
1033
		if(!empty($args['label']) && is_array($args['label'])){
1034
		}elseif(!empty($args['label'])){
1035
			$output .= self::label(array('title'=>$args['label'],'for'=>$args['id'].$count,'class'=>'form-check-label'),'radio');
1036
		}
1037
1038
		// wrap
1039
		if ( ! $args['no_wrap'] ) {
1040
			$wrap_class = $args['inline'] ? 'form-check form-check-inline' : 'form-check';
1041
1042
			// Unique wrap class
1043
			$uniq_class = 'fwrap';
1044
			if ( ! empty( $args['name'] ) ) {
1045
				$uniq_class .= '-' . $args['name'];
1046
			} else if ( ! empty( $args['id'] ) ) {
1047
				$uniq_class .= '-' . $args['id'];
1048
			}
1049
1050
			if ( isset( $args['value'] ) || $args['value'] !== "" ) {
1051
				$uniq_class .= '-' . $args['value'];
1052
			} else {
1053
				$uniq_class .= '-' . $count;
1054
			}
1055
			$wrap_class .= ' ' . sanitize_html_class( $uniq_class );
1056
1057
			$output = self::wrap(array(
1058
				'content' => $output,
1059
				'class' => $wrap_class
1060
			));
1061
		}
1062
1063
		return $output;
1064
	}
1065
1066
}