TheLib_Html

HTML Helper functions Access via function `lib3()->html`.

Defined (1)

The class is defined in the following location(s).

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