xref: /plugin/visualindex/syntax/visualindex.php (revision 7f5290b8d6d83542fd5b939a9c568e40224c0ec8)
13c9c7f3bSLORTET<?php
23c9c7f3bSLORTET/**
33c9c7f3bSLORTET * Plugin visualindex
4*7f5290b8SLORTET * Affiche les pages d'un namespace donné
53c9c7f3bSLORTET * Auteur: Choimetg, Lortetv
63c9c7f3bSLORTET */
73c9c7f3bSLORTET
83c9c7f3bSLORTETuse dokuwiki\Extension\SyntaxPlugin;
93c9c7f3bSLORTETuse dokuwiki\File\PageResolver;
103c9c7f3bSLORTETuse dokuwiki\Ui\Index;
113c9c7f3bSLORTET
123c9c7f3bSLORTETclass syntax_plugin_visualindex_visualindex extends SyntaxPlugin {
133c9c7f3bSLORTET    /** @var helper_plugin_pagesicon|null|false */
143c9c7f3bSLORTET    private $pagesiconHelper = false;
153c9c7f3bSLORTET
163c9c7f3bSLORTET	private function getMediaLinkTargetAttr() {
173c9c7f3bSLORTET		global $conf;
183c9c7f3bSLORTET		$target = (string)($conf['target']['media'] ?? '');
193c9c7f3bSLORTET		if($target === '') return '';
203c9c7f3bSLORTET		return ' target="' . hsc($target) . '"';
213c9c7f3bSLORTET	}
223c9c7f3bSLORTET
233c9c7f3bSLORTET    private function renderInfoMessage(Doku_Renderer $renderer, $langKey) {
243c9c7f3bSLORTET        $message = $this->getLang($langKey);
253c9c7f3bSLORTET        if(!$message) {
263c9c7f3bSLORTET            $message = 'Nothing to display.';
273c9c7f3bSLORTET        }
283c9c7f3bSLORTET        $renderer->doc .= '<div class="visualindex_info">' . hsc($message) . '</div>';
293c9c7f3bSLORTET    }
303c9c7f3bSLORTET
313c9c7f3bSLORTET    public function getType() {
32*7f5290b8SLORTET        return 'substition'; // substition = remplacer la balise par du contenu (orthographe figée dans l'API DokuWiki)
333c9c7f3bSLORTET    }
343c9c7f3bSLORTET
353c9c7f3bSLORTET    public function getPType() {
363c9c7f3bSLORTET        return 'block';
373c9c7f3bSLORTET    }
383c9c7f3bSLORTET
393c9c7f3bSLORTET    public function getSort() { // priorité du plugin par rapport à d'autres
403c9c7f3bSLORTET        return 10;
413c9c7f3bSLORTET    }
423c9c7f3bSLORTET
433c9c7f3bSLORTET    /**
443c9c7f3bSLORTET	 * Reconnaît la syntaxe {{visualindex>[namespace]}}
453c9c7f3bSLORTET     */
463c9c7f3bSLORTET    public function connectTo($mode) { // reconnait la syntaxe utilisé par l'utilisateur
473c9c7f3bSLORTET        $this->Lexer->addSpecialPattern('{{visualindex>.*?}}', $mode, 'plugin_visualindex_visualindex');
483c9c7f3bSLORTET    }
493c9c7f3bSLORTET
503c9c7f3bSLORTET    /**
513c9c7f3bSLORTET     * Nettoie  {{visualindex>[namespace]}}
523c9c7f3bSLORTET     */
533c9c7f3bSLORTET    public function handle($match, $state, $pos, Doku_Handler $handler) {
543c9c7f3bSLORTET		$paramsString = trim(substr($match, 14, -2));
553c9c7f3bSLORTET		$params = explode(';', $paramsString);
563c9c7f3bSLORTET    	$namespace = trim(array_shift($params));
573c9c7f3bSLORTET
583c9c7f3bSLORTET		$result = ['namespace' => $namespace];
593c9c7f3bSLORTET
603c9c7f3bSLORTET		foreach ($params as $param) {
613c9c7f3bSLORTET			$param = trim($param);
623c9c7f3bSLORTET			$paramParts = explode('=', $param, 2);
633c9c7f3bSLORTET			$paramName = $paramParts[0];
643c9c7f3bSLORTET			$paramValue = isset($paramParts[1])? $paramParts[1] : true;
653c9c7f3bSLORTET			$result[$paramName] = $paramValue;
663c9c7f3bSLORTET		}
673c9c7f3bSLORTET
683c9c7f3bSLORTET		return $result;
693c9c7f3bSLORTET	}
703c9c7f3bSLORTET
713c9c7f3bSLORTET	private function getCurrentNamespace($ID, $getMedias = false) {
723c9c7f3bSLORTET		if(!is_dir($this->namespaceDir($ID, $getMedias))) {
733c9c7f3bSLORTET			$pageNamespaceInfo = $this->getNamespaceInfo($ID);
743c9c7f3bSLORTET			if($this->isHomepage($pageNamespaceInfo['pageID'], $pageNamespaceInfo['parentID'])) {
753c9c7f3bSLORTET				return $pageNamespaceInfo['parentNamespace'];
763c9c7f3bSLORTET			}
773c9c7f3bSLORTET		}
783c9c7f3bSLORTET
793c9c7f3bSLORTET		return $ID;
803c9c7f3bSLORTET	}
813c9c7f3bSLORTET
823c9c7f3bSLORTET    public function render($mode, Doku_Renderer $renderer, $data) {
833c9c7f3bSLORTET		if($mode !== 'xhtml' && $mode !== 'wikiedit') return false;
843c9c7f3bSLORTET
853c9c7f3bSLORTET		global $ID;
863c9c7f3bSLORTET
873c9c7f3bSLORTET		$getMedias = isset($data['medias']) && $data['medias'] || false;
883c9c7f3bSLORTET		$filter = isset($data['filter'])? $data['filter'] : null;
893c9c7f3bSLORTET		$desc = isset($data['desc']) && $data['desc'] || false;
903c9c7f3bSLORTET
913c9c7f3bSLORTET		if($data['namespace'] === '.') { // Récupération du namespace courant
923c9c7f3bSLORTET			$namespace = $this->getCurrentNamespace($ID, $getMedias);
933c9c7f3bSLORTET		}
943c9c7f3bSLORTET		elseif(strpos($data['namespace'], '~') === 0) {
953c9c7f3bSLORTET			$relativeNamespace = cleanID(ltrim($data['namespace'], '~'));
963c9c7f3bSLORTET			$currentNamespace = $this->getCurrentNamespace($ID, $getMedias);
973c9c7f3bSLORTET        	$namespace = $currentNamespace . ':' . $relativeNamespace;
983c9c7f3bSLORTET		}
993c9c7f3bSLORTET		else {
1003c9c7f3bSLORTET			$namespace = cleanID($data['namespace']);
1013c9c7f3bSLORTET		}
1023c9c7f3bSLORTET
1033c9c7f3bSLORTET		$items = $this->getItemsAndSubfoldersItems($namespace, $getMedias, $filter, $desc);
1043c9c7f3bSLORTET		if($items === false) {
1053c9c7f3bSLORTET			$this->renderInfoMessage($renderer, 'namespace_not_found');
1063c9c7f3bSLORTET			return true;
1073c9c7f3bSLORTET		}
1083c9c7f3bSLORTET		if(empty($items)) {
1093c9c7f3bSLORTET			$this->renderInfoMessage($renderer, 'empty');
1103c9c7f3bSLORTET			return true;
1113c9c7f3bSLORTET		}
1123c9c7f3bSLORTET
113*7f5290b8SLORTET		// Tri stable : homepages en premier, ordre de scan préservé pour les égaux
114*7f5290b8SLORTET		$idx = 0;
115*7f5290b8SLORTET		foreach ($items as &$item) { $item['_idx'] = $idx++; }
116*7f5290b8SLORTET		unset($item);
1173c9c7f3bSLORTET		usort($items, function($a, $b) {
118*7f5290b8SLORTET			$diff = $b['sortID'] - $a['sortID'];
119*7f5290b8SLORTET			return $diff !== 0 ? $diff : ($a['_idx'] - $b['_idx']);
1203c9c7f3bSLORTET		});
1213c9c7f3bSLORTET
122*7f5290b8SLORTET		$tileWidth = $this->getConf('tile_width');
123*7f5290b8SLORTET		$iconSize  = $this->getConf('icon_size');
124*7f5290b8SLORTET		$textSize  = $this->getConf('text_size');
125*7f5290b8SLORTET		$textColor = $this->getConf('text_color');
126*7f5290b8SLORTET
127*7f5290b8SLORTET		// Styles inline dérivés de la configuration
128*7f5290b8SLORTET		$tileStyle = 'width:' . hsc($tileWidth) . ';';
129*7f5290b8SLORTET		$imgStyle  = 'max-width:' . hsc($iconSize) . ';max-height:' . hsc($iconSize) . ';';
1303c9c7f3bSLORTET
1313c9c7f3bSLORTET		// -----------------------------
1323c9c7f3bSLORTET		// ProseMirror / HTML wrapper
1333c9c7f3bSLORTET		// -----------------------------
1343c9c7f3bSLORTET		$renderer->doc .= '<span class="plugin_visualindex" '
1353c9c7f3bSLORTET			.'data-namespace="'.htmlspecialchars($namespace).'" '
1363c9c7f3bSLORTET			.'data-filter="'.htmlspecialchars($filter).'" '
1373c9c7f3bSLORTET			.'data-desc="'.($desc ? '1' : '0').'">';
1383c9c7f3bSLORTET
1393c9c7f3bSLORTET		// -----------------------------
1403c9c7f3bSLORTET		// HTML classique pour le rendu visuel
1413c9c7f3bSLORTET		// -----------------------------
1423c9c7f3bSLORTET		$renderer->doc .= '<div class="visualindex">';
1433c9c7f3bSLORTET
1443c9c7f3bSLORTET		$renderedItems = 0;
1453c9c7f3bSLORTET		foreach ($items as $item) {
1463c9c7f3bSLORTET			$pageID        = $item['pageID'];
147*7f5290b8SLORTET			$itemNamespace = $item['namespace'];
1483c9c7f3bSLORTET			$pageNamespace = $item['pageNamespace'];
1493c9c7f3bSLORTET			$isHomepage    = $item['isHomepage'];
1503c9c7f3bSLORTET
1513c9c7f3bSLORTET			if($pageNamespace == $ID) {
1523c9c7f3bSLORTET				continue;
1533c9c7f3bSLORTET			}
1543c9c7f3bSLORTET
1553c9c7f3bSLORTET			$permission = auth_quickaclcheck($pageNamespace);
1563c9c7f3bSLORTET			if($permission < AUTH_READ) {
1573c9c7f3bSLORTET				continue;
1583c9c7f3bSLORTET			}
1593c9c7f3bSLORTET
1603c9c7f3bSLORTET			$logoUrl = null;
1613c9c7f3bSLORTET			if(!$getMedias) {
1623c9c7f3bSLORTET				$title = p_get_first_heading($pageNamespace);
1633c9c7f3bSLORTET				if(empty($title)) {
1643c9c7f3bSLORTET					continue;
1653c9c7f3bSLORTET				}
1663c9c7f3bSLORTET			}
1673c9c7f3bSLORTET			else {
1683c9c7f3bSLORTET				$title = str_replace('_', ' ', $pageID);
1693c9c7f3bSLORTET				$logoUrl = $this->getMediaItemImage($pageNamespace);
1703c9c7f3bSLORTET			}
1713c9c7f3bSLORTET
1723c9c7f3bSLORTET			if(!$logoUrl) {
173*7f5290b8SLORTET				$logoUrl = $this->getPageImage($itemNamespace, $pageID);
1743c9c7f3bSLORTET			}
1753c9c7f3bSLORTET
1763c9c7f3bSLORTET			// Afficher le lien de la page ou du sous-dossier
1773c9c7f3bSLORTET			$targetAttr = $getMedias ? $this->getMediaLinkTargetAttr() : '';
178*7f5290b8SLORTET			$renderer->doc .= '<a class="vi_tile' . ($isHomepage? ' homepage' : '') . '" style="' . $tileStyle . 'color:' . $textColor . ';font-size:' . $textSize . '" href="'. ($getMedias? ml($pageNamespace) : wl($pageNamespace)) . '"' . $targetAttr . '>';
179*7f5290b8SLORTET				$renderer->doc .= '<div class="vi_content"><img loading="lazy" src="' . $logoUrl . '" style="' . $imgStyle . '" alt="" /><br />' . $title . '</div>';
1803c9c7f3bSLORTET				$renderer->doc .= '<div class="vi_vertical_align"></div>';
1813c9c7f3bSLORTET			$renderer->doc .= '</a>';
1823c9c7f3bSLORTET			$renderedItems++;
1833c9c7f3bSLORTET		}
1843c9c7f3bSLORTET
1853c9c7f3bSLORTET		$renderer->doc .= '</div>';
1863c9c7f3bSLORTET
1873c9c7f3bSLORTET		if($renderedItems === 0) {
1883c9c7f3bSLORTET			$this->renderInfoMessage($renderer, 'empty');
1893c9c7f3bSLORTET		}
1903c9c7f3bSLORTET
1913c9c7f3bSLORTET		$renderer->doc .= '</span>';
1923c9c7f3bSLORTET		// -----------------------------
1933c9c7f3bSLORTET		// Fin du node ProseMirror
1943c9c7f3bSLORTET		// -----------------------------
1953c9c7f3bSLORTET
1963c9c7f3bSLORTET		return true;
1973c9c7f3bSLORTET	}
1983c9c7f3bSLORTET
1993c9c7f3bSLORTET	private function getPagesiconHelper() {
2003c9c7f3bSLORTET		if($this->pagesiconHelper === false) {
2013c9c7f3bSLORTET			$this->pagesiconHelper = plugin_load('helper', 'pagesicon');
2023c9c7f3bSLORTET		}
2033c9c7f3bSLORTET		return $this->pagesiconHelper ?: null;
2043c9c7f3bSLORTET	}
2053c9c7f3bSLORTET
2063c9c7f3bSLORTET	private function getDefaultImageUrl() {
2073c9c7f3bSLORTET		$defaultImage = cleanID((string)$this->getConf('default_image'));
2083c9c7f3bSLORTET		if($defaultImage !== '' && @file_exists(mediaFN($defaultImage))) {
2093c9c7f3bSLORTET			return ml($defaultImage, ['width' => 55]);
2103c9c7f3bSLORTET		}
2113c9c7f3bSLORTET
2123c9c7f3bSLORTET		return '/lib/plugins/visualindex/images/default_image.png';
2133c9c7f3bSLORTET	}
2143c9c7f3bSLORTET
2153c9c7f3bSLORTET	private function getMediaItemImage($mediaID) {
2163c9c7f3bSLORTET		$mediaID = cleanID((string)$mediaID);
2173c9c7f3bSLORTET		if($mediaID === '') {
2183c9c7f3bSLORTET			return $this->getDefaultImageUrl();
2193c9c7f3bSLORTET		}
2203c9c7f3bSLORTET
2213c9c7f3bSLORTET		$helper = $this->getPagesiconHelper();
2223c9c7f3bSLORTET		if((bool)$this->getConf('use_pagesicon') && $helper) {
2233c9c7f3bSLORTET			if(method_exists($helper, 'getMediaIconUrl')) {
2243c9c7f3bSLORTET				$mtime = null;
2253c9c7f3bSLORTET				$iconUrl = $helper->getMediaIconUrl($mediaID, 'bigorsmall', ['width' => 55], $mtime, false);
2263c9c7f3bSLORTET				if($iconUrl) return $iconUrl;
2273c9c7f3bSLORTET			} else if(method_exists($helper, 'getMediaIcon')) {
2283c9c7f3bSLORTET				$mtime = null;
2293c9c7f3bSLORTET				$withDefaultSupported = false;
2303c9c7f3bSLORTET				try {
2313c9c7f3bSLORTET					$method = new ReflectionMethod($helper, 'getMediaIcon');
2323c9c7f3bSLORTET					$withDefaultSupported = $method->getNumberOfParameters() >= 5;
2333c9c7f3bSLORTET				} catch (ReflectionException $e) {
2343c9c7f3bSLORTET					$withDefaultSupported = false;
2353c9c7f3bSLORTET				}
2363c9c7f3bSLORTET
2373c9c7f3bSLORTET				if($withDefaultSupported) {
2383c9c7f3bSLORTET					$iconUrl = $helper->getMediaIcon($mediaID, 'bigorsmall', ['width' => 55], $mtime, false);
2393c9c7f3bSLORTET				} else {
2403c9c7f3bSLORTET					$iconUrl = $helper->getMediaIcon($mediaID, 'bigorsmall', ['width' => 55], $mtime);
2413c9c7f3bSLORTET				}
2423c9c7f3bSLORTET				if($iconUrl) return $iconUrl;
2433c9c7f3bSLORTET			}
2443c9c7f3bSLORTET		}
2453c9c7f3bSLORTET
2463c9c7f3bSLORTET		$childPathInfo = pathinfo(noNS($mediaID));
2473c9c7f3bSLORTET		$imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'];
2483c9c7f3bSLORTET		if(isset($childPathInfo['extension']) && in_array(strtolower((string)$childPathInfo['extension']), $imageExtensions, true)) {
2493c9c7f3bSLORTET			return ml($mediaID);
2503c9c7f3bSLORTET		}
2513c9c7f3bSLORTET
2523c9c7f3bSLORTET		return $this->getDefaultImageUrl();
2533c9c7f3bSLORTET	}
2543c9c7f3bSLORTET
2553c9c7f3bSLORTET	/**
2563c9c7f3bSLORTET	 * Renvoie l'URL de l'icone de la page via pagesicon, sinon image par defaut.
2573c9c7f3bSLORTET	 */
258*7f5290b8SLORTET	private function getPageImage($namespace, $pageID = null) {
2593c9c7f3bSLORTET		if(!$pageID) {
2603c9c7f3bSLORTET			$pageNamespaceInfo = $this->getNamespaceInfo($namespace);
2613c9c7f3bSLORTET			$namespace = $pageNamespaceInfo['parentNamespace'];
2623c9c7f3bSLORTET			$pageID = $pageNamespaceInfo['pageID'];
2633c9c7f3bSLORTET		}
2643c9c7f3bSLORTET
2653c9c7f3bSLORTET		$helper = $this->getPagesiconHelper();
2663c9c7f3bSLORTET		if((bool)$this->getConf('use_pagesicon') && $helper) {
2673c9c7f3bSLORTET			if(method_exists($helper, 'getPageIconUrl')) {
2683c9c7f3bSLORTET				$mtime = null;
2693c9c7f3bSLORTET				$iconUrl = $helper->getPageIconUrl((string)$namespace, (string)$pageID, 'bigorsmall', ['width' => 55], $mtime, false);
2703c9c7f3bSLORTET				if($iconUrl) return $iconUrl;
2713c9c7f3bSLORTET			} else if(method_exists($helper, 'getImageIcon')) {
2723c9c7f3bSLORTET				$mtime = null;
2733c9c7f3bSLORTET				$withDefaultSupported = false;
2743c9c7f3bSLORTET				try {
2753c9c7f3bSLORTET					$method = new ReflectionMethod($helper, 'getImageIcon');
2763c9c7f3bSLORTET					$withDefaultSupported = $method->getNumberOfParameters() >= 6;
2773c9c7f3bSLORTET				} catch (ReflectionException $e) {
2783c9c7f3bSLORTET					$withDefaultSupported = false;
2793c9c7f3bSLORTET				}
2803c9c7f3bSLORTET
2813c9c7f3bSLORTET				if($withDefaultSupported) {
2823c9c7f3bSLORTET					$iconUrl = $helper->getImageIcon((string)$namespace, (string)$pageID, 'bigorsmall', ['width' => 55], $mtime, false);
2833c9c7f3bSLORTET				} else {
2843c9c7f3bSLORTET					$iconUrl = $helper->getImageIcon((string)$namespace, (string)$pageID, 'bigorsmall', ['width' => 55], $mtime);
2853c9c7f3bSLORTET				}
2863c9c7f3bSLORTET				if($iconUrl) return $iconUrl;
2873c9c7f3bSLORTET			}
2883c9c7f3bSLORTET		}
2893c9c7f3bSLORTET
2903c9c7f3bSLORTET		return $this->getDefaultImageUrl();
2913c9c7f3bSLORTET	}
2923c9c7f3bSLORTET
2933c9c7f3bSLORTET
294*7f5290b8SLORTET	private function createListItem($parentNamespace, $pageID, $isHomepage = false) {
2953c9c7f3bSLORTET		return array(
2963c9c7f3bSLORTET			'pageID' => $pageID,
2973c9c7f3bSLORTET			'namespace' => $parentNamespace,
2983c9c7f3bSLORTET			'pageNamespace' => cleanID("$parentNamespace:$pageID"),
2993c9c7f3bSLORTET			'sortID' => ($isHomepage? 100 : 0),
3003c9c7f3bSLORTET			'isHomepage' => $isHomepage
3013c9c7f3bSLORTET		);
3023c9c7f3bSLORTET	}
3033c9c7f3bSLORTET
3043c9c7f3bSLORTET	/**
3053c9c7f3bSLORTET	 * Récupère à la fois les pages et les sous-dossiers d'un namespace
3063c9c7f3bSLORTET	 */
307*7f5290b8SLORTET	private function getItemsAndSubfoldersItems($namespace, $getMedias = false, $filter = null, $desc = false) {
3083c9c7f3bSLORTET		global $conf;
3093c9c7f3bSLORTET
3103c9c7f3bSLORTET		$childrens = @scandir($this->namespaceDir($namespace, $getMedias), $desc? SCANDIR_SORT_DESCENDING : SCANDIR_SORT_ASCENDING);
3113c9c7f3bSLORTET		if($childrens === false) {
3123c9c7f3bSLORTET			if($getMedias) {
3133c9c7f3bSLORTET				$childrens = @scandir($this->namespaceDir($namespace));
3143c9c7f3bSLORTET				if($childrens != false) {
3153c9c7f3bSLORTET					return [];
3163c9c7f3bSLORTET				}
3173c9c7f3bSLORTET			}
3183c9c7f3bSLORTET
3193c9c7f3bSLORTET			return false;
3203c9c7f3bSLORTET		}
3213c9c7f3bSLORTET
322*7f5290b8SLORTET		$start = $conf['start']; // page d'accueil du namespace
3233c9c7f3bSLORTET
3243c9c7f3bSLORTET		$finalPattern = null;
3253c9c7f3bSLORTET		if($filter) {
3263c9c7f3bSLORTET			$parts = explode('|', $filter);
3273c9c7f3bSLORTET			$regexParts = [];
3283c9c7f3bSLORTET			foreach ($parts as $part) {
3293c9c7f3bSLORTET				$pattern = preg_quote($part, '/');
3303c9c7f3bSLORTET				$pattern = str_replace('\*', '.*', $pattern);
3313c9c7f3bSLORTET				$regexParts[] = '^' . $pattern . '$';
3323c9c7f3bSLORTET			}
3333c9c7f3bSLORTET
3343c9c7f3bSLORTET			$finalPattern = '/(' . implode('|', $regexParts) . ')/i';
3353c9c7f3bSLORTET		}
3363c9c7f3bSLORTET
3373c9c7f3bSLORTET		$items = [];
3383c9c7f3bSLORTET		foreach($childrens as $child) {
3393c9c7f3bSLORTET			if($child[0] == '.' ) {
3403c9c7f3bSLORTET				continue;
3413c9c7f3bSLORTET			}
3423c9c7f3bSLORTET
3433c9c7f3bSLORTET			if($finalPattern && !preg_match($finalPattern, $child)) {
3443c9c7f3bSLORTET				continue;
3453c9c7f3bSLORTET			}
3463c9c7f3bSLORTET
3473c9c7f3bSLORTET			$childPathInfo = pathinfo($child);
3483c9c7f3bSLORTET			$childID = cleanID($childPathInfo['filename']);
3493c9c7f3bSLORTET			$childNamespace = cleanID("$namespace:$childID");
3503c9c7f3bSLORTET
3513c9c7f3bSLORTET			$childHasExtension = isset($childPathInfo['extension']) && $childPathInfo['extension'] !== '';
3523c9c7f3bSLORTET			$isDirNamespace = is_dir($this->namespaceDir($childNamespace, $getMedias));
3533c9c7f3bSLORTET			$isPageNamespace = page_exists($childNamespace);
3543c9c7f3bSLORTET
3553c9c7f3bSLORTET			if($getMedias) {
3563c9c7f3bSLORTET				if($childHasExtension) {
3573c9c7f3bSLORTET					$items[] = $this->createListItem($namespace, $child);
3583c9c7f3bSLORTET				}
3593c9c7f3bSLORTET				continue;
3603c9c7f3bSLORTET			}
3613c9c7f3bSLORTET
3623c9c7f3bSLORTET			if(!$childHasExtension && $isDirNamespace) { // Si dossier
3633c9c7f3bSLORTET				if(page_exists("$childNamespace:$start")) { // S'il y a une page d'accueil
3643c9c7f3bSLORTET					$items[] = $this->createListItem($childNamespace, $start);
3653c9c7f3bSLORTET				}
3663c9c7f3bSLORTET				else if(page_exists("$childNamespace:$childID")) { // S'il y a une page du même nom que le dossier dans le dossier
3673c9c7f3bSLORTET					$items[] = $this->createListItem($childNamespace, $childID);
3683c9c7f3bSLORTET				}
3693c9c7f3bSLORTET				else if($isPageNamespace) { // S'il y a une page du même nom que le dossier au même niveau que le dossier
3703c9c7f3bSLORTET					$items[] = $this->createListItem($namespace, $childID);
3713c9c7f3bSLORTET				}
3723c9c7f3bSLORTET
3733c9c7f3bSLORTET				continue;
3743c9c7f3bSLORTET			}
3753c9c7f3bSLORTET
3763c9c7f3bSLORTET			if(!$isDirNamespace && $isPageNamespace) {
3773c9c7f3bSLORTET				$skipRegex = $this->getConf('skip_file');
3783c9c7f3bSLORTET				if (!empty($skipRegex) && preg_match($skipRegex, $childNamespace)) {
3793c9c7f3bSLORTET					continue;
3803c9c7f3bSLORTET				}
3813c9c7f3bSLORTET
3823c9c7f3bSLORTET				$isHomepage = false;
3833c9c7f3bSLORTET				$pageNamespaceInfo = $this->getNamespaceInfo("$namespace:$childID");
3843c9c7f3bSLORTET				if($this->isHomepage($childID, $pageNamespaceInfo['parentID'])) {
3853c9c7f3bSLORTET					$isHomepage = true;
3863c9c7f3bSLORTET				}
3873c9c7f3bSLORTET
3883c9c7f3bSLORTET				$items[] = $this->createListItem($namespace, $childID, $isHomepage);
3893c9c7f3bSLORTET			}
3903c9c7f3bSLORTET		}
3913c9c7f3bSLORTET
3923c9c7f3bSLORTET		return $items;
3933c9c7f3bSLORTET	}
3943c9c7f3bSLORTET
395*7f5290b8SLORTET	private function isHomepage($pageID, $parentID) {
3963c9c7f3bSLORTET		global $conf;
3973c9c7f3bSLORTET		$startPageID = $conf['start'];
3983c9c7f3bSLORTET
3993c9c7f3bSLORTET		return $pageID == $startPageID || $pageID == $parentID;
4003c9c7f3bSLORTET	}
4013c9c7f3bSLORTET
402*7f5290b8SLORTET	private function namespaceDir($namespace, $getMedias = false) {
4033c9c7f3bSLORTET		global $conf;
4043c9c7f3bSLORTET
4053c9c7f3bSLORTET		// Choix du dossier selon le mode
4063c9c7f3bSLORTET		$baseDir = $getMedias ? $conf['mediadir'] : $conf['datadir'];
4073c9c7f3bSLORTET
4083c9c7f3bSLORTET		// Remplacement des deux-points par des slashs et encodage UTF-8
4093c9c7f3bSLORTET		return $baseDir . '/' . utf8_encodeFN(str_replace(':', '/', $namespace));
4103c9c7f3bSLORTET	}
4113c9c7f3bSLORTET
412*7f5290b8SLORTET	private function getNamespaceInfo($namespace) {
4133c9c7f3bSLORTET		$namespaces = explode(':', $namespace);
4143c9c7f3bSLORTET
4153c9c7f3bSLORTET		return array(
4163c9c7f3bSLORTET			'pageNamespace' => $namespace,
4173c9c7f3bSLORTET			'pageID' => array_pop($namespaces),
4183c9c7f3bSLORTET			'parentNamespace' => implode(':', $namespaces),
4193c9c7f3bSLORTET			'parentID' => array_pop($namespaces)
4203c9c7f3bSLORTET		);
4213c9c7f3bSLORTET	}
4223c9c7f3bSLORTET}
423