PluginProbe ʕ •ᴥ•ʔ
Hustle – Email Marketing, Lead Generation, Optins, Popups / 7.4.6
Hustle – Email Marketing, Lead Generation, Optins, Popups v7.4.6
7.8.13 7.8.13.1 trunk 3.0 3.1 3.1.1 3.1.2 3.1.3 3.1.4 4.3.2 4.4.4 4.4.5 4.4.5.1 4.4.5.4 4.6 4.6.1.1 4.6.1.4 4.7.0.2 4.7.0.3 4.7.0.7 4.7.0.9 4.7.1.0 4.7.1.1 4.8.0.0 5.0.0 5.0.1 5.0.1.1 5.0.1.2 5.1 5.1.1 5.1.2 5.1.3 5.1.3.1 5.1.3.2 5.1.4 5.1.5 6.0 6.0.1 6.0.2 6.0.3 6.0.4.2 6.0.5 6.0.6.1 6.0.7 6.0.8.1 6.0.9 7.0.0.1 7.0.2 7.0.3 7.0.4 7.1.0 7.1.1 7.2.0 7.2.1 7.3.0 7.3.1 7.3.3 7.3.5 7.3.6 7.3.7 7.4.0 7.4.1 7.4.11 7.4.13 7.4.13.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.5.1 7.4.5.2 7.4.6 7.4.7 7.5.0 7.6.0 7.6.1 7.6.3 7.6.4 7.6.6 7.7.0 7.7.1 7.8.0 7.8.1 7.8.10 7.8.10.1 7.8.10.2 7.8.11 7.8.12 7.8.12.1 7.8.2 7.8.3 7.8.4 7.8.5 7.8.6 7.8.7 7.8.8 7.8.9 7.8.9.1 7.8.9.2 7.8.9.3
wordpress-popup / lib / wpmu-lib / inc / class-thelib-html.php
wordpress-popup / lib / wpmu-lib / inc Last commit date
class-thelib-array.php 5 years ago class-thelib-core.php 5 years ago class-thelib-debug.php 5 years ago class-thelib-html.php 5 years ago class-thelib-net.php 5 years ago class-thelib-session.php 5 years ago class-thelib-ui.php 5 years ago class-thelib-updates.php 5 years ago class-thelib.php 5 years ago
class-thelib-html.php
1757 lines
1 <?php
2 /**
3 * HTML Helper functions
4 * Access via function `lib3()->html`.
5 *
6 * @since 1.1.0
7 */
8 class TheLib_Html extends TheLib {
9
10 /* Constants for default HTML input elements. */
11 const INPUT_TYPE_HIDDEN = 'hidden';
12 const INPUT_TYPE_TEXT_AREA = 'textarea';
13 const INPUT_TYPE_SELECT = 'select';
14 const INPUT_TYPE_RADIO = 'radio';
15 const INPUT_TYPE_SUBMIT = 'submit';
16 const INPUT_TYPE_BUTTON = 'button';
17 const INPUT_TYPE_CHECKBOX = 'checkbox';
18 const INPUT_TYPE_IMAGE = 'image';
19 // Different input types
20 const INPUT_TYPE_TEXT = 'text';
21 const INPUT_TYPE_PASSWORD = 'password';
22 const INPUT_TYPE_NUMBER = 'number';
23 const INPUT_TYPE_EMAIL = 'email';
24 const INPUT_TYPE_URL = 'url';
25 const INPUT_TYPE_TIME = 'time';
26 const INPUT_TYPE_SEARCH = 'search';
27 const INPUT_TYPE_FILE = 'file';
28
29 /* Constants for advanced HTML input elements. */
30 const INPUT_TYPE_DATEPICKER = 'datepicker';
31 const INPUT_TYPE_RADIO_SLIDER = 'radio_slider';
32 const INPUT_TYPE_TAG_SELECT = 'tag_select';
33 const INPUT_TYPE_WP_COLOR_PICKER = 'wp_color_picker';
34 const INPUT_TYPE_WP_EDITOR = 'wp_editor';
35 const INPUT_TYPE_WP_MEDIA = 'wp_media';
36 const INPUT_TYPE_WP_PAGES = 'wp_pages';
37
38 /* Constants for default HTML elements. */
39 const TYPE_HTML_LINK = 'html_link';
40 const TYPE_HTML_SEPARATOR = 'html_separator';
41 const TYPE_HTML_TEXT = 'html_text';
42 const TYPE_HTML_TABLE = 'html_table';
43
44
45 /**
46 * Class constructor
47 *
48 * @since 1.1.0
49 */
50 public function __construct() {
51 parent::__construct();
52 }
53
54
55 /*================================*\
56 ====================================
57 == ==
58 == WP POINTER ==
59 == ==
60 ====================================
61 \*================================*/
62
63
64 /**
65 * Displays a WordPress pointer on the current admin screen.
66 *
67 * @since 1.1.0
68 * @api
69 *
70 * @param array|string $pointer_id Internal ID of the pointer, make sure it is unique!
71 * Optionally this param can contain all params in array notation.
72 * @param string $html_el HTML element to point to (e.g. '#menu-appearance')
73 * @param string $title The title of the pointer.
74 * @param string $body Text of the pointer.
75 *
76 * @return TheLib_Html Reference to $this for chaining.
77 */
78 public function pointer( $args, $html_el = '', $title = false, $body = '' ) {
79 if ( ! is_admin() ) {
80 return;
81 }
82 $classes = array(
83 'wpmui-pointer-handler',
84 'prepared',
85 );
86 if ( is_array( $args ) ) {
87 if ( ! isset( $args['schema'] ) || 'wp' !== $args['schema'] ) {
88 $classes[] = 'wpmui-pointer';
89 }
90 $elements = array(
91 'target' => 'html_el',
92 'id' => 'pointer_id',
93 'title' => 'title',
94 'body' => 'body',
95 'classes' => 'classes',
96 );
97 foreach ( $elements as $from => $to ) {
98 if ( isset( $args[ $to ] ) ) {
99 continue;
100 }
101 if ( isset( $args[ $from ] ) ) {
102 $args[ $to ] = $args[ $from ];
103 }
104 if ( empty( $args[ $to ] ) && isset( $$to ) ) {
105 $args[ $to ] = $$to;
106 }
107 }
108 if ( isset( $args['modal'] ) && ! isset( $args['blur'] ) ) {
109 $args['blur'] = $args['modal'];
110 }
111 $elements = array( 'once', 'modal', 'blur' );
112 foreach ( $elements as $key ) {
113 if ( ! isset( $args[ $key ] ) ) {
114 $args[ $key ] = true;
115 }
116 }
117 self::$core->array->equip( $args, 'pointer_id', 'html_el', 'title', 'body', 'once', 'modal', 'blur' );
118 extract( $args );
119 } else {
120 $pointer_id = $args;
121 $once = true;
122 $modal = true;
123 $blur = true;
124 $classes[] = 'wpmui-pointer';
125 }
126
127 $once = self::$core->is_true( $once );
128 $modal = self::$core->is_true( $modal );
129 $blur = self::$core->is_true( $blur );
130
131 $this->_add( 'init_pointer', compact( 'pointer_id', 'html_el', 'title', 'body', 'once', 'modal', 'blur', 'classes' ) );
132 $this->add_action( 'init', '_init_pointer' );
133
134 return $this;
135 }
136
137 /**
138 * Action handler for plugins_loaded. This decides if the pointer will be displayed.
139 *
140 * @since 1.0.2
141 * @internal
142 */
143 public function _init_pointer() {
144 $items = $this->_get( 'init_pointer' );
145 foreach ( $items as $item ) {
146 extract( $item ); // pointer_id, html_el, title, body, once, modal, blur
147 $show = true;
148
149 if ( $once ) {
150 // Find out which pointer IDs this user has already seen.
151 $seen = (string) get_user_meta(
152 get_current_user_id(),
153 'dismissed_wp_pointers',
154 true
155 );
156 $seen_list = explode( ',', $seen );
157 $show = ! in_array( $pointer_id, $seen_list );
158 } else {
159 $show = true;
160 }
161
162 // Include all scripts and code to display the pointer!
163 if ( $show ) {
164 $this->add_action( 'admin_print_footer_scripts', '_pointer_print_scripts' );
165 $this->add_action( 'admin_enqueue_scripts', '_enqueue_pointer' );
166
167 $this->_add( 'pointer', $item );
168 }
169 }
170 }
171
172 /**
173 * Enqueue wp-pointer
174 *
175 * @since 1.0.1
176 * @internal
177 */
178 public function _enqueue_pointer() {
179 // Load the JS/CSS for WP Pointers
180 wp_enqueue_script( 'wp-pointer' );
181 wp_enqueue_style( 'wp-pointer' );
182 }
183
184 /**
185 * Action hook for admin footer scripts
186 *
187 * @since 1.0.1
188 * @internal
189 */
190 public function _pointer_print_scripts() {
191 $items = $this->_get( 'pointer' );
192 foreach ( $items as $item ) {
193 extract( $item ); // pointer_id, html_el, title, body, once, modal, blur
194 include $this->_view_path( 'pointer.php' );
195 }
196 }
197
198
199 /*===========================*\
200 ===============================
201 == ==
202 == POPUP ==
203 == ==
204 ===============================
205 \*===========================*/
206
207
208 /**
209 * Display a wpmUi popup on page load.
210 *
211 * @since 1.1.0
212 * @api
213 *
214 * @param array $args Popup options.
215 * @return Reference to $this for chaining.
216 */
217 public function popup( $args = array() ) {
218 // Determine which hook should print the data.
219 $hook = ( is_admin() ? 'admin_footer' : 'wp_footer' );
220
221 self::$core->array->equip( $args, 'title', 'body', 'screen', 'modal', 'width', 'height', 'class' );
222
223 // Don't add empty popups
224 if ( empty( $args['title'] ) && empty( $args['body'] ) ) {
225 return;
226 }
227 if ( ! isset( $args['close'] ) ) {
228 $args['close'] = true;
229 }
230 if ( ! isset( $args['sticky'] ) ) {
231 $args['sticky'] = false;
232 }
233
234 $args['width'] = absint( $args['width'] );
235 $args['height'] = absint( $args['height'] );
236
237 if ( $args['width'] < 20 ) {
238 $args['width'] = -1;
239 }
240 if ( $args['height'] < 20 ) {
241 $args['height'] = -1;
242 }
243
244 $args['modal'] = $args['modal'] ? 'true' : 'false';
245 $args['persist'] = $args['sticky'] ? 'false' : 'true';
246 $args['close'] = $args['close'] ? 'true' : 'false';
247
248 self::_add( 'popup', $args );
249 $this->add_action( $hook, '_popup_callback' );
250 self::$core->ui->add( 'core' );
251
252 return $this;
253 }
254
255 /**
256 * Add popup code to the page footer
257 *
258 * @since 1.1.3
259 * @internal
260 */
261 public function _popup_callback() {
262 $items = self::_get( 'popup' );
263 self::_clear( 'popup' );
264 $screen_info = get_current_screen();
265 $screen_id = $screen_info->id;
266
267 foreach ( $items as $item ) {
268 extract( $item ); // title, body, modal, close, modal, persist, width, height, class
269
270 if ( empty( $title ) ) {
271 $close = false;
272 }
273
274 if ( empty( $screen ) || $screen_id == $screen ) {
275 $body = '<div>' . $body . '</div>';
276 echo '<script>jQuery(function(){wpmUi.popup()';
277 printf( '.title( %1$s, %2$s )', json_encode( $title ), $close );
278 printf( '.modal( %1$s, %2$s )', $modal, $persist );
279 printf( '.size( %1$s, %2$s )', json_encode( $width ), json_encode( $height ) );
280 printf( '.set_class( %1$s )', json_encode( $class ) );
281 printf( '.content( %1$s )', json_encode( $body ) );
282 echo '.show();})</script>';
283 }
284 }
285 }
286
287
288 /*=================================*\
289 =====================================
290 == ==
291 == PLUGIN LIST ==
292 == ==
293 =====================================
294 \*=================================*/
295
296
297 /**
298 * Generates full code for a plugin list in WordPress 4.0 style, including
299 * the filter and search section in the top.
300 *
301 * All items are included in page load and displayed or filtered via
302 * javascript.
303 *
304 * @since 1.1
305 * @api
306 *
307 * @param array $items {
308 * List of all items to include. Each item has these properties:
309 *
310 * @var string $title
311 * @var string $description
312 * @var string $version
313 * @var string $author
314 * @var array $action
315 * @var array $details
316 * @var bool $active
317 * @var string $icon
318 * }
319 * @param object $lang {
320 * @var string $active_badge
321 * @var string $show_details
322 * @var string $close_details
323 * }
324 * @param array $filters {
325 * @var string $key
326 * @var string $label
327 * }
328 *
329 * @return Reference to $this for chaining.
330 */
331 public function addon_list( $items, $lang, $filters ) {
332 self::$core->ui->css( $this->_css_url( 'wpmu-card-list.3.min.css' ) );
333 self::$core->ui->js( $this->_js_url( 'wpmu-card-list.3.min.js' ) );
334 include $this->_view_path( 'list.php' );
335 return $this;
336 }
337
338
339 /*====================================*\
340 ========================================
341 == ==
342 == HTML STRUCTURE ==
343 == ==
344 ========================================
345 \*====================================*/
346
347
348 /**
349 * Method for creating HTML elements/fields.
350 *
351 * Pass in array with field arguments. See $defaults for argmuments.
352 * Use constants to specify field type. e.g. self::INPUT_TYPE_TEXT
353 *
354 * @since 1.1.0
355 * @api
356 *
357 * @param array|string $field_args {
358 * If this param is a string then the string is output.
359 * Otherwise an array is expected that defines the output
360 * field.
361 *
362 * $type string Field type. {@see const definitions}
363 * $id string Field ID (html attribute)
364 * $class string Field class (html attribute)
365 * $value string Field value (html attribute)
366 *
367 * $title string Field label/caption to display.
368 * $desc string Description.
369 * $before string Text before the input element.
370 * $after string Text after the input element.
371 *
372 * (more attributes available)
373 * }
374 * @param bool $return Optional. If true the element is returned by
375 * function. Default: false (direct echo the HTML)
376 *
377 * @return void|string If $return param is false the HTML will be echo'ed,
378 * otherwise returned as string (default is echo)
379 */
380 public function element( $field_args, $return = false ) {
381 self::$core->ui->add( 'html_element' );
382
383 if ( is_string( $field_args ) ) {
384 if ( $return ) {
385 return $field_args;
386 } else {
387 echo $field_args;
388 return;
389 }
390 }
391
392 // Field arguments.
393 $defaults = array(
394 'id' => '',
395 'name' => '',
396 'section' => '', // Only used if name is empty
397 'title' => '', // Title above desc / element
398 'desc' => '', // Usually displayed in row above the element
399 'before' => '', // In same row as element
400 'after' => '', // In same row as element
401 'value' => '',
402 'type' => 'text',
403 'class' => '',
404 'label_class' => '',
405 'maxlength' => '',
406 'equalTo' => '',
407 'field_options' => array(),
408 'multiple' => false,
409 'tooltip' => '',
410 'alt' => '',
411 'read_only' => false,
412 'disabled' => false,
413 'placeholder' => '',
414 'data_placeholder' => '',
415 'ajax_data' => '',
416 'data' => array(),
417 'label_type' => 'label',
418 'sticky' => false, // populate $value from $_REQUEST struct
419 'config' => array(), // other, element-specific configurations
420 'wrapper_class' => '', // class added to the outermost element wrapper
421 // Specific for type 'button', 'submit':
422 'button_value' => '',
423 'button_type' => '', // for display [empty/'submit'/'button']
424 // Specific for type 'tag_select':
425 'title_selected' => '',
426 'empty_text' => '',
427 'button_text' => '',
428 // Specific for type 'link':
429 'target' => '_self',
430 // Specific for type 'radio_slider':
431 'url' => '',
432 );
433
434 $field_args = wp_parse_args( $field_args, $defaults );
435 extract( $field_args );
436
437 if ( empty( $name ) ) {
438 if ( ! empty( $section ) ) {
439 $name = $section . "[$id]";
440 } else {
441 $name = $id;
442 }
443 }
444
445 // Input arguments
446
447 $attr_placeholder = '';
448 $attr_data_placeholder = '';
449
450 if ( '' !== $placeholder && false !== $placeholder ) {
451 $attr_placeholder = 'placeholder="' . esc_attr( $placeholder ) . '" ';
452 }
453
454 if ( '' !== $data_placeholder && false !== $data_placeholder ) {
455 $attr_data_placeholder = 'data-placeholder="' . esc_attr( $data_placeholder ) . '" ';
456 }
457
458 if ( ! empty( $data_ms ) && empty( $ajax_data ) ) {
459 $ajax_data = $data_ms;
460 }
461
462 if ( ! empty( $ajax_data ) ) {
463 if ( ! empty( $ajax_data['action'] )
464 && ( empty( $ajax_data['_wpnonce'] )
465 || true === $ajax_data['_wpnonce']
466 )
467 ) {
468 $ajax_data['_wpnonce'] = wp_create_nonce( $ajax_data['action'] );
469 }
470
471 $ajax_data = ' data-wpmui-ajax="' . esc_attr( json_encode( $ajax_data ) ) . '" ';
472 }
473
474 $max_attr = empty( $maxlength ) ? '' : 'maxlength="' . esc_attr( $maxlength ) . '" ';
475 $read_only = empty( $read_only ) ? '' : 'readonly="readonly" ';
476 $multiple = empty( $multiple ) ? '' : 'multiple="multiple" ';
477 $disabled = empty( $disabled ) ? '' : 'disabled="disabled" ';
478
479 $data_attr = '';
480 foreach ( $data as $data_key => $data_value ) {
481 $data_attr .= 'data-' . $data_key . '=' . json_encode( $data_value ) . ' ';
482 }
483 foreach ( $config as $conf_key => $conf_value ) {
484 $data_attr .= $conf_key . '=' . json_encode( $conf_value ) . ' ';
485 }
486
487 if ( ! empty( $ajax_data ) ) {
488 $class .= ' wpmui-ajax-update';
489 }
490
491 if ( $sticky ) {
492 $sticky_key = $name;
493 if ( '[]' == substr( $sticky_key, -2 ) ) {
494 $sticky_key = substr( $sticky_key, 0, -2 );
495 }
496
497 if ( isset( $_POST[ $sticky_key ] ) ) {
498 $value = $_POST[ $sticky_key ];
499 } elseif ( isset( $_GET[ $sticky_key ] ) ) {
500 $value = $_GET[ $sticky_key ];
501 }
502 }
503
504 $field_options = self::$core->array->get( $field_options );
505
506 $labels = (object) array(
507 'title' => $title,
508 'desc' => $desc,
509 'before' => $before,
510 'after' => $after,
511 'tooltip' => $tooltip,
512 'tooltip_code' => $this->tooltip( $tooltip, true ),
513 'id' => $id,
514 'class' => $label_class,
515 'label_type' => $label_type,
516 );
517
518 // Capture to output buffer
519 if ( $return ) { ob_start(); }
520
521 switch ( $type ) {
522 case self::INPUT_TYPE_HIDDEN:
523 $this->element_hidden(
524 $id,
525 $name,
526 $value,
527 $class
528 );
529 break;
530
531 case self::INPUT_TYPE_TEXT:
532 case self::INPUT_TYPE_PASSWORD:
533 case self::INPUT_TYPE_NUMBER:
534 case self::INPUT_TYPE_EMAIL:
535 case self::INPUT_TYPE_URL:
536 case self::INPUT_TYPE_TIME:
537 case self::INPUT_TYPE_SEARCH:
538 case self::INPUT_TYPE_FILE:
539 $this->element_input(
540 $labels,
541 $type,
542 $class,
543 $id,
544 $name,
545 $value,
546 $read_only . $max_attr . $attr_placeholder . $ajax_data . $data_attr . $disabled,
547 $wrapper_class
548 );
549 break;
550
551 case self::INPUT_TYPE_DATEPICKER:
552 $this->element_datepicker(
553 $labels,
554 $class,
555 $id,
556 $name,
557 $value,
558 $max_attr . $attr_placeholder . $ajax_data . $data_attr . $disabled,
559 $wrapper_class
560 );
561 break;
562
563 case self::INPUT_TYPE_TEXT_AREA:
564 $this->element_textarea(
565 $labels,
566 $class,
567 $id,
568 $name,
569 $value,
570 $read_only . $attr_placeholder . $ajax_data . $data_attr . $disabled,
571 $wrapper_class
572 );
573 break;
574
575 case self::INPUT_TYPE_SELECT:
576 $this->element_select(
577 $labels,
578 $class,
579 $id,
580 $name,
581 $value,
582 $multiple . $read_only . $attr_data_placeholder . $ajax_data . $data_attr . $disabled,
583 $field_options,
584 $wrapper_class
585 );
586 break;
587
588 case self::INPUT_TYPE_RADIO:
589 $this->element_radio(
590 $labels,
591 $class,
592 $id,
593 $name,
594 $value,
595 $ajax_data,
596 $field_options,
597 $wrapper_class
598 );
599 break;
600
601 case self::INPUT_TYPE_CHECKBOX:
602 $this->element_checkbox(
603 $labels,
604 $class,
605 $id,
606 $name,
607 $value,
608 $ajax_data . $data_attr . $disabled,
609 $field_options,
610 $config
611 );
612 break;
613
614 case self::INPUT_TYPE_WP_EDITOR:
615 $this->element_wp_editor(
616 $labels,
617 $id? $id:$name,
618 $value,
619 $field_options
620 );
621 break;
622
623 case self::INPUT_TYPE_BUTTON:
624 case self::INPUT_TYPE_SUBMIT:
625 if ( empty( $button_type ) ) {
626 $button_type = $type;
627 }
628
629 if ( $button_type === self::INPUT_TYPE_SUBMIT ) {
630 $class .= ' wpmui-submit button-primary';
631 }
632
633 $this->element_button(
634 $labels,
635 $type,
636 $class,
637 $id,
638 $name,
639 $value,
640 $button_value,
641 $ajax_data . $data_attr . $disabled
642 );
643 break;
644
645 case self::INPUT_TYPE_IMAGE:
646 $this->element_image(
647 $labels,
648 $class,
649 $id,
650 $name,
651 $value,
652 $alt,
653 $ajax_data . $data_attr . $disabled
654 );
655 break;
656
657 case self::INPUT_TYPE_RADIO_SLIDER:
658 $this->element_radioslider(
659 $labels,
660 $class,
661 $id,
662 $name,
663 $value,
664 $url,
665 $read_only,
666 $ajax_data . $data_attr,
667 $field_options,
668 $wrapper_class
669 );
670 break;
671
672 case self::INPUT_TYPE_TAG_SELECT:
673 $this->element_tagselect(
674 $labels,
675 $class,
676 $id,
677 $name,
678 $value,
679 $field_options,
680 $multiple . $read_only . $attr_data_placeholder . $data_attr . $disabled,
681 $ajax_data,
682 $empty_text,
683 $button_text,
684 $title_selected,
685 $wrapper_class
686 );
687 break;
688
689 case self::INPUT_TYPE_WP_PAGES:
690 $this->element_wp_pages(
691 $labels,
692 $class,
693 $id,
694 $name,
695 $value,
696 $multiple . $read_only . $attr_data_placeholder . $ajax_data . $data_attr . $disabled,
697 $field_options,
698 $wrapper_class
699 );
700 break;
701
702 case self::TYPE_HTML_LINK:
703 $this->element_link(
704 $labels,
705 $class,
706 $id,
707 $value,
708 $url,
709 $ajax_data . $data_attr,
710 $target
711 );
712 break;
713
714 case self::TYPE_HTML_SEPARATOR:
715 $this->element_separator(
716 ($value !== 'vertical' ? 'horizontal' : 'vertical')
717 );
718 break;
719
720 case self::TYPE_HTML_TEXT:
721 $this->element_wrapper(
722 $labels,
723 $class,
724 $id,
725 $value,
726 'span',
727 $wrapper_class
728 );
729 break;
730
731 case self::TYPE_HTML_TABLE:
732 $this->element_table(
733 $labels,
734 $class,
735 $id,
736 $value,
737 $field_options,
738 $wrapper_class
739 );
740 break;
741
742 /**
743 * wp-color-picker
744 *
745 * @since 3.0.5
746 */
747 case self::INPUT_TYPE_WP_COLOR_PICKER:
748 $this->element_color_picker(
749 $labels,
750 $class,
751 $id,
752 $name,
753 $value,
754 $max_attr . $attr_placeholder . $ajax_data . $data_attr . $disabled,
755 $wrapper_class
756 );
757 break;
758
759 /**
760 * wp_media
761 *
762 * @since 3.0.5
763 */
764 case self::INPUT_TYPE_WP_MEDIA:
765 $this->element_wp_media(
766 $labels,
767 $class,
768 $id,
769 $name,
770 $value,
771 $max_attr . $attr_placeholder . $ajax_data . $data_attr,
772 $wrapper_class
773 );
774 break;
775
776 }
777
778 // Return the output buffer
779 if ( $return ) { return ob_get_clean(); }
780 }
781
782
783 /**
784 * Helper function used by `html_element`
785 *
786 * @since 1.1.0
787 * @internal
788 */
789 private function element_hidden( $id, $name, $value, $class ) {
790 printf(
791 '<input class="wpmui-field-input wpmui-hidden %4$s" type="hidden" id="%1$s" name="%2$s" value="%3$s" />',
792 esc_attr( $id ),
793 esc_attr( $name ),
794 esc_attr( $value ),
795 esc_attr( $class )
796 );
797 }
798
799 /**
800 * Helper function used by `html_element`
801 *
802 * @since 1.1.0
803 * @internal
804 */
805 private function element_input( $labels, $type, $class, $id, $name, $value, $attr, $wrapper_class ) {
806 $this->wrap_open( 'input', $class, 'span', $wrapper_class );
807 $this->element_label( $labels );
808
809 printf(
810 '<input class="wpmui-field-input wpmui-%1$s %2$s wpmui-input-%4$s" type="%1$s" id="%3$s" name="%4$s" value="%5$s" %6$s />',
811 esc_attr( $type ),
812 esc_attr( $class ),
813 esc_attr( $id ),
814 esc_attr( sanitize_title( $name ) ),
815 esc_attr( $value ),
816 $attr
817 );
818 if ( ! empty( $labels->title ) ) {
819 $this->element_desc( $labels );
820 }
821 $this->element_hint( $labels );
822 $this->wrap_close();
823 }
824
825 /**
826 * Helper function used by `html_element`
827 *
828 * @since 1.1.0
829 * @internal
830 */
831 private function element_datepicker( $labels, $class, $id, $name, $value, $attr, $wrapper_class ) {
832 $this->wrap_open( 'datepicker', $class, 'span', $wrapper_class );
833 $this->element_label( $labels );
834
835 if ( ! empty( $value ) ) {
836 if ( ! preg_match( '/\d\d\d\d-\d\d-\d\d/', $value ) ) {
837 $value = date( 'Y-m-d', strtotime( $value ) );
838 }
839 }
840
841 printf(
842 '<span class="wpmui-field-input"><input class="wpmui-datepicker %1$s" type="text" id="%2$s" name="%3$s" value="%4$s" %5$s /><i class="wpmui-icon wpmui-fa wpmui-fa-calendar"></i></span>',
843 esc_attr( $class ),
844 esc_attr( $id ),
845 esc_attr( $name ),
846 esc_attr( $value ),
847 $attr
848 );
849
850 $this->element_hint( $labels );
851 $this->wrap_close();
852 }
853
854 /**
855 * Helper function used by `html_element`
856 *
857 * @since 1.1.0
858 * @internal
859 */
860 private function element_textarea( $labels, $class, $id, $name, $value, $attr, $wrapper_class ) {
861 $this->wrap_open( 'textarea', $class, 'span', $wrapper_class );
862 $this->element_label( $labels );
863
864 printf(
865 '<textarea class="wpmui-field-input wpmui-textarea %1$s" type="text" id="%2$s" name="%3$s" %5$s>%4$s</textarea>',
866 esc_attr( $class ),
867 esc_attr( $id ),
868 esc_attr( $name ),
869 esc_textarea( $value ),
870 $attr
871 );
872
873 $this->element_hint( $labels );
874 $this->wrap_close();
875 }
876
877 /**
878 * Helper function used by `html_element`
879 *
880 * @since 1.1.0
881 * @internal
882 */
883 private function element_select( $labels, $class, $id, $name, $value, $attr, $field_options, $wrapper_class ) {
884 $options = $this->select_options( $field_options, $value );
885
886 $this->wrap_open( 'select', $class, 'span', $wrapper_class );
887 $this->element_label( $labels );
888
889 printf(
890 '<select id="%1$s" class="wpmui-field-input wpmui-field-select %2$s" name="%3$s" %4$s>%5$s</select>',
891 esc_attr( $id ),
892 esc_attr( $class ),
893 esc_attr( $name ),
894 $attr,
895 $options
896 );
897
898 $this->element_hint( $labels );
899 $this->wrap_close();
900 }
901
902 /**
903 * Helper function used by `html_element`
904 *
905 * @since 1.1.0
906 * @internal
907 */
908 private function element_radio( $labels, $class, $id, $name, $value, $attr, $field_options, $wrapper_class ) {
909 $this->wrap_open( 'radio', $class, 'span', $wrapper_class );
910 $this->element_label( $labels );
911
912 foreach ( $field_options as $key => $option ) {
913 if ( is_array( $option ) ) {
914 self::$core->array->equip( $option, 'text', 'desc', 'disabled' );
915 $item_text = $option['text'];
916 $item_desc = $option['desc'];
917 $item_disabled = self::$core->is_true( $option['disabled'] );
918 } else {
919 $item_text = $option;
920 $item_desc = '';
921 $item_disabled = false;
922 }
923
924 $checked = checked( $value, $key, false );
925 $item_attr = $attr;
926 $item_class = $class;
927 if ( $item_disabled ) {
928 $item_attr .= ' disabled="disabled"';
929 $item_class .= ' disabled';
930 }
931 $radio_desc = '';
932
933 if ( ! empty( $item_desc ) ) {
934 $radio_desc = sprintf( '<div class="wpmui-input-description"><p>%1$s</p></div>', $item_desc );
935 }
936
937 printf(
938 '<div class="wpmui-radio-input-wrapper %1$s wpmui-%2$s"><label class="wpmui-field-label" for="%4$s_%2$s"><input class="wpmui-field-input wpmui-radio %1$s" type="radio" name="%3$s" id="%4$s_%2$s" value="%2$s" %5$s /><span class="wpmui-radio-caption">%6$s</span>%7$s</label></div>',
939 esc_attr( $item_class ),
940 esc_attr( $key ),
941 esc_attr( $name ),
942 esc_attr( $id ),
943 $item_attr . $checked,
944 $item_text,
945 $radio_desc
946 );
947 }
948
949 $this->element_hint( $labels );
950 $this->wrap_close();
951 }
952
953 /**
954 * Helper function used by `html_element`
955 *
956 * @since 1.1.0
957 * @internal
958 */
959 private function element_checkbox( $labels, $class, $id, $name, $value, $attr, $itemlist, $options ) {
960 $item_desc = '';
961 if ( ! empty( $labels->desc ) ) {
962 $item_desc = sprintf( '<div class="wpmui-field-description"><p>%1$s</p></div>', $labels->desc );
963 }
964 $listitems = array();
965
966 if ( ! empty( $itemlist ) ) {
967 // Multiple items in the checkbox list.
968 printf(
969 '<div class="wpmui-checkbox-title">%1$s %2$s</div><div class="wpmui-checkbox-list wpmui-field-input">%3$s',
970 $labels->title,
971 $labels->tooltip,
972 $item_desc
973 );
974 $item_desc = '';
975
976 if ( ! is_array( $value ) ) {
977 $value = array( $value );
978 }
979
980 foreach ( $itemlist as $key => $item ) {
981 $tmp_items = array();
982 if ( is_array( $item ) ) {
983 $tmp_items[] = array(
984 'name' => false,
985 'label' => $key,
986 'value' => false,
987 'parent' => true,
988 );
989 foreach ( $item as $sub_key => $sub_item ) {
990 $tmp_items[] = array(
991 'name' => $name . '[]',
992 'label' => $sub_item,
993 'value' => $sub_key,
994 'child' => true,
995 );
996 }
997 } else {
998 $tmp_items[] = array(
999 'name' => $name . '[]',
1000 'label' => $item,
1001 'value' => $key,
1002 );
1003 }
1004
1005 foreach ( $tmp_items as $tmp_item ) {
1006 $item_label = sprintf(
1007 '<div class="wpmui-checkbox-caption">%1$s</div>',
1008 $tmp_item['label']
1009 );
1010
1011 $tmp_item['label'] = $item_label;
1012 $tmp_item['checked'] = checked( in_array( $tmp_item['value'], $value ), true, false );
1013 $tmp_item['child'] = empty( $tmp_item['child'] ) ? false : true;
1014 $tmp_item['parent'] = empty( $tmp_item['parent'] ) ? false : true;
1015
1016 $listitems[] = $tmp_item;
1017 }
1018 }
1019 } else {
1020 // Single checkbox item.
1021 $item_label = '';
1022 if ( empty( $options['checkbox_position'] )
1023 || 'left' === $options['checkbox_position']
1024 ) {
1025 $item_label = sprintf(
1026 '<div class="wpmui-checkbox-caption">%1$s %2$s</div>',
1027 $labels->title,
1028 $labels->tooltip
1029 );
1030 }
1031
1032 $listitems[] = array(
1033 'name' => $name,
1034 'label' => $item_label,
1035 'checked' => checked( $value, true, false ),
1036 'value' => 1,
1037 'child' => false,
1038 'parent' => false,
1039 );
1040 }
1041
1042 $is_group = false;
1043 foreach ( $listitems as $item ) {
1044 $item_class = $class;
1045 if ( $item['parent'] ) {
1046 $is_group = true;
1047 echo '<div class="wpmui-group">';
1048 $item_class .= ' wpmui-parent';
1049 } elseif ( $item['child'] ) {
1050 $is_group = true;
1051 $item_class .= ' wpmui-child';
1052 } elseif ( $is_group ) {
1053 echo '</div>';
1054 $is_group = false;
1055 }
1056
1057 if ( empty( $item['name'] ) ) {
1058 printf(
1059 '<label class="wpmui-checkbox-wrapper wpmui-field-label wpmui-no-checkbox %1$s">%2$s %3$s</label>',
1060 esc_attr( $item_class ),
1061 $item['label'],
1062 $item_desc
1063 );
1064 } else {
1065 printf(
1066 '<label class="wpmui-checkbox-wrapper wpmui-field-label %2$s"><input id="%1$s" class="wpmui-field-input wpmui-field-checkbox" type="checkbox" name="%3$s" value="%7$s" %4$s />%5$s %6$s</label>',
1067 esc_attr( $id ),
1068 esc_attr( $item_class ),
1069 esc_attr( $item['name'] ),
1070 $attr . $item['checked'],
1071 $item['label'],
1072 $item_desc,
1073 $item['value']
1074 );
1075 }
1076 }
1077
1078 $this->element_hint( $labels );
1079
1080 if ( ! empty( $itemlist ) ) {
1081 echo '</div>';
1082 }
1083 }
1084
1085 /**
1086 * Helper function used by `html_element`
1087 *
1088 * @since 1.1.0
1089 * @internal
1090 */
1091 private function element_wp_editor( $labels, $id, $value, $options ) {
1092 if ( empty( $id ) ) {
1093 $id = 'wpmulib-wp-editor-'.rand();
1094 }
1095 $this->element_label( $labels );
1096 wp_editor( $value, $id, $options );
1097 $this->element_hint( $labels );
1098 }
1099
1100 /**
1101 * Helper function used by `html_element`
1102 *
1103 * @since 1.1.0
1104 * @internal
1105 */
1106 private function element_button( $labels, $type, $class, $id, $name, $label, $value, $attr ) {
1107 $this->element_label( $labels );
1108
1109 printf(
1110 '<button class="wpmui-field-input button %1$s" type="%7$s" id="%2$s" name="%3$s" value="%6$s" %5$s>%4$s</button>',
1111 esc_attr( $class ),
1112 esc_attr( $id ),
1113 esc_attr( $name ),
1114 $label,
1115 $attr,
1116 $value,
1117 $type
1118 );
1119
1120 $this->element_hint( $labels );
1121 }
1122
1123 /**
1124 * Helper function used by `html_element`
1125 *
1126 * @since 1.1.0
1127 * @internal
1128 */
1129 private function element_image( $labels, $class, $id, $name, $value, $alt, $attr ) {
1130 $this->element_label( $labels );
1131
1132 printf(
1133 '<input type="image" class="wpmui-field-input wpmui-input-image %1$s" id="%2$s" name="%3$s" border="0" src="%4$s" alt="%5$s" %6$s/>',
1134 esc_attr( $class ),
1135 esc_attr( $id ),
1136 esc_attr( $name ),
1137 esc_url( $value ),
1138 esc_attr( $alt ),
1139 $attr
1140 );
1141
1142 $this->element_hint( $labels );
1143 }
1144
1145 /**
1146 * Helper function used by `html_element`
1147 *
1148 * @since 1.1.0
1149 * @internal
1150 */
1151 private function element_radioslider( $labels, $class, $id, $name, $state, $url, $read_only, $attr, $options, $wrapper_class ) {
1152 $options = self::$core->array->get( $options );
1153 if ( ! isset( $options['active'] ) ) { $options['active'] = true; }
1154 if ( ! isset( $options['inactive'] ) ) { $options['inactive'] = false; }
1155
1156 if ( $state ) { $value = $options['active']; } else { $value = $options['inactive']; }
1157
1158 $turned = ( $value ) ? 'on' : 'off';
1159
1160 $this->wrap_open( 'radio-slider', $class, 'span', $turned . ' ' . $wrapper_class );
1161 $this->element_label( $labels );
1162
1163 $attr .= ' data-states="' . esc_attr( json_encode( $options ) ) . '" ';
1164 $link_url = ! empty( $url ) ? '<a href="' . esc_url( $url ) . '"></a>' : '';
1165
1166 $attr_input = '';
1167 if ( ! $read_only ) {
1168 $attr_input = sprintf(
1169 '<input class="wpmui-field-input wpmui-hidden" type="hidden" id="%1$s" name="%2$s" value="%3$s" />',
1170 esc_attr( $id ),
1171 esc_attr( $name ),
1172 esc_attr( $value )
1173 );
1174 }
1175
1176 printf(
1177 '<div class="wpmui-radio-slider %1$s wpmui-slider-%5$s %7$s" %6$s>%8$s<div class="wpmui-toggle" %2$s>%3$s</div>%4$s%9$s</div>',
1178 esc_attr( $turned ),
1179 $attr,
1180 $link_url,
1181 $attr_input,
1182 esc_attr( $id ),
1183 $read_only,
1184 esc_attr( $class ),
1185 '<span class="before"></span>',
1186 '<span class="after"></span>'
1187 );
1188 if ( ! empty( $labels->title ) ) {
1189 $this->element_desc( $labels );
1190 }
1191 $this->element_hint( $labels );
1192 $this->wrap_close();
1193 }
1194
1195 /**
1196 * Helper function used by `html_element`
1197 *
1198 * @since 1.1.0
1199 * @internal
1200 */
1201 private function element_tagselect( $labels, $class, $id, $name, $value, $field_options, $attr, $ajax_data, $empty_text, $button_text, $title_selected, $wrapper_class ) {
1202 $labels->id = '_src_' . $id;
1203
1204 $this->wrap_open( 'tag-selector', $class, 'span', $wrapper_class );
1205 $this->element_label( $labels );
1206
1207 $options_selected = '';
1208 $options_available = '<option value=""></option>';
1209 if ( ! is_array( $value ) ) {
1210 $value = array( $value );
1211 }
1212
1213 if ( empty( $field_options ) ) {
1214 // No values available, display a note instead of the input elements.
1215 printf(
1216 '<div id="%1$s" class="wpmui-no-data wpmui-field-input %2$s">%3$s</div>',
1217 esc_attr( $id ),
1218 esc_attr( $class ),
1219 $empty_text
1220 );
1221 } else {
1222 // There are values to select or remove. Display the input elements.
1223 $options_selected .= $this->select_options( $field_options, $value );
1224 $options_available .= $this->select_options( $field_options, $value, 'taglist' );
1225
1226 $src_class = str_replace( 'wpmui-ajax-update', '', $class );
1227
1228 // First Select: The value selected here can be added to the tag-list.
1229 printf(
1230 '<select id="_src_%1$s" class="wpmui-field-input wpmui-tag-source %2$s" %4$s>%5$s</select>',
1231 esc_attr( $id ),
1232 esc_attr( $src_class ),
1233 esc_attr( $name ),
1234 $attr,
1235 $options_available
1236 );
1237
1238 // Button: Add element from First Select to Second Select.
1239 printf(
1240 '<button id="_src_add_%1$s" class="wpmui-field-input wpmui-tag-button button %2$s" type="button">%3$s</button>',
1241 esc_attr( $id ),
1242 esc_attr( $src_class ),
1243 $button_text
1244 );
1245
1246 $label_tag = $labels;
1247 $label_tag->id = $id;
1248 $label_tag->title = $title_selected;
1249 $label_tag->id = $id;
1250 $label_tag->tooltip = '';
1251 $label_tag->tooltip_code = '';
1252 $label_tag->class .= ' wpmui-tag-label';
1253 $this->element_label( $label_tag );
1254
1255 // Second Select: The actual tag-list
1256 printf(
1257 '<select id="%1$s" class="wpmui-field-input wpmui-field-select wpmui-tag-data %2$s" multiple="multiple" readonly="readonly" %4$s>%5$s</select>',
1258 esc_attr( $id ),
1259 esc_attr( $class ),
1260 esc_attr( $name ),
1261 $ajax_data,
1262 $options_selected
1263 );
1264 }
1265
1266 $this->element_hint( $labels );
1267 $this->wrap_close();
1268 }
1269
1270 /**
1271 * Helper function used by `html_element`
1272 *
1273 * @since 1.1.0
1274 * @internal
1275 */
1276 private function element_wp_pages( $labels, $class, $id, $name, $value, $attr, $field_options, $wrapper_class ) {
1277 $defaults = array(
1278 'hierarchical' => 1,
1279 'sort_column' => 'post_title',
1280 'sort_order' => 'ASC',
1281 'no_item' => '(Select a page)',
1282 );
1283 $args = wp_parse_args( $field_options, $defaults );
1284
1285 $pages = get_pages( $args );
1286 $parent_list = array();
1287 $items = array();
1288
1289 foreach ( $pages as $page ) {
1290 $parent_list[ $page->ID ] = $page;
1291 }
1292
1293 if ( ! array_key_exists( $value, $parent_list ) ) {
1294 // In case no value is selected set the default to 'no item';
1295 $items[ $value ] = $args['no_item'];
1296 }
1297
1298 foreach ( $pages as $page_id => $page ) {
1299 $level = 0;
1300 $parent = $page;
1301 while ( $parent->post_parent ) {
1302 $parent = $parent_list[ $parent->post_parent ];
1303 $level += 1;
1304 }
1305
1306 if ( 0 === strlen( $page->post_title ) ) {
1307 $label = sprintf(
1308 '#%1$s (%2$s)',
1309 $page->ID,
1310 $page->post_name
1311 );
1312 } else {
1313 $label = $page->post_title;
1314 }
1315
1316 $items[ $page->ID ] = str_repeat( '&nbsp;&mdash;&nbsp;', $level ) . $label;
1317 }
1318
1319 $this->element_select(
1320 $labels,
1321 $class . ' wpmui-wp-pages',
1322 $id,
1323 $name,
1324 $value,
1325 $attr,
1326 $items,
1327 $wrapper_class
1328 );
1329 }
1330
1331 /**
1332 * Helper function used by `html_element`
1333 *
1334 * @since 1.1.0
1335 * @internal
1336 */
1337 private function element_separator( $type = 'horizontal' ) {
1338 if ( 'v' === $type[0] ) {
1339 echo '<div class="wpmui-divider"></div>';
1340 } else {
1341 echo '<div class="wpmui-separator"></div>';
1342 }
1343 }
1344
1345 /**
1346 * Helper function used by `html_element`
1347 *
1348 * @since 1.1.0
1349 * @internal
1350 */
1351 private function element_link( $labels, $class, $id, $label, $url, $attr, $target ) {
1352 $this->element_desc( $labels );
1353
1354 if ( empty( $labels->title ) ) {
1355 $title = $label;
1356 } else {
1357 $title = $labels->title;
1358 }
1359
1360 printf(
1361 '<a id="%1$s" title="%2$s" class="wpmui-link %3$s" href="%4$s" target="%7$s" %6$s>%5$s</a>',
1362 esc_attr( $id ),
1363 esc_attr( strip_tags( $title ) ),
1364 esc_attr( $class ),
1365 esc_url( $url ),
1366 $label,
1367 $attr,
1368 $target
1369 );
1370
1371 $this->element_hint( $labels );
1372 }
1373
1374 /**
1375 * Helper function used by `html_element`
1376 *
1377 * @since 1.1.0
1378 * @internal
1379 */
1380 private function element_wrapper( $labels, $class, $id, $code, $wrap, $wrapper_class ) {
1381 if ( empty( $wrap ) ) { $wrap = 'span'; }
1382
1383 $this->wrap_open( 'html-text', $class, 'span', $wrapper_class );
1384 $this->element_label( $labels );
1385
1386 printf(
1387 '<%1$s class="%2$s">%3$s</%1$s>',
1388 esc_attr( $wrap ),
1389 esc_attr( $class ),
1390 $code
1391 );
1392
1393 $this->element_hint( $labels );
1394 $this->wrap_close();
1395 }
1396
1397 /**
1398 * Helper function used by `html_element`
1399 *
1400 * @since 1.1.0
1401 * @internal
1402 */
1403 private function element_table( $labels, $class, $id, $rows, $args, $wrapper_class ) {
1404 self::$core->array->equip( $args, 'head_row', 'head_col', 'col_class' );
1405
1406 $this->wrap_open( 'table', $class, 'span', $wrapper_class );
1407 $this->element_label( $labels );
1408
1409 $code_body = '';
1410 $code_head = '';
1411
1412 if ( is_array( $rows ) ) {
1413 $args['col_class'] = self::$core->array->get( $args['col_class'] );
1414
1415 foreach ( $rows as $row_num => $row ) {
1416 $code_row = '';
1417 $is_head_row = false;
1418 $row_class = $row_num % 2 === 0 ? '' : 'alternate';
1419
1420 if ( 0 === $row_num && $args['head_row'] ) {
1421 $is_head_row = true;
1422 }
1423
1424 if ( is_array( $row ) ) {
1425 foreach ( $row as $col_num => $col ) {
1426 $is_head = $is_head_row
1427 || ( 0 === $col_num && $args['head_col'] );
1428
1429 $col_class = isset( $args['col_class'][ $col_num ] )
1430 ? $args['col_class'][ $col_num ]
1431 : '';
1432
1433 $code_row .= sprintf(
1434 '<%1$s class="%3$s">%2$s</%1$s>',
1435 ($is_head ? 'th' : 'td'),
1436 $col,
1437 $col_class
1438 );
1439 }
1440 } else {
1441 $code_row = $row;
1442 }
1443
1444 $code_row = sprintf(
1445 '<tr class="%2$s">%1$s</tr>',
1446 $code_row,
1447 $row_class
1448 );
1449
1450 if ( $is_head_row ) {
1451 $code_head .= $code_row;
1452 } else {
1453 $code_body .= $code_row;
1454 }
1455 }
1456
1457 printf(
1458 '<table class="wpmui-html-table %1$s">%2$s%3$s</table>',
1459 esc_attr( $class ),
1460 '<thead>' . $code_head . '</thead>',
1461 '<tbody>' . $code_body . '</tbody>'
1462 );
1463 }
1464
1465 $this->element_hint( $labels );
1466 $this->wrap_close();
1467 }
1468
1469 /**
1470 * Returns HTML code containing options used to build a select tag.
1471 *
1472 * @since 1.1.0
1473 * @internal
1474 *
1475 * @param array $list List items as 'key => value' pairs.
1476 * @param array|string $value The selected value.
1477 * @param string $type Either 'default' or 'taglist'.
1478 *
1479 * @return string
1480 */
1481 private function select_options( $list, $value = '', $type = 'default' ) {
1482 $options = '';
1483 $list = self::$core->array->get( $list );
1484
1485 foreach ( $list as $key => $option ) {
1486 if ( is_array( $option ) ) {
1487 if ( empty( $option ) ) { continue; }
1488 $options .= sprintf(
1489 '<optgroup label="%1$s">%2$s</optgroup>',
1490 $key,
1491 $this->select_options( $option, $value, $type )
1492 );
1493 } else {
1494 $attr = '';
1495 if ( is_object( $option ) ) {
1496 if ( isset( $option->attr ) ) { $attr = $option->attr; }
1497 if ( isset( $option->label ) ) { $option = $option->label; }
1498 }
1499 if ( empty( $option ) ) { continue; }
1500
1501 if ( is_array( $value ) ) {
1502 $is_selected = ( in_array( $key, $value ) );
1503 } else {
1504 $is_selected = $key == $value;
1505 }
1506
1507 switch ( $type ) {
1508 case 'default':
1509 $attr .= selected( $is_selected, true, false );
1510 $options .= sprintf(
1511 '<option value="%1$s" %2$s>%3$s</option>',
1512 esc_attr( $key ),
1513 $attr,
1514 $option
1515 );
1516 break;
1517
1518 case 'taglist':
1519 $attr .= ($is_selected ? 'disabled="disabled"' : '');
1520 $options .= sprintf(
1521 '<option value="%1$s" %2$s>%3$s</option>',
1522 esc_attr( $key ),
1523 $attr,
1524 $option
1525 );
1526 break;
1527 }
1528 }
1529 }
1530
1531 return $options;
1532 }
1533
1534 /**
1535 * Output the opening tag of an input wrapper.
1536 *
1537 * @since 2.0.0
1538 * @internal
1539 *
1540 * @param string $type Wrapper type, class is set to 'wpmui-$type-wrapper'.
1541 * @param string $classes String or array containing additional classes.
1542 * All classes are extended with '-wrapper'.
1543 * @param string $tag Optional. The tag name, default 'span'
1544 * @param string $raw_classes String or array containing additional classes.
1545 * These classes are not modified, but output as they appear.
1546 */
1547 private function wrap_open( $type, $classes = '', $tag = 'span', $raw_classes = '' ) {
1548 if ( is_string( $classes ) ) {
1549 $classes = explode( ' ', $classes );
1550 }
1551
1552 if ( count( $classes ) ) {
1553 $classes = array_filter( array_map( 'trim', $classes ) );
1554 $classes = array_map( 'strtolower', $classes );
1555 $extra_classes = implode( '-wrapper ', $classes );
1556 if ( ! empty( $extra_classes ) ) { $extra_classes .= '-wrapper'; }
1557 } else {
1558 $extra_classes = '';
1559 }
1560
1561 if ( ! empty( $raw_classes ) ) {
1562 if ( is_array( $raw_classes ) ) {
1563 $extra_classes .= implode( ' ', $raw_classes );
1564 } else {
1565 $extra_classes .= ' ' . $raw_classes;
1566 }
1567 }
1568 $extra_classes = trim( $extra_classes );
1569
1570 printf(
1571 '<%1$s class="wpmui-wrapper wpmui-%2$s-wrapper %3$s">',
1572 $tag,
1573 $type,
1574 $extra_classes
1575 );
1576 }
1577
1578 /**
1579 * Output the closing tag of an input wrapper.
1580 *
1581 * @since 2.0.0
1582 * @internal
1583 *
1584 * @param string $tag Optional. The tag name, default 'span'
1585 */
1586 private function wrap_close( $tag = 'span' ) {
1587 printf( '</%1$s>', $tag );
1588 }
1589
1590 /**
1591 * Helper function used by `html_element`
1592 *
1593 * @since 1.1.0
1594 * @internal
1595 */
1596 private function element_label( $labels ) {
1597 if ( ! empty( $labels->title ) ) {
1598 printf(
1599 '<%5$s for="%1$s" class="wpmui-field-label %4$s">%2$s %3$s</%5$s>',
1600 esc_attr( $labels->id ),
1601 $labels->title,
1602 $labels->tooltip_code,
1603 esc_attr( ' wpmui-label-' . $labels->id . ' ' . $labels->class ),
1604 esc_attr( $labels->label_type )
1605 );
1606 } else {
1607 $this->element_desc( $labels );
1608 }
1609 }
1610
1611 /**
1612 * Helper function used by `html_element`
1613 *
1614 * @since 1.1.0
1615 * @internal
1616 */
1617 private function element_desc( $labels ) {
1618 if ( ! empty( $labels->desc ) ) {
1619 printf(
1620 '<label class="wpmui-field-description %2$s" for="%3$s">%1$s</label >',
1621 $labels->desc,
1622 esc_attr( 'wpmui-description-' . $labels->id . ' ' . $labels->class ),
1623 esc_attr( $labels->id )
1624 );
1625 }
1626
1627 if ( ! empty( $labels->before ) ) {
1628 printf(
1629 '<span class="wpmui-label-before">%s</span>',
1630 $labels->before
1631 );
1632 }
1633 }
1634
1635 /**
1636 * Helper function used by `html_element`
1637 *
1638 * @since 1.1.0
1639 * @internal
1640 */
1641 private function element_hint( $labels ) {
1642 if ( ! empty( $labels->after ) ) {
1643 printf(
1644 '<span class="wpmui-label-after">%s</span>',
1645 $labels->after
1646 );
1647 }
1648
1649 if ( empty( $labels->title ) ) {
1650 echo $labels->tooltip_code;
1651 }
1652 }
1653
1654 /**
1655 * Method for outputting tooltips.
1656 *
1657 * @since 1.1.0
1658 * @api
1659 *
1660 * @param string $tip The tooltip to display.
1661 * @param bool $return Optional. If true then the HTML code is returned as
1662 * function return value. Otherwise echo'ed.
1663 *
1664 * @return string|void Depending on param $return either nothing or HTML code.
1665 */
1666 public function tooltip( $tip = '', $return = false ) {
1667 if ( empty( $tip ) ) { return; }
1668
1669 if ( $return ) { ob_start(); }
1670
1671 $this->wrap_open( 'tooltip', '', 'div' );
1672 ?>
1673 <div class="wpmui-tooltip-wrapper">
1674 <div class="wpmui-tooltip-info"><i class="wpmui-fa wpmui-fa-info-circle"></i></div>
1675 <div class="wpmui-tooltip">
1676 <div class="wpmui-tooltip-button">&times;</div>
1677 <div class="wpmui-tooltip-content">
1678 <?php echo $tip; ?>
1679 </div>
1680 </div>
1681 <?php
1682 $this->wrap_close( 'div' );
1683
1684 if ( $return ) { return ob_get_clean(); }
1685 }
1686
1687 /**
1688 * Enqueue wp-color-picker
1689 *
1690 * @since 3.0.5
1691 * @internal
1692 */
1693 private function _enqueue_color_picker() {
1694 wp_enqueue_script( 'wp-color-picker' );
1695 wp_enqueue_style( 'wp-color-picker' );
1696 }
1697
1698 /**
1699 * Helper function used by `wp-color-picker`
1700 *
1701 * @since 3.0.5
1702 * @internal
1703 */
1704 private function element_color_picker( $labels, $class, $id, $name, $value, $attr, $wrapper_class ) {
1705 $this->_enqueue_color_picker();
1706 $this->wrap_open( 'colorpicker', $class, 'span', $wrapper_class );
1707 $this->element_label( $labels );
1708 printf(
1709 '<input class="wpmui-color-field %1$s" type="text" id="%2$s" name="%3$s" value="%4$s" %5$s />',
1710 esc_attr( $class ),
1711 esc_attr( $id ),
1712 esc_attr( $name ),
1713 esc_attr( $value ),
1714 $attr
1715 );
1716 $this->element_hint( $labels );
1717 $this->wrap_close();
1718 }
1719
1720 /**
1721 * Helper function used by `html_element`
1722 *
1723 * @since 1.1.0
1724 * @internal
1725 */
1726 private function element_wp_media( $labels, $class, $id, $name, $value, $attr, $wrapper_class ) {
1727 $image_src = wp_get_attachment_image_url( $value );
1728 wp_enqueue_media();
1729 $this->element_label( $labels );
1730 $content = sprintf( '<div class="wp-media-wrapper %s">', esc_attr( empty( $image_src )? 'hidden':'' ) );
1731 $content .= '<div class="image-preview-wrapper">';
1732 $content .= sprintf(
1733 '<img class="image-preview" src="%s" />',
1734 esc_url( $image_src )
1735 );
1736 $content .= '</div>';
1737 $content .= '<span class="filename"></span>';
1738 $content .= sprintf(
1739 '<a href="#" class="image-reset %s">%s</a>',
1740 esc_attr( $image_src? '': 'disabled' ),
1741 esc_html__( 'Clear' )
1742 );
1743 $content .= '</div>';
1744 $content .= sprintf(
1745 '<input type="button" class="button button-select-image" value="%s" />',
1746 esc_attr__( 'Browse' )
1747 );
1748 $content .= sprintf(
1749 '<input type="hidden" name="%s" value="%s" class="attachment-id" />',
1750 esc_attr( $name ),
1751 esc_attr( $value )
1752 );
1753 echo $content;
1754 $this->element_hint( $labels );
1755 }
1756 }
1757