xref: /plugin/combo/syntax/minimap.php (revision 0356c661ca6c430c00d91e2fb57ade78a85f1f07)
1*0356c661Sgerardnico<?php
2*0356c661Sgerardnico/**
3*0356c661Sgerardnico * Plugin minimap : Displays mini-map for namespace
4*0356c661Sgerardnico *
5*0356c661Sgerardnico * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
6*0356c661Sgerardnico * @author  Nicolas GERARD
7*0356c661Sgerardnico */
8*0356c661Sgerardnico
9*0356c661Sgerardnicouse ComboStrap\LinkUtility;
10*0356c661Sgerardnicouse ComboStrap\PluginUtility;
11*0356c661Sgerardnico
12*0356c661Sgerardnicoif (!defined('DOKU_INC')) die();
13*0356c661Sgerardnico
14*0356c661Sgerardnico
15*0356c661Sgerardnicoclass syntax_plugin_combo_minimap extends DokuWiki_Syntax_Plugin
16*0356c661Sgerardnico{
17*0356c661Sgerardnico
18*0356c661Sgerardnico    const MINIMAP_TAG_NAME = 'minimap';
19*0356c661Sgerardnico    const INCLUDE_DIRECTORY_PARAMETERS = 'includedirectory';
20*0356c661Sgerardnico    const SHOW_HEADER = 'showheader';
21*0356c661Sgerardnico    const NAMESPACE_KEY_ATT = 'namespace';
22*0356c661Sgerardnico    const POWERED_BY = 'poweredby';
23*0356c661Sgerardnico
24*0356c661Sgerardnico    const STYLE_SNIPPET = <<<EOF
25*0356c661Sgerardnico<style>
26*0356c661Sgerardnico.nicon_folder_open {
27*0356c661Sgerardnico    background-image: url('data:image/svg+xml;charset=utf8,<svg xmlns="http://www.w3.org/2000/svg" width="250" height="195"><g fill="rgb(204,204,204)" transform="translate(-7.897 -268.6)"><rect rx="0" y="286.829" x="12.897" height="175" width="200" opacity=".517"/><path d="M13.23 458.808l39.687-132.291h198.437l-39.687 132.291z" fill-rule="evenodd"/><rect rx="0" y="273.6" x="39.688" height="13" width="90"/></g></svg>');
28*0356c661Sgerardnico    display: inline-block;
29*0356c661Sgerardnico    width: 1.5em;
30*0356c661Sgerardnico    height: 1em;
31*0356c661Sgerardnico    vertical-align: middle;
32*0356c661Sgerardnico    content: "";
33*0356c661Sgerardnico    background-size: 100% 100%;
34*0356c661Sgerardnico}
35*0356c661Sgerardnico#minimap__plugin {
36*0356c661Sgerardnico    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
37*0356c661Sgerardnico    font-size: 14px;
38*0356c661Sgerardnico    line-height: 1.42857;
39*0356c661Sgerardnico}
40*0356c661Sgerardnico
41*0356c661Sgerardnico#minimap__plugin .panel-default {
42*0356c661Sgerardnico    border-color: #ddd;
43*0356c661Sgerardnico    box-sizing: border-box;
44*0356c661Sgerardnico}
45*0356c661Sgerardnico
46*0356c661Sgerardnico#minimap__plugin .panel {
47*0356c661Sgerardnico    box-sizing: border-box;
48*0356c661Sgerardnico    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
49*0356c661Sgerardnico    -moz-border-bottom-colors: none;
50*0356c661Sgerardnico    -moz-border-left-colors: none;
51*0356c661Sgerardnico    -moz-border-right-colors: none;
52*0356c661Sgerardnico    -moz-border-top-colors: none;
53*0356c661Sgerardnico    background-color: #fff;
54*0356c661Sgerardnico    border-image-outset: 0 0 0 0;
55*0356c661Sgerardnico    border-image-repeat: stretch stretch;
56*0356c661Sgerardnico    border-image-slice: 100% 100% 100% 100%;
57*0356c661Sgerardnico    border-image-source: none;
58*0356c661Sgerardnico    border-image-width: 1 1 1 1;
59*0356c661Sgerardnico    border-radius: 4px;
60*0356c661Sgerardnico    border: 1px solid;
61*0356c661Sgerardnico    margin-bottom: 20px;
62*0356c661Sgerardnico    display: block;
63*0356c661Sgerardnico    color: #ddd;
64*0356c661Sgerardnico}
65*0356c661Sgerardnico
66*0356c661Sgerardnico#minimap__plugin .panel-default > .panel-heading {
67*0356c661Sgerardnico    background: #f5f5f5 linear-gradient(to bottom, #f5f5f5 0px, #e8e8e8 100%) repeat-x;
68*0356c661Sgerardnico    border-color: #ddd;
69*0356c661Sgerardnico    color: #333;
70*0356c661Sgerardnico}
71*0356c661Sgerardnico
72*0356c661Sgerardnico#minimap__plugin .panel-heading {
73*0356c661Sgerardnico    border-bottom: 1px solid;
74*0356c661Sgerardnico    border-top-left-radius: 3px;
75*0356c661Sgerardnico    border-top-right-radius: 3px;
76*0356c661Sgerardnico    padding: 10px 15px;
77*0356c661Sgerardnico    box-sizing: border-box;
78*0356c661Sgerardnico    display: block;
79*0356c661Sgerardnico    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
80*0356c661Sgerardnico    font-size: 14px;
81*0356c661Sgerardnico    line-height: 1.42857;
82*0356c661Sgerardnico}
83*0356c661Sgerardnico
84*0356c661Sgerardnico#minimap__plugin .panel > .list-group, #minimap__plugin .panel > .panel-collapse > .list-group {
85*0356c661Sgerardnico    margin-bottom: 0;
86*0356c661Sgerardnico}
87*0356c661Sgerardnico
88*0356c661Sgerardnico#minimap__plugin .list-group {
89*0356c661Sgerardnico    border-radius: 4px;
90*0356c661Sgerardnico    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
91*0356c661Sgerardnico    padding-left: 0;
92*0356c661Sgerardnico    box-sizing: border-box;
93*0356c661Sgerardnico    color: #333;
94*0356c661Sgerardnico}
95*0356c661Sgerardnico
96*0356c661Sgerardnico#minimap__plugin .panel-heading + .list-group .list-group-item:first-child {
97*0356c661Sgerardnico    border-top-width: 0;
98*0356c661Sgerardnico}
99*0356c661Sgerardnico
100*0356c661Sgerardnico#minimap__plugin .panel > .list-group .list-group-item,
101*0356c661Sgerardnico#minimap__plugin .panel > .panel-collapse > .list-group .list-group-item {
102*0356c661Sgerardnico    border-bottom-width: 1px;
103*0356c661Sgerardnico    border-left-width: 0;
104*0356c661Sgerardnico    border-right-width: 0;
105*0356c661Sgerardnico    border-radius: 0;
106*0356c661Sgerardnico}
107*0356c661Sgerardnico
108*0356c661Sgerardnico#minimap__plugin .list-group-item {
109*0356c661Sgerardnico    -moz-border-bottom-colors: none;
110*0356c661Sgerardnico    -moz-border-left-colors: none;
111*0356c661Sgerardnico    -moz-border-right-colors: none;
112*0356c661Sgerardnico    -moz-border-top-colors: none;
113*0356c661Sgerardnico    background-color: #fff;
114*0356c661Sgerardnico    border-image-outset: 0 0 0 0;
115*0356c661Sgerardnico    border-image-repeat: stretch stretch;
116*0356c661Sgerardnico    border-image-slice: 100% 100% 100% 100%;
117*0356c661Sgerardnico    border-image-source: none;
118*0356c661Sgerardnico    border-image-width: 1 1 1 1;
119*0356c661Sgerardnico    /*border: solid #ddd;*/
120*0356c661Sgerardnico    display: block;
121*0356c661Sgerardnico    padding: 10px 15px;
122*0356c661Sgerardnico    position: relative;
123*0356c661Sgerardnico    box-sizing: border-box;
124*0356c661Sgerardnico    margin: 0 0 -1px;
125*0356c661Sgerardnico}
126*0356c661Sgerardnico
127*0356c661Sgerardnico#minimap__plugin .label-primary {
128*0356c661Sgerardnico    background-color: #337ab7;
129*0356c661Sgerardnico}
130*0356c661Sgerardnico
131*0356c661Sgerardnico#minimap__plugin .label {
132*0356c661Sgerardnico    border-radius: 0.25em;
133*0356c661Sgerardnico    color: #fff;
134*0356c661Sgerardnico    display: inline;
135*0356c661Sgerardnico    font-size: 75%;
136*0356c661Sgerardnico    font-weight: 700;
137*0356c661Sgerardnico    line-height: 1;
138*0356c661Sgerardnico    padding: 0.2em 0.6em 0.3em;
139*0356c661Sgerardnico    text-align: center;
140*0356c661Sgerardnico    vertical-align: baseline;
141*0356c661Sgerardnico    white-space: nowrap;
142*0356c661Sgerardnico    box-sizing: border-box;
143*0356c661Sgerardnico}
144*0356c661Sgerardnico
145*0356c661Sgerardnico/* Active link css */
146*0356c661Sgerardnico#minimap__plugin .list-group-item.active,
147*0356c661Sgerardnico#minimap__plugin .list-group-item.active:focus,
148*0356c661Sgerardnico#minimap__plugin .list-group-item.active:hover {
149*0356c661Sgerardnico    background: #f5f5f5 linear-gradient(to bottom, #f5f5f5 0px, #e8e8e8 100%) repeat-x;
150*0356c661Sgerardnico    border-color: #ddd;
151*0356c661Sgerardnico    color: #333;
152*0356c661Sgerardnico    text-shadow: none;
153*0356c661Sgerardnico}
154*0356c661Sgerardnico
155*0356c661Sgerardnico#minimap__plugin .list-group-item.active {
156*0356c661Sgerardnico    background-color: #e8e8e8 ! important;
157*0356c661Sgerardnico    z-index: 2;
158*0356c661Sgerardnico}
159*0356c661Sgerardnico
160*0356c661Sgerardnico
161*0356c661Sgerardnico#minimap__plugin .panel-body {
162*0356c661Sgerardnico    clear: both;
163*0356c661Sgerardnico    content: " ";
164*0356c661Sgerardnico    box-sizing: border-box;
165*0356c661Sgerardnico    display: table;
166*0356c661Sgerardnico    padding: 15px;
167*0356c661Sgerardnico    unicode-bidi: -moz-isolate;
168*0356c661Sgerardnico    color: #333;
169*0356c661Sgerardnico}
170*0356c661Sgerardnico
171*0356c661Sgerardnico#minimap__plugin .glyphicon {
172*0356c661Sgerardnico    /*already same color than the header*/
173*0356c661Sgerardnico    color: #d8d2d2;
174*0356c661Sgerardnico}
175*0356c661Sgerardnico
176*0356c661Sgerardnico#minimap__plugin .panel-footing {
177*0356c661Sgerardnico    display: flex;
178*0356c661Sgerardnico    padding: 0.10rem;
179*0356c661Sgerardnico    background: #f5f5f5 linear-gradient(to bottom,#f5f5f5 0px,#e8e8e8 100%) repeat-x;
180*0356c661Sgerardnico}
181*0356c661Sgerardnico
182*0356c661Sgerardnico#minimap__plugin .minimap_badge {
183*0356c661Sgerardnico
184*0356c661Sgerardnico    border-radius: 0.25em;
185*0356c661Sgerardnico    background-color: #d8d2d2;
186*0356c661Sgerardnico    font-size: 0.6rem;
187*0356c661Sgerardnico    padding: 0.25rem;
188*0356c661Sgerardnico    margin-left: auto !important;
189*0356c661Sgerardnico    margin-right: 0.3rem;
190*0356c661Sgerardnico    color: #1d4a71;
191*0356c661Sgerardnico    margin: 0.1rem;
192*0356c661Sgerardnico}
193*0356c661Sgerardnico</style>
194*0356c661SgerardnicoEOF;
195*0356c661Sgerardnico
196*0356c661Sgerardnico
197*0356c661Sgerardnico    function connectTo($aMode)
198*0356c661Sgerardnico    {
199*0356c661Sgerardnico        $pattern = '<' . self::MINIMAP_TAG_NAME . '[^>]*>';
200*0356c661Sgerardnico        $this->Lexer->addSpecialPattern($pattern, $aMode, PluginUtility::getModeForComponent($this->getPluginComponent()));
201*0356c661Sgerardnico    }
202*0356c661Sgerardnico
203*0356c661Sgerardnico    function getSort()
204*0356c661Sgerardnico    {
205*0356c661Sgerardnico        /**
206*0356c661Sgerardnico         * One less than the old one
207*0356c661Sgerardnico         */
208*0356c661Sgerardnico        return 149;
209*0356c661Sgerardnico    }
210*0356c661Sgerardnico
211*0356c661Sgerardnico    /**
212*0356c661Sgerardnico     * No p element please
213*0356c661Sgerardnico     * @return string
214*0356c661Sgerardnico     */
215*0356c661Sgerardnico    function getPType()
216*0356c661Sgerardnico    {
217*0356c661Sgerardnico        return 'block';
218*0356c661Sgerardnico    }
219*0356c661Sgerardnico
220*0356c661Sgerardnico    function getType()
221*0356c661Sgerardnico    {
222*0356c661Sgerardnico        // The spelling is wrong but this is a correct value
223*0356c661Sgerardnico        // https://www.dokuwiki.org/devel:syntax_plugins#syntax_types
224*0356c661Sgerardnico        return 'substition';
225*0356c661Sgerardnico    }
226*0356c661Sgerardnico
227*0356c661Sgerardnico    /**
228*0356c661Sgerardnico     *
229*0356c661Sgerardnico     * The handle function goal is to parse the matched syntax through the pattern function
230*0356c661Sgerardnico     * and to return the result for use in the renderer
231*0356c661Sgerardnico     * This result is always cached until the page is modified.
232*0356c661Sgerardnico     * @param string $match
233*0356c661Sgerardnico     * @param int $state
234*0356c661Sgerardnico     * @param int $pos
235*0356c661Sgerardnico     * @param Doku_Handler $handler
236*0356c661Sgerardnico     * @return array|bool
237*0356c661Sgerardnico     * @see DokuWiki_Syntax_Plugin::handle()
238*0356c661Sgerardnico     *
239*0356c661Sgerardnico     */
240*0356c661Sgerardnico    function handle($match, $state, $pos, Doku_Handler $handler)
241*0356c661Sgerardnico    {
242*0356c661Sgerardnico
243*0356c661Sgerardnico        switch ($state) {
244*0356c661Sgerardnico
245*0356c661Sgerardnico            // As there is only one call to connect to in order to a add a pattern,
246*0356c661Sgerardnico            // there is only one state entering the function
247*0356c661Sgerardnico            // but I leave it for better understanding of the process flow
248*0356c661Sgerardnico            case DOKU_LEXER_SPECIAL :
249*0356c661Sgerardnico
250*0356c661Sgerardnico                // Parse the parameters
251*0356c661Sgerardnico                $match = substr($match, 8, -1); //9 = strlen("<minimap")
252*0356c661Sgerardnico
253*0356c661Sgerardnico                // Init
254*0356c661Sgerardnico                $parameters = array();
255*0356c661Sgerardnico                $parameters['substr'] = 1;
256*0356c661Sgerardnico                $parameters[self::INCLUDE_DIRECTORY_PARAMETERS] = $this->getConf(self::INCLUDE_DIRECTORY_PARAMETERS);
257*0356c661Sgerardnico                $parameters[self::SHOW_HEADER] = $this->getConf(self::SHOW_HEADER);
258*0356c661Sgerardnico
259*0356c661Sgerardnico
260*0356c661Sgerardnico                // /i not case sensitive
261*0356c661Sgerardnico                $attributePattern = "\\s*(\w+)\\s*=\\s*[\'\"]{1}([^\`\"]*)[\'\"]{1}\\s*";
262*0356c661Sgerardnico                $result = preg_match_all('/' . $attributePattern . '/i', $match, $matches);
263*0356c661Sgerardnico                if ($result != 0) {
264*0356c661Sgerardnico                    foreach ($matches[1] as $key => $parameterKey) {
265*0356c661Sgerardnico                        $parameter = strtolower($parameterKey);
266*0356c661Sgerardnico                        $value = $matches[2][$key];
267*0356c661Sgerardnico                        if (in_array($parameter, [self::SHOW_HEADER, self::INCLUDE_DIRECTORY_PARAMETERS])) {
268*0356c661Sgerardnico                            $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
269*0356c661Sgerardnico                        }
270*0356c661Sgerardnico                        $parameters[$parameter] = $value;
271*0356c661Sgerardnico                    }
272*0356c661Sgerardnico                }
273*0356c661Sgerardnico                // Cache the values
274*0356c661Sgerardnico                return array($state, $parameters);
275*0356c661Sgerardnico
276*0356c661Sgerardnico        }
277*0356c661Sgerardnico
278*0356c661Sgerardnico        return false;
279*0356c661Sgerardnico    }
280*0356c661Sgerardnico
281*0356c661Sgerardnico
282*0356c661Sgerardnico    function render($mode, Doku_Renderer $renderer, $data)
283*0356c661Sgerardnico    {
284*0356c661Sgerardnico
285*0356c661Sgerardnico        // The $data variable comes from the handle() function
286*0356c661Sgerardnico        //
287*0356c661Sgerardnico        // $mode = 'xhtml' means that we output html
288*0356c661Sgerardnico        // There is other mode such as metadata where you can output data for the headers (Not 100% sure)
289*0356c661Sgerardnico        if ($mode == 'xhtml') {
290*0356c661Sgerardnico
291*0356c661Sgerardnico            /** @var Doku_Renderer_xhtml $renderer */
292*0356c661Sgerardnico
293*0356c661Sgerardnico            // Unfold the $data array in two separates variables
294*0356c661Sgerardnico            list($state, $parameters) = $data;
295*0356c661Sgerardnico
296*0356c661Sgerardnico            // As there is only one call to connect to in order to a add a pattern,
297*0356c661Sgerardnico            // there is only one state entering the function
298*0356c661Sgerardnico            // but I leave it for better understanding of the process flow
299*0356c661Sgerardnico            switch ($state) {
300*0356c661Sgerardnico
301*0356c661Sgerardnico                case DOKU_LEXER_SPECIAL :
302*0356c661Sgerardnico
303*0356c661Sgerardnico                    if (!PluginUtility::htmlSnippetAlreadyAdded($renderer->info,self::MINIMAP_TAG_NAME)){
304*0356c661Sgerardnico                        $renderer->doc .= self::STYLE_SNIPPET;
305*0356c661Sgerardnico                    };
306*0356c661Sgerardnico
307*0356c661Sgerardnico                    global $ID;
308*0356c661Sgerardnico                    global $INFO;
309*0356c661Sgerardnico                    $callingId = $ID;
310*0356c661Sgerardnico                    // If mini-map is in a sidebar, we don't want the ID of the sidebar
311*0356c661Sgerardnico                    // but the ID of the page.
312*0356c661Sgerardnico                    if ($INFO != null) {
313*0356c661Sgerardnico                        $callingId = $INFO['id'];
314*0356c661Sgerardnico                    }
315*0356c661Sgerardnico
316*0356c661Sgerardnico                    $nameSpacePath = getNS($callingId); // The complete path to the directory
317*0356c661Sgerardnico                    if (array_key_exists(self::NAMESPACE_KEY_ATT, $parameters)) {
318*0356c661Sgerardnico                        $nameSpacePath = $parameters[self::NAMESPACE_KEY_ATT];
319*0356c661Sgerardnico                    }
320*0356c661Sgerardnico                    $currentNameSpace = curNS($callingId); // The name of the container directory
321*0356c661Sgerardnico                    $includeDirectory = $parameters[self::INCLUDE_DIRECTORY_PARAMETERS];
322*0356c661Sgerardnico                    $pagesOfNamespace = $this->getNamespaceChildren($nameSpacePath, $sort = 'natural', $listdirs = $includeDirectory);
323*0356c661Sgerardnico
324*0356c661Sgerardnico                    // Set the two possible home page for the namespace ie:
325*0356c661Sgerardnico                    //   - the name of the containing map ($homePageWithContainingMapName)
326*0356c661Sgerardnico                    //   - the start conf parameters ($homePageWithStartConf)
327*0356c661Sgerardnico                    global $conf;
328*0356c661Sgerardnico                    $parts = explode(':', $nameSpacePath);
329*0356c661Sgerardnico                    $lastContainingNameSpace = $parts[count($parts) - 1];
330*0356c661Sgerardnico                    $homePageWithContainingMapName = $nameSpacePath . ':' . $lastContainingNameSpace;
331*0356c661Sgerardnico                    $startConf = $conf['start'];
332*0356c661Sgerardnico                    $homePageWithStartConf = $nameSpacePath . ':' . $startConf;
333*0356c661Sgerardnico
334*0356c661Sgerardnico                    // Build the list of page
335*0356c661Sgerardnico                    $miniMapList = '<ul class="list-group">';
336*0356c661Sgerardnico                    $pageNum = 0;
337*0356c661Sgerardnico                    $startPageFound = false;
338*0356c661Sgerardnico                    $homePageFound = false;
339*0356c661Sgerardnico                    //$pagesCount = count($pagesOfNamespace); // number of pages in the namespace
340*0356c661Sgerardnico                    foreach ($pagesOfNamespace as $pageArray) {
341*0356c661Sgerardnico
342*0356c661Sgerardnico                        // The title of the page
343*0356c661Sgerardnico                        $title = '';
344*0356c661Sgerardnico
345*0356c661Sgerardnico                        // If it's a directory
346*0356c661Sgerardnico                        if ($pageArray['type'] == "d") {
347*0356c661Sgerardnico
348*0356c661Sgerardnico                            $pageId = $this->getNamespaceStartId($pageArray['id']);
349*0356c661Sgerardnico
350*0356c661Sgerardnico                        } else {
351*0356c661Sgerardnico
352*0356c661Sgerardnico                            $pageNum++;
353*0356c661Sgerardnico                            $pageId = $pageArray['id'];
354*0356c661Sgerardnico
355*0356c661Sgerardnico                        }
356*0356c661Sgerardnico                        $link = new LinkUtility($pageId);
357*0356c661Sgerardnico
358*0356c661Sgerardnico
359*0356c661Sgerardnico                        /**
360*0356c661Sgerardnico                         * Set name and title
361*0356c661Sgerardnico                         */
362*0356c661Sgerardnico                        // Name if the variable that it's shown. A part of it can be suppressed
363*0356c661Sgerardnico                        // Title will stay full in the link
364*0356c661Sgerardnico                        $h1TargetPage = $link->getInternalPage()->getH1();
365*0356c661Sgerardnico                        $title = $link->getInternalPage()->getTitle();
366*0356c661Sgerardnico
367*0356c661Sgerardnico                        $link->setName(noNSorNS($pageId));
368*0356c661Sgerardnico                        if ($h1TargetPage !=null) {
369*0356c661Sgerardnico                            $link->setName($h1TargetPage);
370*0356c661Sgerardnico                        } else {
371*0356c661Sgerardnico                            if ($title!=null) {
372*0356c661Sgerardnico                                $link->setName($title);
373*0356c661Sgerardnico                            }
374*0356c661Sgerardnico                        }
375*0356c661Sgerardnico                        $link->setTitle(noNSorNS($pageId));
376*0356c661Sgerardnico                        if ($title!=null) {
377*0356c661Sgerardnico                            $link->setTitle($title);
378*0356c661Sgerardnico                        }
379*0356c661Sgerardnico
380*0356c661Sgerardnico                        // If debug mode
381*0356c661Sgerardnico                        if ($parameters['debug']) {
382*0356c661Sgerardnico                            $link->setTitle($link->getTitle().' (' . $pageId . ')');
383*0356c661Sgerardnico                        }
384*0356c661Sgerardnico
385*0356c661Sgerardnico                        // Add the page number in the URL title
386*0356c661Sgerardnico                        $link->setTitle($link->getTitle() .' (' . $pageNum . ')');
387*0356c661Sgerardnico
388*0356c661Sgerardnico                        // Suppress the parts in the name with the regexp defines in the 'suppress' params
389*0356c661Sgerardnico                        if ($parameters['suppress']) {
390*0356c661Sgerardnico                            $substrPattern = '/' . $parameters['suppress'] . '/i';
391*0356c661Sgerardnico                            $replacement = '';
392*0356c661Sgerardnico                            $name = preg_replace($substrPattern, $replacement, $link->getName());
393*0356c661Sgerardnico                            $link->setName($name);
394*0356c661Sgerardnico                        }
395*0356c661Sgerardnico
396*0356c661Sgerardnico                        // See in which page we are
397*0356c661Sgerardnico                        // The style will then change
398*0356c661Sgerardnico                        $active = '';
399*0356c661Sgerardnico                        if ($callingId == $pageId) {
400*0356c661Sgerardnico                            $active = 'active';
401*0356c661Sgerardnico                        }
402*0356c661Sgerardnico
403*0356c661Sgerardnico                        // Not all page are printed
404*0356c661Sgerardnico                        // sidebar are not for instance
405*0356c661Sgerardnico
406*0356c661Sgerardnico                        // Are we in the root ?
407*0356c661Sgerardnico                        if ($pageArray['ns']) {
408*0356c661Sgerardnico                            $nameSpacePathPrefix = $pageArray['ns'] . ':';
409*0356c661Sgerardnico                        } else {
410*0356c661Sgerardnico                            $nameSpacePathPrefix = '';
411*0356c661Sgerardnico                        }
412*0356c661Sgerardnico                        $print = true;
413*0356c661Sgerardnico                        if ($pageArray['id'] == $nameSpacePathPrefix . $currentNameSpace) {
414*0356c661Sgerardnico                            // If the start page exists, the page with the same name
415*0356c661Sgerardnico                            // than the namespace must be shown
416*0356c661Sgerardnico                            if (page_exists($nameSpacePathPrefix . $startConf)) {
417*0356c661Sgerardnico                                $print = true;
418*0356c661Sgerardnico                            } else {
419*0356c661Sgerardnico                                $print = false;
420*0356c661Sgerardnico                            }
421*0356c661Sgerardnico                            $homePageFound = true;
422*0356c661Sgerardnico                        } else if ($pageArray['id'] == $nameSpacePathPrefix . $startConf) {
423*0356c661Sgerardnico                            $print = false;
424*0356c661Sgerardnico                            $startPageFound = true;
425*0356c661Sgerardnico                        } else if ($pageArray['id'] == $nameSpacePathPrefix . $conf['sidebar']) {
426*0356c661Sgerardnico                            $pageNum -= 1;
427*0356c661Sgerardnico                            $print = false;
428*0356c661Sgerardnico                        };
429*0356c661Sgerardnico
430*0356c661Sgerardnico
431*0356c661Sgerardnico                        // If the page must be printed, build the link
432*0356c661Sgerardnico                        if ($print) {
433*0356c661Sgerardnico
434*0356c661Sgerardnico                            // Open the item tag
435*0356c661Sgerardnico                            $miniMapList .= "<li class=\"list-group-item " . $active . "\">";
436*0356c661Sgerardnico
437*0356c661Sgerardnico                            // Add a glyphicon if it's a directory
438*0356c661Sgerardnico                            if ($pageArray['type'] == "d") {
439*0356c661Sgerardnico                                $miniMapList .= "<span class=\"nicon_folder_open\" aria-hidden=\"true\"></span>&nbsp;&nbsp;";
440*0356c661Sgerardnico                            }
441*0356c661Sgerardnico
442*0356c661Sgerardnico                            $miniMapList .= $link->render($renderer);;
443*0356c661Sgerardnico
444*0356c661Sgerardnico
445*0356c661Sgerardnico                            // Close the item
446*0356c661Sgerardnico                            $miniMapList .= "</li>";
447*0356c661Sgerardnico
448*0356c661Sgerardnico                        }
449*0356c661Sgerardnico
450*0356c661Sgerardnico                    }
451*0356c661Sgerardnico                    $miniMapList .= '</ul>'; // End list-group
452*0356c661Sgerardnico
453*0356c661Sgerardnico
454*0356c661Sgerardnico                    // Build the panel header
455*0356c661Sgerardnico                    $miniMapHeader = "";
456*0356c661Sgerardnico                    $startId = "";
457*0356c661Sgerardnico                    if ($startPageFound) {
458*0356c661Sgerardnico                        $startId = $homePageWithStartConf;
459*0356c661Sgerardnico                    } else {
460*0356c661Sgerardnico                        if ($homePageFound) {
461*0356c661Sgerardnico                            $startId = $homePageWithContainingMapName;
462*0356c661Sgerardnico                        }
463*0356c661Sgerardnico                    }
464*0356c661Sgerardnico
465*0356c661Sgerardnico                    $panelHeaderContent = "";
466*0356c661Sgerardnico                    if ($startId == "") {
467*0356c661Sgerardnico                        if ($parameters[self::SHOW_HEADER] == true) {
468*0356c661Sgerardnico                            $panelHeaderContent = 'No Home Page found';
469*0356c661Sgerardnico                        }
470*0356c661Sgerardnico                    } else {
471*0356c661Sgerardnico                        $startLink = new LinkUtility($startId);
472*0356c661Sgerardnico                        $startLink->setTitle($startId);
473*0356c661Sgerardnico
474*0356c661Sgerardnico                        $panelHeaderContent = $startLink->render($renderer);
475*0356c661Sgerardnico                        // We are not counting the header page
476*0356c661Sgerardnico                        $pageNum--;
477*0356c661Sgerardnico                    }
478*0356c661Sgerardnico
479*0356c661Sgerardnico                    if ($panelHeaderContent != "") {
480*0356c661Sgerardnico                        $miniMapHeader .= '<div class="panel-heading">' . $panelHeaderContent . '  <span class="label label-primary">' . $pageNum . ' pages</span></div>';
481*0356c661Sgerardnico                    }
482*0356c661Sgerardnico
483*0356c661Sgerardnico                    if ($parameters['debug']) {
484*0356c661Sgerardnico                        $miniMapHeader .= '<div class="panel-body">' .
485*0356c661Sgerardnico                            '<B>Debug Information:</B><BR>' .
486*0356c661Sgerardnico                            'CallingId: (' . $callingId . ')<BR>' .
487*0356c661Sgerardnico                            'Suppress Option: (' . $parameters['suppress'] . ')<BR>' .
488*0356c661Sgerardnico                            '</div>';
489*0356c661Sgerardnico                    }
490*0356c661Sgerardnico
491*0356c661Sgerardnico                    // Header + list
492*0356c661Sgerardnico                    $renderer->doc .= '<div id="minimap__plugin"><div class="panel panel-default">'
493*0356c661Sgerardnico                        . $miniMapHeader
494*0356c661Sgerardnico                        . $miniMapList
495*0356c661Sgerardnico                        . '</div></div>';
496*0356c661Sgerardnico                    break;
497*0356c661Sgerardnico            }
498*0356c661Sgerardnico
499*0356c661Sgerardnico            return true;
500*0356c661Sgerardnico        }
501*0356c661Sgerardnico        return false;
502*0356c661Sgerardnico
503*0356c661Sgerardnico    }
504*0356c661Sgerardnico
505*0356c661Sgerardnico    /**
506*0356c661Sgerardnico     * Return all pages and/of sub-namespaces (subdirectory) of a namespace (ie directory)
507*0356c661Sgerardnico     * Adapted from feed.php
508*0356c661Sgerardnico     *
509*0356c661Sgerardnico     * @param $namespace The container of the pages
510*0356c661Sgerardnico     * @param string $sort 'natural' to use natural order sorting (default); 'date' to sort by filemtime
511*0356c661Sgerardnico     * @param $listdirs - Add the directory to the list of files
512*0356c661Sgerardnico     * @return array An array of the pages for the namespace
513*0356c661Sgerardnico     */
514*0356c661Sgerardnico    function getNamespaceChildren($namespace, $sort = 'natural', $listdirs = false)
515*0356c661Sgerardnico    {
516*0356c661Sgerardnico        require_once(DOKU_INC . 'inc/search.php');
517*0356c661Sgerardnico        global $conf;
518*0356c661Sgerardnico
519*0356c661Sgerardnico        $ns = ':' . cleanID($namespace);
520*0356c661Sgerardnico        // ns as a path
521*0356c661Sgerardnico        $ns = utf8_encodeFN(str_replace(':', '/', $ns));
522*0356c661Sgerardnico
523*0356c661Sgerardnico        $data = array();
524*0356c661Sgerardnico
525*0356c661Sgerardnico        // Options of the callback function search_universal
526*0356c661Sgerardnico        // in the search.php file
527*0356c661Sgerardnico        $search_opts = array(
528*0356c661Sgerardnico            'depth' => 1,
529*0356c661Sgerardnico            'pagesonly' => true,
530*0356c661Sgerardnico            'listfiles' => true,
531*0356c661Sgerardnico            'listdirs' => $listdirs,
532*0356c661Sgerardnico            'firsthead' => true
533*0356c661Sgerardnico        );
534*0356c661Sgerardnico        // search_universal is a function in inc/search.php that accepts the $search_opts parameters
535*0356c661Sgerardnico        search($data, $conf['datadir'], 'search_universal', $search_opts, $ns, $lvl = 1, $sort);
536*0356c661Sgerardnico
537*0356c661Sgerardnico        return $data;
538*0356c661Sgerardnico    }
539*0356c661Sgerardnico
540*0356c661Sgerardnico    /**
541*0356c661Sgerardnico     * Return the id of the start page of a namespace
542*0356c661Sgerardnico     *
543*0356c661Sgerardnico     * @param $id an id of a namespace (directory)
544*0356c661Sgerardnico     * @return string the id of the home page
545*0356c661Sgerardnico     */
546*0356c661Sgerardnico    function getNamespaceStartId($id)
547*0356c661Sgerardnico    {
548*0356c661Sgerardnico
549*0356c661Sgerardnico        global $conf;
550*0356c661Sgerardnico
551*0356c661Sgerardnico        $id = $id . ":";
552*0356c661Sgerardnico
553*0356c661Sgerardnico        if (page_exists($id . $conf['start'])) {
554*0356c661Sgerardnico            // start page inside namespace
555*0356c661Sgerardnico            $homePageId = $id . $conf['start'];
556*0356c661Sgerardnico        } elseif (page_exists($id . noNS(cleanID($id)))) {
557*0356c661Sgerardnico            // page named like the NS inside the NS
558*0356c661Sgerardnico            $homePageId = $id . noNS(cleanID($id));
559*0356c661Sgerardnico        } elseif (page_exists($id)) {
560*0356c661Sgerardnico            // page like namespace exists
561*0356c661Sgerardnico            $homePageId = substr($id, 0, -1);
562*0356c661Sgerardnico        } else {
563*0356c661Sgerardnico            // fall back to default
564*0356c661Sgerardnico            $homePageId = $id . $conf['start'];
565*0356c661Sgerardnico        }
566*0356c661Sgerardnico        return $homePageId;
567*0356c661Sgerardnico    }
568*0356c661Sgerardnico
569*0356c661Sgerardnico    /**
570*0356c661Sgerardnico     * @param $get_called_class
571*0356c661Sgerardnico     * @return string
572*0356c661Sgerardnico     */
573*0356c661Sgerardnico    public static function getTagName($get_called_class)
574*0356c661Sgerardnico    {
575*0356c661Sgerardnico        list(/* $t */, /* $p */, $c) = explode('_', $get_called_class, 3);
576*0356c661Sgerardnico        return (isset($c) ? $c : '');
577*0356c661Sgerardnico    }
578*0356c661Sgerardnico
579*0356c661Sgerardnico    /**
580*0356c661Sgerardnico     * @return string - the tag
581*0356c661Sgerardnico     */
582*0356c661Sgerardnico    public static function getTag()
583*0356c661Sgerardnico    {
584*0356c661Sgerardnico        return self::getTagName(get_called_class());
585*0356c661Sgerardnico    }
586*0356c661Sgerardnico
587*0356c661Sgerardnico
588*0356c661Sgerardnico}
589