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