TheLib_Ui

The UI component.

Defined (1)

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

/lib/wpmu-lib/inc/class-thelib-ui.php  
  1. class TheLib_Ui extends TheLib { 
  2.  
  3. // Load the main JS module (the wpmUi object) and basic styles. 
  4. const MODULE_CORE = 'core'; 
  5.  
  6. // Load CSS animations. 
  7. const MODULE_ANIMATION = 'animate'; 
  8.  
  9. // Custom select2 integration. JS: wpmUi.upgrade_multiselect() 
  10. const MODULE_SELECT = 'select'; 
  11.  
  12. // Vertical navigation support. 
  13. const MODULE_VNAV = 'vnav'; 
  14.  
  15. // Styles for lib3()->html->element() output. 
  16. const MODULE_HTML = 'html_element'; 
  17.  
  18. // WordPress media gallery support. 
  19. const MODULE_MEDIA = 'media'; 
  20.  
  21. // Fontawesome CSS icons. 
  22. const MODULE_ICONS = 'fontawesome'; 
  23.  
  24. // jQuery datepicker, draggable, jQuery-UI styles. 
  25. const MODULE_JQUERY = 'jquery-ui'; 
  26.  
  27. /** 
  28. * Class constructor 
  29. * @since 1.0.0 
  30. * @internal 
  31. */ 
  32. public function __construct() { 
  33. parent::__construct(); 
  34.  
  35. // Check for persistent data from last request that needs to be processed. 
  36. $this->add_action( 
  37. 'plugins_loaded',  
  38. '_check_admin_notices' 
  39. ); 
  40.  
  41. /** 
  42. * Enqueue core UI files (CSS/JS). 
  43. * Defined modules: 
  44. * - core 
  45. * - select 
  46. * - vnav 
  47. * - card-list 
  48. * - html-element 
  49. * - media 
  50. * - fontawesome 
  51. * - jquery-ui 
  52. * All undefined modules are assumed to be a valid CSS or JS file-name. 
  53. * @since 1.0.0 
  54. * @api 
  55. * @param string $modules The module to load. 
  56. * @param string $onpage A page hook; files will only be loaded on this page. 
  57. */ 
  58. public function add( $module = 'core', $onpage = 'all' ) { 
  59. switch ( $module ) { 
  60. case 'core': 
  61. $this->css( $this->_css_url( 'wpmu-ui.3.min.css' ), $onpage ); 
  62. $this->js( $this->_js_url( 'wpmu-ui.3.min.js' ), $onpage ); 
  63. break; 
  64.  
  65. case 'animate': 
  66. case 'animation': 
  67. $this->css( $this->_css_url( 'animate.3.min.css' ), $onpage ); 
  68. break; 
  69.  
  70. case 'select': 
  71. $this->css( $this->_css_url( 'select2.3.min.css' ), $onpage ); 
  72. $this->js( $this->_js_url( 'select2.3.min.js' ), $onpage ); 
  73. break; 
  74.  
  75. case 'vnav': 
  76. $this->css( $this->_css_url( 'wpmu-vnav.3.min.css' ), $onpage ); 
  77. $this->js( $this->_js_url( 'wpmu-vnav.3.min.js' ), $onpage ); 
  78. break; 
  79.  
  80. case 'html-element': 
  81. case 'html_element': 
  82. case 'html': 
  83. $this->css( $this->_css_url( 'wpmu-html.3.min.css' ), $onpage ); 
  84. break; 
  85.  
  86. case 'media': 
  87. $this->js( 'wpmu:media', $onpage ); 
  88. break; 
  89.  
  90. case 'fontawesome': 
  91. case 'icons': 
  92. $this->css( $this->_css_url( 'fontawesome.3.min.css' ), $onpage ); 
  93. break; 
  94.  
  95. case 'jquery-ui': 
  96. case 'jquery': 
  97. $this->js( 'jquery-ui-core', $onpage ); 
  98. $this->js( 'jquery-ui-datepicker', $onpage ); 
  99. $this->js( 'jquery-ui-draggable', $onpage ); 
  100. $this->css( $this->_css_url( 'jquery-ui.wpmui.3.min.css' ), $onpage ); 
  101. break; 
  102.  
  103. default: 
  104. $ext = strrchr( $module, '.' ); 
  105.  
  106. if ( WDEV_UNMINIFIED ) { 
  107. $module = str_replace( '.min' . $ext, $ext, $module ); 
  108. if ( '.css' === $ext ) { 
  109. $this->css( $module, $onpage, 20 ); 
  110. } else if ( '.js' === $ext ) { 
  111. $this->js( $module, $onpage, 20 ); 
  112.  
  113. /** 
  114. * Adds a variable to javascript. 
  115. * @since 1.0.7 
  116. * @api 
  117. * @param string $name Name of the variable 
  118. * @param mixed $data Value of the variable 
  119. */ 
  120. public function data( $name, $data ) { 
  121. $this->_add( 'js_data_hook', true ); 
  122.  
  123. // Determine which hook should print the data. 
  124. $hook = ( is_admin() ? 'admin_footer' : 'wp_footer' ); 
  125.  
  126. // Enqueue the data for output with javascript sources. 
  127. $this->_add( 'js_data', array( $name, $data ) ); 
  128.  
  129. $this->add_action( $hook, '_print_script_data' ); 
  130.  
  131. /** 
  132. * Adds custom javascript to the page footer. 
  133. * @since 1.1.3 
  134. * @api 
  135. * @param string $jscript The javascript code. 
  136. */ 
  137. public function script( $jscript ) { 
  138. $this->_add( 'js_data_hook', true ); 
  139.  
  140. // Determine which hook should print the data. 
  141. $hook = ( is_admin() ? 'admin_footer' : 'wp_footer' ); 
  142.  
  143. // Enqueue the data for output with javascript sources. 
  144. $this->_add( 'js_script', $jscript ); 
  145.  
  146. $this->add_action( $hook, '_print_script_code' ); 
  147.  
  148. /** 
  149. * Enqueue a javascript file. 
  150. * @since 1.0.0 
  151. * @api 
  152. * @param string $url Full URL to the javascript file. 
  153. * @param string $onpage A page hook; files will only be loaded on this page. 
  154. * @param int $priority Loading order. The higher the number, the later it is loaded. 
  155. */ 
  156. public function js( $url, $onpage = 'all', $priority = 10 ) { 
  157. $this->_prepare_js_or_css( $url, 'js', $onpage, $priority ); 
  158.  
  159. /** 
  160. * Enqueue a css file. 
  161. * @since 1.0.0 
  162. * @api 
  163. * @param string $url Full URL to the css filename. 
  164. * @param string $onpage A page hook; files will only be loaded on this page. 
  165. * @param int $priority Loading order. The higher the number, the later it is loaded. 
  166. */ 
  167. public function css( $url, $onpage = 'all', $priority = 10 ) { 
  168. $this->_prepare_js_or_css( $url, 'css', $onpage, $priority ); 
  169.  
  170. /** 
  171. * Prepare to enqueue a javascript or css file. 
  172. * @since 1.0.7 
  173. * @internal 
  174. * @param string $url Full URL to the javascript/css file. 
  175. * @param string $type 'css' or 'js' 
  176. * @param string $onpage A page hook; files will only be loaded on this page. 
  177. * @param int $priority Loading order. The higher the number, the later it is loaded. 
  178. */ 
  179. protected function _prepare_js_or_css( $url, $type, $onpage, $priority ) { 
  180. $this->_add( 'js_or_css', compact( 'url', 'type', 'onpage', 'priority' ) ); 
  181.  
  182. $this->add_action( 'init', '_add_js_or_css' ); 
  183.  
  184. /** 
  185. * Returns the JS/CSS handle of the item. 
  186. * This is a private helper function used by array_map() 
  187. * @since 1.0.7 
  188. * @internal 
  189. */ 
  190. public function _get_script_handle( $item ) { 
  191. if ( ! property_exists( $item, 'handle' ) ) { 
  192. $item->handle = ''; 
  193.  
  194. return $item->handle; 
  195.  
  196. /** 
  197. * Enqueues either a css or javascript file 
  198. * @since 1.0.0 
  199. * @internal 
  200. */ 
  201. public function _add_js_or_css() { 
  202. global $wp_styles, $wp_scripts; 
  203.  
  204. $scripts = $this->_get( 'js_or_css' ); 
  205. $this->_clear( 'js_or_css' ); 
  206.  
  207. // Prevent adding the same URL twice. 
  208. $done_urls = array(); 
  209.  
  210. foreach ( $scripts as $script ) { 
  211. extract( $script ); // url, type, onpage, priority 
  212.  
  213. // Skip Front-End files in Admin Dashboard. 
  214. if ( 'front' === $onpage && is_admin() ) { continue; } 
  215.  
  216. // Prevent adding the same URL twice. 
  217. if ( in_array( $url, $done_urls ) ) { continue; } 
  218. $done_urls[] = $url; 
  219.  
  220. $type = ( 'css' === $type || 'style' === $type ? 'css' : 'js' ); 
  221.  
  222. // The $handle values are intentionally not cached: 
  223. // Any plugin/theme could add new handles at any moment... 
  224. $handles = array(); 
  225. if ( 'css' == $type ) { 
  226. if ( ! is_a( $wp_styles, 'WP_Styles' ) ) { 
  227. $wp_styles = new WP_Styles(); 
  228. $handles = array_values( 
  229. array_map( 
  230. array( $this, '_get_script_handle' ),  
  231. $wp_styles->registered 
  232. ); 
  233. $type_callback = '_enqueue_style_callback'; 
  234. } else { 
  235. if ( ! is_a( $wp_scripts, 'WP_Scripts' ) ) { 
  236. $wp_scripts = new WP_Scripts(); 
  237. $handles = array_values( 
  238. array_map( 
  239. array( $this, '_get_script_handle' ),  
  240. $wp_scripts->registered 
  241. ); 
  242. $type_callback = '_enqueue_script_callback'; 
  243.  
  244. if ( in_array( $url, $handles ) ) { 
  245. $alias = $url; 
  246. $url = ''; 
  247. } else { 
  248. // Get the filename from the URL, then sanitize it and prefix "wpmu-" 
  249. $urlparts = explode( '?', $url, 2 ); 
  250. $alias = 'wpmu-' . sanitize_title( basename( $urlparts[0] ) ); 
  251. $onpage = empty( $onpage ) ? 'all' : $onpage; 
  252.  
  253. if ( ! is_admin() ) { 
  254. $hook = 'wp_enqueue_scripts'; 
  255. } else { 
  256. $hook = 'admin_enqueue_scripts'; 
  257.  
  258. $item = compact( 'url', 'alias', 'onpage' ); 
  259. $this->_add( $type, $item ); 
  260.  
  261. $this->add_action( $hook, $type_callback, 100 + $priority ); 
  262.  
  263. /** 
  264. * Action hook for enqueue style (for PHP <5.3 only) 
  265. * @since 1.0.1 
  266. * @internal 
  267. */ 
  268. public function _enqueue_style_callback() { 
  269. global $hook_suffix; 
  270.  
  271. $items = $this->_get( 'css' ); 
  272. $this->_clear( 'css' ); 
  273. $hook = $hook_suffix; 
  274.  
  275. if ( empty( $hook ) ) { $hook = 'front'; } 
  276.  
  277. foreach ( $items as $item ) { 
  278. extract( $item ); // url, alias, onpage 
  279.  
  280. if ( empty( $onpage ) ) { $onpage = 'all'; } 
  281.  
  282. // onpage == 'all' will always load the script. 
  283. // otherwise onpage must match the enqueue-hook. 
  284. if ( 'all' == $onpage || $hook == $onpage ) { 
  285. if ( empty( $url ) ) { 
  286. wp_enqueue_style( $alias ); 
  287. } else { 
  288. wp_enqueue_style( $alias, $url ); 
  289.  
  290. /** 
  291. * Action hook for enqueue script (for PHP <5.3 only) 
  292. * @since 1.0.1 
  293. * @internal 
  294. */ 
  295. public function _enqueue_script_callback() { 
  296. global $hook_suffix; 
  297.  
  298. $items = $this->_get( 'js' ); 
  299. $this->_clear( 'js' ); 
  300. $hook = $hook_suffix; 
  301.  
  302. if ( empty( $hook ) ) { $hook = 'front'; } 
  303.  
  304. foreach ( $items as $item ) { 
  305. extract( $item ); // url, alias, onpage 
  306.  
  307. if ( empty( $onpage ) ) { $onpage = 'all'; } 
  308.  
  309. // onpage == 'all' will always load the script. 
  310. // otherwise onpage must match the enqueue-hook. 
  311. if ( 'all' == $onpage || $hook == $onpage ) { 
  312. // Load the Media-library functions. 
  313. if ( 'wpmu:media' === $url ) { 
  314. wp_enqueue_media(); 
  315. continue; 
  316.  
  317. // Register script if it has an URL. 
  318. if ( ! empty( $url ) ) { 
  319. wp_register_script( $alias, $url, array( 'jquery' ), false, true ); 
  320.  
  321. // Enqueue the script for output in the page footer. 
  322. wp_enqueue_script( $alias ); 
  323.  
  324. /** 
  325. * Prints extra script data to the page. 
  326. * @action `wp_head` 
  327. * @since 1.1.1 
  328. * @internal 
  329. */ 
  330. public function _print_script_data() { 
  331. $data = $this->_get( 'js_data' ); 
  332. $this->_clear( 'js_data' ); 
  333.  
  334. // Append javascript data to the script output. 
  335. if ( is_array( $data ) ) { 
  336. $collected = array(); 
  337.  
  338. foreach ( $data as $item ) { 
  339. if ( ! is_array( $item ) ) { continue; } 
  340. $key = sanitize_html_class( $item[0] ); 
  341. $obj = array( 'window.' . $key => $item[1] ); 
  342. $collected = self::$core->array->merge_recursive_distinct( $collected, $obj ); 
  343.  
  344. echo '<script>'; 
  345. foreach ( $collected as $var => $value ) { 
  346. printf( 
  347. '%1$s = %2$s;',  
  348. $var,  
  349. json_encode( $value ) 
  350. ); 
  351. echo '</script>'; 
  352.  
  353.  
  354. /** 
  355. * Prints extra javascript code to the page. 
  356. * @action `wp_foot` 
  357. * @since 1.1.3 
  358. * @internal 
  359. */ 
  360. public function _print_script_code() { 
  361. $data = $this->_get( 'js_script' ); 
  362. $this->_clear( 'js_script' ); 
  363.  
  364. // Append javascript data to the script output. 
  365. if ( is_array( $data ) ) { 
  366. foreach ( $data as $item ) { 
  367. printf( 
  368. '<script>try { %1$s } catch( err ) { window.console.log(err.message); }</script>',  
  369. $item 
  370. ); 
  371.  
  372. /** 
  373. * Display an admin notice. 
  374. * @since 1.0.0 
  375. * @api 
  376. * @param string $text Text to display. 
  377. * @param string $class Message-type [updated|error] 
  378. * @param string $screen Limit message to this screen-ID 
  379. * @param string $id Message ID. Prevents adding duplicate messages. 
  380. */ 
  381. public function admin_message( $text, $class = '', $screen = '', $id = '' ) { 
  382. switch ( $class ) { 
  383. case 'red': 
  384. case 'err': 
  385. case 'error': 
  386. $class = 'error'; 
  387. break; 
  388.  
  389. case 'warning': 
  390. case 'orange': 
  391. $class = 'warning'; 
  392. break; 
  393.  
  394. case 'info': 
  395. case 'blue': 
  396. $class = 'info'; 
  397. break; 
  398.  
  399. default: 
  400. $class = 'updated'; 
  401. break; 
  402.  
  403. // Check if the message is already queued... 
  404. $items = self::_sess_get( 'admin_notice' ); 
  405. foreach ( $items as $key => $data ) { 
  406. if ( 
  407. $data['text'] == $text && 
  408. $data['class'] == $class && 
  409. $data['screen'] == $screen 
  410. ) { 
  411. return; // Don't add duplicate message to queue. 
  412.  
  413. /** 
  414. * `$id` prevents adding duplicate messages. 
  415. * @since 1.1.0 
  416. */ 
  417. if ( ! empty( $id ) && $data['id'] == $id ) { 
  418. return; // Don't add duplicate message to queue. 
  419.  
  420. self::_sess_add( 'admin_notice', compact( 'text', 'class', 'screen', 'id' ) ); 
  421. $this->add_action( 'admin_notices', '_admin_notice_callback', 1 ); 
  422. $this->add_action( 'network_admin_notices', '_admin_notice_callback', 1 ); 
  423.  
  424. /** 
  425. * Action hook for admin notices (for PHP <5.3 only) 
  426. * @since 1.0.1 
  427. * @internal 
  428. */ 
  429. public function _admin_notice_callback() { 
  430. $items = self::_sess_get( 'admin_notice' ); 
  431. self::_sess_clear( 'admin_notice' ); 
  432. $screen_info = get_current_screen(); 
  433. $screen_id = $screen_info->id; 
  434.  
  435. foreach ( $items as $item ) { 
  436. extract( $item ); // text, class, screen, id 
  437. if ( empty( $screen ) || $screen_id == $screen ) { 
  438. printf( 
  439. '<div class="%1$s notice notice-%1$s is-dismissible %3$s"><p>%2$s</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">%4$s</span></button></div>',  
  440. esc_attr( $class ),  
  441. $text,  
  442. esc_attr( $id ),  
  443. __( 'Dismiss this notice.' ) 
  444. ); 
  445.  
  446. /** 
  447. * Checks the DB for persistent data from last request. 
  448. * If persistent data exists the appropriate hooks are set to process them. 
  449. * @since 1.0.7 
  450. * @internal 
  451. */ 
  452. public function _check_admin_notices() { 
  453. if ( self::_sess_have( 'admin_notice' ) ) { 
  454. $this->add_action( 'admin_notices', '_admin_notice_callback', 1 ); 
  455. $this->add_action( 'network_admin_notices', '_admin_notice_callback', 1 ); 
  456.