[namespace]}} */ public function connectTo($mode) { // reconnait la syntaxe utilisé par l'utilisateur $this->Lexer->addSpecialPattern('{{catmenu>.*?}}', $mode, 'plugin_catmenu_catmenu'); } /** * Nettoie {{catmenu>[namespace]}} */ public function handle($match, $state, $pos, Doku_Handler $handler) { $namespace = trim(substr($match, 10, -2)); // retirer {{visualindex>, }} et les espaces return ['namespace' => $namespace]; } public function render($mode, Doku_Renderer $renderer, $data) { if ($mode !== 'xhtml') return false; global $ID; global $conf; $random = uniqid(); if($data['namespace'] === '.') { // Récupération du namespace courant if(!is_dir($this->namespaceDir($ID))) { $pageNamespaceInfo = $this->getPageNamespaceInfo($ID); if($this->isHomepage($pageNamespaceInfo['pageID'], $pageNamespaceInfo['parentID'])) { $namespace = $pageNamespaceInfo['parentNamespace']; } } if(!isset($namespace)) { $namespace = $ID; } } else { $namespace = cleanID($data['namespace']); } $pages = $this->getPagesAndSubfoldersItems($namespace); if($pages === false) { $renderer->doc .= '
' . hsc($this->getLang('namespace_not_found')) . '
'; return true; } $renderer->doc .= '
'; $renderer->doc .= ""; return true; } /** * Récupère à la fois les pages et les sous-dossiers d'un namespace */ public function getPagesAndSubfoldersItems($namespace) { global $conf; $skipPageWithoutTitle = (bool)$this->getConf('skip_page_without_title'); $childrens = @scandir($this->namespaceDir($namespace)); // Récupère les elements if($childrens === false) { return false; } $start = $conf['start']; // 'accueil' dans la plupart des temps (dans bpnum:d-s:accueil) $items = []; foreach($childrens as $child) { // Boucle sur les elements if ($child[0] == '.' ) { // Remove ., .. and hidden files continue; } $childPathInfo = pathinfo($child); $childID = cleanID($childPathInfo['filename']); $childNamespace = cleanID($namespace !== '' ? ($namespace . ':' . $childID) : $childID); $childHasExtension = isset($childPathInfo['extension']) && $childPathInfo['extension'] !== ''; $isDirNamespace = is_dir($this->namespaceDir($childNamespace)); $isPageNamespace = page_exists($childNamespace); if(!$childHasExtension && $isDirNamespace) { // Si dossier $pageNamespaceInfo = $this->getPageNamespaceInfo($childNamespace); if($this->isHomepage($childID, (string)$pageNamespaceInfo['parentID'])) { // Flatten namespace "homepage" folders like ns:ns so children stay direct. $subItems = $this->getPagesAndSubfoldersItems($childNamespace); if(is_array($subItems) && $subItems) { $items = array_merge($items, $subItems); } continue; } $pageID = null; if(page_exists("$childNamespace:$start")) { // S'il y a une page d'accueil $pageID = "$childNamespace:$start"; } else if(page_exists("$childNamespace:$childID")) { // S'il y a une page du même nom que le dossier dans le dossier $pageID = "$childNamespace:$childID"; } else if($isPageNamespace) { // S'il y a une page du même nom que le dossier au même niveau que le dossier $pageID = cleanID($namespace !== '' ? ($namespace . ':' . $childID) : $childID); } $permission = auth_quickaclcheck($pageID); if($permission < AUTH_READ) { continue; } $title = $pageID ? p_get_first_heading($pageID) : $pageID; if (empty($title)) { if ($skipPageWithoutTitle || empty($pageID)) { continue; } $title = noNS($pageID); } $items[] = array( 'title' => $title, 'url' => $pageID? wl($pageID) : null, 'icon' => $this->getPageImage($pageID), 'pagesiconUploadUrl' => $this->getPagesiconUploadUrl($pageID ?: $childNamespace), 'folderNamespace' => $childNamespace, 'namespace' => $childNamespace, 'subtree' => $this->getPagesAndSubfoldersItems($childNamespace), 'permission' => $permission ); continue; } if(!$isDirNamespace && $isPageNamespace) { // Si page seulement $skipRegex = $this->getConf('skip_file'); if (!empty($skipRegex) && preg_match($skipRegex, $childNamespace)) { continue; } $pageNamespaceInfo = $this->getPageNamespaceInfo("$namespace:$childID"); if($this->isHomepage($childID, $pageNamespaceInfo['parentID'])) { continue; } $permission = auth_quickaclcheck($childNamespace); if($permission < AUTH_READ) { continue; } $title = p_get_first_heading($childNamespace); if (empty($title)) { if ($skipPageWithoutTitle) { continue; } $title = noNS($childNamespace); } $items[] = array( 'title' => $title, 'url' => $childNamespace? wl($childNamespace) : null, 'icon' => $this->getPageImage($childNamespace), 'pagesiconUploadUrl' => $this->getPagesiconUploadUrl($childNamespace), 'folderNamespace' => $namespace, 'namespace' => $childNamespace, 'permission' => $permission ); } } return $items; } /** * Renvoie l'URL de la petite icone (thumbnail) via le helper pagesicon. * Si aucune icone n'est definie, ne renvoie rien. */ public function getPageImage($page) { if(!$page) return ''; $page = cleanID((string)$page); if($page === '') return ''; /** @var helper_plugin_pagesicon|null $helper */ $helper = plugin_load('helper', 'pagesicon'); if(!$helper) return ''; $namespace = getNS($page); $pageID = noNS($page); // Prefer new pagesicon API, keep legacy fallback for older versions. if(method_exists($helper, 'getPageIconUrl')) { $mtime = null; $iconUrl = $helper->getPageIconUrl($namespace, $pageID, 'smallorbig', ['width' => 55], $mtime, true); if($iconUrl) return $iconUrl; } else if(method_exists($helper, 'getImageIcon')) { $mtime = null; $withDefaultSupported = false; try { $method = new ReflectionMethod($helper, 'getImageIcon'); $withDefaultSupported = $method->getNumberOfParameters() >= 6; } catch (ReflectionException $e) { $withDefaultSupported = false; } if($withDefaultSupported) { $iconUrl = $helper->getImageIcon($namespace, $pageID, 'smallorbig', ['width' => 55], $mtime, true); } else { $iconUrl = $helper->getImageIcon($namespace, $pageID, 'smallorbig', ['width' => 55], $mtime); } if($iconUrl) return $iconUrl; } $iconMediaID = false; if(method_exists($helper, 'getPageIconId')) { $iconMediaID = $helper->getPageIconId($namespace, $pageID, 'smallorbig'); } else if(method_exists($helper, 'getPageImage')) { $withDefaultSupported = false; try { $method = new ReflectionMethod($helper, 'getPageImage'); $withDefaultSupported = $method->getNumberOfParameters() >= 4; } catch (ReflectionException $e) { $withDefaultSupported = false; } if($withDefaultSupported) { $iconMediaID = $helper->getPageImage($namespace, $pageID, 'smallorbig', true); } else { $iconMediaID = $helper->getPageImage($namespace, $pageID, 'smallorbig'); } } if(!$iconMediaID) return ''; return ml($iconMediaID, ['width' => 55]); } private function getPagesiconUploadUrl($namespace) { if ($this->pagesiconHelper === false) { $this->pagesiconHelper = plugin_load('helper', 'pagesicon'); } if (!$this->pagesiconHelper) return null; if (!method_exists($this->pagesiconHelper, 'getUploadIconPage')) return null; return $this->pagesiconHelper->getUploadIconPage((string)$namespace); } public function isHomepage($pageID, $parentID) { global $conf; $startPageID = $conf['start']; return $pageID == $startPageID || $pageID == $parentID; } public function namespaceDir($namespace) { global $conf; return $conf['datadir'] . '/' . utf8_encodeFN(str_replace(':', '/', $namespace)); } public function getPageNamespaceInfo($namespace) { $namespaces = explode(':', $namespace); return array( 'pageNamespace' => $namespace, 'pageID' => array_pop($namespaces), 'parentNamespace' => implode(':', $namespaces), 'parentID' => array_pop($namespaces) ); } }