xref: /template/mikio/mikio.php (revision c165b1846fc5c512505dc577e9428a1a76926c7e)
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