1<?php 2/** 3 * Plugin catmenu — Helper partagé pour la résolution des namespaces 4 * 5 * Regroupe les utilitaires de navigation dans les namespaces DokuWiki 6 * utilisés à la fois par le rendu syntaxique et l'intégration ProseMirror. 7 * 8 * Auteur: Lortetv 9 */ 10 11use dokuwiki\Extension\Plugin; 12 13class helper_plugin_catmenu_namespace extends Plugin 14{ 15 /** 16 * Retourne le chemin filesystem d'un namespace DokuWiki. 17 */ 18 public function namespaceDir(string $namespace): string 19 { 20 global $conf; 21 return rtrim((string)$conf['datadir'], '/') . '/' . utf8_encodeFN(str_replace(':', '/', $namespace)); 22 } 23 24 /** 25 * Décompose un namespace en ses composants (page, parent, etc.). 26 * 27 * @return array{pageID: string, parentNamespace: string, parentID: string} 28 */ 29 public function getPageNamespaceInfo(string $namespace): array 30 { 31 $parts = explode(':', $namespace); 32 $pageID = (string)array_pop($parts); 33 $parentNamespace = implode(':', $parts); 34 $parentID = ''; 35 if ($parentNamespace !== '') { 36 $parentParts = explode(':', $parentNamespace); 37 $parentID = (string)array_pop($parentParts); 38 } 39 return [ 40 'pageID' => $pageID, 41 'parentNamespace' => $parentNamespace, 42 'parentID' => $parentID, 43 ]; 44 } 45 46 /** 47 * Indique si un identifiant de page correspond à une page d'accueil 48 * (page de démarrage ou page homonyme du namespace parent). 49 */ 50 public function isHomepage(string $pageID, string $parentID): bool 51 { 52 global $conf; 53 $startPageID = (string)$conf['start']; 54 return $pageID === $startPageID || ($parentID !== '' && $pageID === $parentID); 55 } 56 57 /** 58 * Résout le namespace courant pour une page hôte donnée. 59 * Remonte d'un niveau si la page hôte est elle-même une page d'accueil. 60 */ 61 public function getCurrentNamespace(string $hostPageID): string 62 { 63 if (!is_dir($this->namespaceDir($hostPageID))) { 64 $info = $this->getPageNamespaceInfo($hostPageID); 65 if ($this->isHomepage($info['pageID'], $info['parentID'])) { 66 return $info['parentNamespace']; 67 } 68 } 69 return $hostPageID; 70 } 71 72 /** 73 * Résout une expression de namespace (`.`, `~relatif`, ou absolu) 74 * par rapport à la page hôte courante. 75 */ 76 public function resolveNamespaceExpression(string $expr, string $hostPageID): string 77 { 78 $expr = trim($expr); 79 if ($expr === '.') { 80 return $this->getCurrentNamespace($hostPageID); 81 } 82 if ($expr !== '' && $expr[0] === '~') { 83 $rel = cleanID(ltrim($expr, '~')); 84 $base = $this->getCurrentNamespace($hostPageID); 85 return cleanID($base !== '' ? ($base . ':' . $rel) : $rel); 86 } 87 return cleanID($expr); 88 } 89 90 /** 91 * Indique si une page cible appartient à un namespace donné. 92 */ 93 public function isTargetInNamespace(string $targetPage, string $namespace): bool 94 { 95 if ($namespace === '') return true; 96 $targetPage = cleanID($targetPage); 97 $namespace = cleanID($namespace); 98 if ($targetPage === '' || $namespace === '') return false; 99 return ($targetPage === $namespace) || (strpos($targetPage . ':', $namespace . ':') === 0); 100 } 101} 102