1<?php 2/** 3 * DokuWiki Mikio Template 4 * 5 * @link http://dokuwiki.org/template:mikio 6 * @author James Collins <james.collins@outlook.com.au> 7 * @license MIT License (https://raw.githubusercontent.com/nomadjimbob/Mikio/master/LICENSE) 8 */ 9 10if (!defined('DOKU_INC')) die(); 11 12require_once('inc/simple_html_dom.php'); 13 14class MikioTemplate { 15 public $tplDir = ''; 16 public $baseDir = ''; 17 18 19 /** 20 * Class constructor 21 * 22 * @author James Collins <james.collins@outlook.com.au> 23 */ 24 public function __construct() { 25 $this->tplDir = tpl_incdir(); 26 $this->baseDir = tpl_basedir(); 27 28 $this->_registerHooks(); 29 } 30 31 32 /** 33 * Register themes DokuWiki hooks 34 * 35 * @author James Collins <james.collins@outlook.com.au> 36 */ 37 private function _registerHooks() { 38 global $EVENT_HANDLER; 39 40 $events_dispatcher = array( 41 'TPL_METAHEADER_OUTPUT' => 'metaheadersHandler', 42 'TPL_CONTENT_DISPLAY' => 'contentHandler', 43 ); 44 45 foreach ($events_dispatcher as $event => $method) { 46 $EVENT_HANDLER->register_hook($event, 'BEFORE', $this, $method); 47 } 48 } 49 50 51 /** 52 * DokuWiki META Header event handler 53 * 54 * @author James Collins <james.collins@outlook.com.au> 55 */ 56 public function metaHeadersHandler(Doku_Event $event) { 57 $stylesheets = array(); 58 $scripts = array(); 59 60 if($this->getConf('useTheme') != '') { 61 if(file_exists($this->tplDir . 'themes/' . $this->getConf('useTheme') . '/style.css')) { 62 $stylesheets[] = $this->baseDir . 'themes/' . $this->getConf('useTheme') . '/style.css'; 63 } 64 } 65 66 $stylesheets[] = $this->baseDir . 'css/mikio.css'; 67 $stylesheets[] = $this->baseDir . 'css/bootstrap.min.css'; 68 69 if($this->getConf('includeFontAwesome') == true) $stylesheets[] = $this->baseDir . 'assets/fontawesome/css/all.min.css'; 70 71 $scripts[] = $this->baseDir . 'js/bootstrap.min.js'; 72 73 foreach ($stylesheets as $style) { 74 array_unshift($event->data['link'], array( 75 'type' => 'text/css', 76 'rel' => 'stylesheet', 77 'href' => $style 78 )); 79 } 80 81 foreach ($scripts as $script) { 82 $event->data['script'][] = array( 83 'type' => 'text/javascript', 84 '_data' => '', 85 'src' => $script 86 ); 87 } 88 } 89 90 91 /** 92 * DokuWiki content event handler 93 * 94 * @author James Collins <james.collins@outlook.com.au> 95 */ 96 public function contentHandler(Doku_Event $event) 97 { 98 $event->data = $this->normalizeContent($event->data); 99 } 100 101 102 /** 103 * Parse configuration options 104 * 105 * @author James Collins <james.collins@outlook.com.au> 106 * 107 * @param string $key The configuration key to retreive 108 * @param mixed $default If key doesn't exist, return this value 109 * @return mixed Parsed value of configuration 110 */ 111 public function getConf($key, $default = false) { 112 global $ACT, $conf; 113 114 $value = tpl_getConf($key, $default); 115 116 switch($key) { 117 118 case 'navbar': // TODO is this needed? 119 $value = explode(',', $value); 120 break; 121 122 case 'showSidebar': 123 if ($ACT !== 'show') { 124 return false; 125 } 126 127 return page_findnearest($conf['sidebar'], $this->getConf('useACL')); 128 129 case 'navbarMenuStyle': 130 if($value != 'text') { 131 if(!$this->getConf('useFontAwesome')) { 132 return 'text'; 133 } 134 } 135 } 136 137 return $value; 138 } 139 140 141 /** 142 * Icon 143 * 144 * @author James Collins <james.collins@outlook.com.au> 145 * 146 * @param string $type The type of icon to return 147 * @return string HTML for icon element 148 */ 149 public function icon($type) { 150 if($this->getConf('useFontAwesome')) { 151 return '<i class="fa fa-' . $type . '" aria-hidden="true"></i>'; 152 } 153 154 return ''; 155 } 156 157 158 /** 159 * Print the Navbar menu title/icon 160 * 161 * @author James Collins <james.collins@outlook.com.au> 162 * 163 * @param string $type The type of icon to return 164 * @return string HTML for icon element 165 */ 166 public function navbarMenuTitle($title, $icon) { 167 global $lang; 168 169 $title = ''; 170 171 if($this->getConf('navbarMenuStyle') != 'text') { 172 $title .= $this->icon($icon); 173 } 174 175 if($this->getConf('navbarMenuStyle') != 'icon') { 176 $title .= $lang['user_tools']; 177 } 178 179 echo $title; 180 } 181 182 183 /** 184 * Add class to first DOM element 185 * 186 * @author James Collins <james.collins@outlook.com.au> 187 * 188 * @param string $content HTML DOM 189 * @param string $class Class to add DOM elements 190 * @return string HTML DOM with class added 191 */ 192 public function elementAddClass($html, $class) { 193 preg_match('/class.*?".*?"/', $html, $matches); 194 if(count($matches) > 0) { 195 preg_match('/[" ]'.$class.'[" ]/', $matches[0], $matches); 196 if(count($matches) == 0) { 197 return preg_replace('/(class.*?=.*?")/', '${1}'.$class.' ', $html, 1); 198 } 199 } else { 200 return preg_replace('/>/', 'class="'.$class.'">', $html, 1); 201 } 202 203 return $html; 204 } 205 206 207 /** 208 * Include Sidebar 209 * 210 * @author James Collins <james.collins@outlook.com.au> 211 * 212 * @param string $type Sidebar type 213 * @return boolean If sidebar was added 214 */ 215 public function includeSidebar($type) { 216 global $conf; 217 218 switch($type) { 219 case 'left': 220 if($this->getConf('showSidebar')) { 221 echo '<aside>'; 222 tpl_includeFile('sidebarheader.html'); 223 tpl_include_page($conf['sidebar'], 1, 1); 224 tpl_includeFile('sidebarfooter.html'); 225 echo '</aside>'; 226 227 return true; 228 } 229 230 return false; 231 } 232 233 return false; 234 } 235 236 237 /** 238 * Parse HTML for bootstrap 239 * 240 * @author James Collins <james.collins@outlook.com.au> 241 * 242 * @param string $content HTML content to parse 243 * @return string Parsed HTML for bootstrap 244 */ 245 public function normalizeContent($content) { 246 $html = new simple_html_dom(); 247 $html->load($content, true, false); 248 249 # Return original content if Simple HTML DOM fail or exceeded page size (default MAX_FILE_SIZE => 600KB) 250 if (!$html) { 251 return $content; 252 } 253 254 255 # Buttons 256 foreach ($html->find('.button') as $elm) { 257 if ($elm->tag == 'form') { 258 continue; 259 } 260 $elm->class .= ' btn'; 261 } 262 263 foreach ($html->find('[type=button], [type=submit], [type=reset]') as $elm) { 264 $elm->class .= ' btn btn-outline-secondary'; 265 } 266 267 268 # Section Edit Button 269 foreach ($html->find('.btn_secedit [type=submit]') as $elm) { 270 $elm->class .= ' btn-sm'; 271 } 272 273 # Section Edit icons 274 foreach ($html->find('.secedit.editbutton_section button') as $elm) { 275 $elm->innertext = '<i class="fa fa-edit" aria-hidden="true"></i> ' . $elm->innertext; 276 } 277 278 foreach ($html->find('.secedit.editbutton_table button') as $elm) { 279 // $elm->innertext = iconify('mdi:table') . ' ' . $elm->innertext; 280 } 281 282 $content = $html->save(); 283 284 $html->clear(); 285 unset($html); 286 287 return $content; 288 } 289} 290