Passed
Push — master ( c16653...06c25c )
by Brian
04:36
created

AUI_Component_Input::wrap()   C

Complexity

Conditions 11
Paths 201

Size

Total Lines 69
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 35
c 1
b 0
f 1
dl 0
loc 69
rs 6.4708
cc 11
nc 201
nop 1

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

762
								$selected = in_array($option_value, /** @scrutinizer ignore-type */ stripslashes_deep($args['value'])) ? "selected" : "";
Loading history...
763
							} elseif(!empty($args['value'])) {
764
								$selected = selected($option_value,stripslashes_deep($args['value']), false);
765
							}
766
767
							$output .= '<option value="' . esc_attr($option_value) . '" ' . $selected . '>' . $option_label . '</option>';
768
						}
769
					}else{
770
						if(!empty($args['value'])){
771
							if(is_array($args['value'])){
772
								$selected = in_array($val,$args['value']) ? 'selected="selected"' : '';
773
							} elseif(!empty($args['value'])) {
774
								$selected = selected( $args['value'], $val, false);
775
							}
776
						}
777
						$output .= '<option value="'.esc_attr($val).'" '.$selected.'>'.esc_attr($name).'</option>';
778
					}
779
				}
780
			}
781
782
		}
783
784
		// closing tag
785
		$output .= '</select>';
786
787
		if(!empty($args['label']) && $label_after){
788
			$label_args = array(
789
				'title'=> $args['label'],
790
				'for'=> $args['id'],
791
				'class' => $args['label_class']." ",
792
				'label_type' => $args['label_type']
793
			);
794
			$output .= self::label($label_args);
795
		}
796
797
		// help text
798
		if(!empty($args['help_text'])){
799
			$output .= AUI_Component_Helper::help_text($args['help_text']);
800
		}
801
802
		// maybe horizontal label
803
		if($args['label_type']=='horizontal'){
804
			$output .= '</div>';
805
		}
806
807
808
		// wrap
809
		if(!$args['no_wrap']){
810
			$wrap_class = $args['label_type']=='horizontal' ? 'form-group row' : 'form-group';
811
			$output = self::wrap(array(
812
				'content' => $output,
813
				'class'   => $wrap_class,
814
				'element_require'   => $args['element_require'],
815
				'argument_id'  => $args['id']
816
			));
817
		}
818
819
820
		return $output;
821
	}
822
823
	/**
824
	 * Build the component.
825
	 *
826
	 * @param array $args
827
	 *
828
	 * @return string The rendered component.
829
	 */
830
	public static function radio($args = array()){
831
		$defaults = array(
832
			'class'      => '',
833
			'id'         => '',
834
			'title'      => '',
835
			'horizontal' => false, // sets the lable horizontal
836
			'value'      => '',
837
			'label'      => '',
838
			'label_class'=> '',
839
			'label_type' => '', // sets the label type, default: hidden. Options: hidden, top, horizontal, floating
840
			'inline'     => true,
841
			'required'   => false,
842
			'options'    => array(),
843
			'icon'       => '',
844
			'no_wrap'    => false,
845
			'element_require'   => '', // [%element_id%] == "1"
846
			'extra_attributes'  => array() // an array of extra attributes
847
		);
848
849
		/**
850
		 * Parse incoming $args into an array and merge it with $defaults
851
		 */
852
		$args   = wp_parse_args( $args, $defaults );
853
854
		// for now lets use horizontal for floating
855
		if( $args['label_type'] != 'hidden' ){$args['label_type'] = 'horizontal';}
856
857
		$label_args = array(
858
			'title'=> $args['label'],
859
			'class' => $args['label_class']." pt-0 ",
860
			'label_type' => $args['label_type']
861
		);
862
863
		$output = '';
864
865
866
867
		// label before
868
		if(!empty($args['label'])){
869
			$output .= self::label( $label_args, 'radio' );
870
		}
871
872
		// maybe horizontal label
873
		if($args['label_type']=='horizontal'){
874
			$output .= '<div class="col-sm-10">';
875
		}
876
877
		if(!empty($args['options'])){
878
			$count = 0;
879
			foreach($args['options'] as $value => $label){
880
				$option_args = $args;
881
				$option_args['value'] = $value;
882
				$option_args['label'] = $label;
883
				$option_args['checked'] = $value == $args['value'] ? true : false;
884
				$output .= self::radio_option($option_args,$count);
885
				$count++;
886
			}
887
		}
888
889
		// maybe horizontal label
890
		if($args['label_type']=='horizontal'){
891
			$output .= '</div>';
892
		}
893
894
895
		// wrap
896
		$wrap_class = $args['label_type']=='horizontal' ? 'form-group row' : 'form-group';
897
		$output = self::wrap(array(
898
			'content' => $output,
899
			'class'   => $wrap_class,
900
			'element_require'   => $args['element_require'],
901
			'argument_id'  => $args['id']
902
		));
903
904
905
		return $output;
906
	}
907
908
	/**
909
	 * Build the component.
910
	 *
911
	 * @param array $args
912
	 *
913
	 * @return string The rendered component.
914
	 */
915
	public static function radio_option($args = array(),$count = ''){
916
		$defaults = array(
917
			'class'      => '',
918
			'id'         => '',
919
			'title'      => '',
920
			'value'      => '',
921
			'required'   => false,
922
			'inline'     => true,
923
			'label'      => '',
924
			'options'    => array(),
925
			'icon'       => '',
926
			'no_wrap'    => false,
927
			'extra_attributes'  => array() // an array of extra attributes
928
		);
929
930
		/**
931
		 * Parse incoming $args into an array and merge it with $defaults
932
		 */
933
		$args   = wp_parse_args( $args, $defaults );
934
935
		$output = '';
936
937
		// open/type
938
		$output .= '<input type="radio"';
939
940
		// class
941
		$output .= ' class="form-check-input" ';
942
943
		// name
944
		if(!empty($args['name'])){
945
			$output .= AUI_Component_Helper::name($args['name']);
946
		}
947
948
		// id
949
		if(!empty($args['id'])){
950
			$output .= AUI_Component_Helper::id($args['id'].$count);
951
		}
952
953
		// title
954
		if(!empty($args['title'])){
955
			$output .= AUI_Component_Helper::title($args['title']);
956
		}
957
958
		// value
959
		if(isset($args['value'])){
960
			$output .= ' value="'.sanitize_text_field($args['value']).'" ';
961
		}
962
963
		// checked, for radio and checkboxes
964
		if( $args['checked'] ){
965
			$output .= ' checked ';
966
		}
967
968
		// data-attributes
969
		$output .= AUI_Component_Helper::data_attributes($args);
970
971
		// aria-attributes
972
		$output .= AUI_Component_Helper::aria_attributes($args);
973
974
		// extra attributes
975
		if(!empty($args['extra_attributes'])){
976
			$output .= AUI_Component_Helper::extra_attributes($args['extra_attributes']);
977
		}
978
979
		// required
980
		if(!empty($args['required'])){
981
			$output .= ' required ';
982
		}
983
984
		// close opening tag
985
		$output .= ' >';
986
987
		// label
988
		if(!empty($args['label']) && is_array($args['label'])){
989
		}elseif(!empty($args['label'])){
990
			$output .= self::label(array('title'=>$args['label'],'for'=>$args['id'].$count,'class'=>'form-check-label'),'radio');
991
		}
992
993
		// wrap
994
		if(!$args['no_wrap']){
995
			$wrap_class = $args['inline'] ? 'form-check form-check-inline' : 'form-check';
996
			$output = self::wrap(array(
997
				'content' => $output,
998
				'class' => $wrap_class
999
			));
1000
		}
1001
1002
1003
		return $output;
1004
	}
1005
1006
}