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> "; 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