xref: /plugin/visualindex/syntax/visualindex.php (revision 3c9c7f3beeea1dce712c368cb507b309c63f5d06)
1*3c9c7f3bSLORTET<?php
2*3c9c7f3bSLORTET/**
3*3c9c7f3bSLORTET * Plugin visualindex
4*3c9c7f3bSLORTET * Affiche les pages d’un namespace donné
5*3c9c7f3bSLORTET * Auteur: Choimetg, Lortetv
6*3c9c7f3bSLORTET */
7*3c9c7f3bSLORTET
8*3c9c7f3bSLORTETuse dokuwiki\Extension\SyntaxPlugin;
9*3c9c7f3bSLORTETuse dokuwiki\File\PageResolver;
10*3c9c7f3bSLORTETuse dokuwiki\Ui\Index;
11*3c9c7f3bSLORTET
12*3c9c7f3bSLORTETclass syntax_plugin_visualindex_visualindex extends SyntaxPlugin {
13*3c9c7f3bSLORTET    /** @var helper_plugin_pagesicon|null|false */
14*3c9c7f3bSLORTET    private $pagesiconHelper = false;
15*3c9c7f3bSLORTET
16*3c9c7f3bSLORTET	private function getMediaLinkTargetAttr() {
17*3c9c7f3bSLORTET		global $conf;
18*3c9c7f3bSLORTET		$target = (string)($conf['target']['media'] ?? '');
19*3c9c7f3bSLORTET		if($target === '') return '';
20*3c9c7f3bSLORTET		return ' target="' . hsc($target) . '"';
21*3c9c7f3bSLORTET	}
22*3c9c7f3bSLORTET
23*3c9c7f3bSLORTET    private function renderInfoMessage(Doku_Renderer $renderer, $langKey) {
24*3c9c7f3bSLORTET        $message = $this->getLang($langKey);
25*3c9c7f3bSLORTET        if(!$message) {
26*3c9c7f3bSLORTET            $message = 'Nothing to display.';
27*3c9c7f3bSLORTET        }
28*3c9c7f3bSLORTET        $renderer->doc .= '<div class="visualindex_info">' . hsc($message) . '</div>';
29*3c9c7f3bSLORTET    }
30*3c9c7f3bSLORTET
31*3c9c7f3bSLORTET    public function getType() {
32*3c9c7f3bSLORTET        return 'substition'; // substitution = remplacer la balise par du contenu
33*3c9c7f3bSLORTET    }
34*3c9c7f3bSLORTET
35*3c9c7f3bSLORTET    public function getPType() {
36*3c9c7f3bSLORTET        return 'block';
37*3c9c7f3bSLORTET    }
38*3c9c7f3bSLORTET
39*3c9c7f3bSLORTET    public function getSort() { // priorité du plugin par rapport à d'autres
40*3c9c7f3bSLORTET        return 10;
41*3c9c7f3bSLORTET    }
42*3c9c7f3bSLORTET
43*3c9c7f3bSLORTET    /**
44*3c9c7f3bSLORTET	 * Reconnaît la syntaxe {{visualindex>[namespace]}}
45*3c9c7f3bSLORTET     */
46*3c9c7f3bSLORTET    public function connectTo($mode) { // reconnait la syntaxe utilisé par l'utilisateur
47*3c9c7f3bSLORTET        $this->Lexer->addSpecialPattern('{{visualindex>.*?}}', $mode, 'plugin_visualindex_visualindex');
48*3c9c7f3bSLORTET    }
49*3c9c7f3bSLORTET
50*3c9c7f3bSLORTET    /**
51*3c9c7f3bSLORTET     * Nettoie  {{visualindex>[namespace]}}
52*3c9c7f3bSLORTET     */
53*3c9c7f3bSLORTET    public function handle($match, $state, $pos, Doku_Handler $handler) {
54*3c9c7f3bSLORTET		$paramsString = trim(substr($match, 14, -2));
55*3c9c7f3bSLORTET		$params = explode(';', $paramsString);
56*3c9c7f3bSLORTET    	$namespace = trim(array_shift($params));
57*3c9c7f3bSLORTET
58*3c9c7f3bSLORTET		$result = ['namespace' => $namespace];
59*3c9c7f3bSLORTET
60*3c9c7f3bSLORTET		foreach ($params as $param) {
61*3c9c7f3bSLORTET			$param = trim($param);
62*3c9c7f3bSLORTET			$paramParts = explode('=', $param, 2);
63*3c9c7f3bSLORTET			$paramName = $paramParts[0];
64*3c9c7f3bSLORTET			$paramValue = isset($paramParts[1])? $paramParts[1] : true;
65*3c9c7f3bSLORTET			$result[$paramName] = $paramValue;
66*3c9c7f3bSLORTET		}
67*3c9c7f3bSLORTET
68*3c9c7f3bSLORTET		return $result;
69*3c9c7f3bSLORTET	}
70*3c9c7f3bSLORTET
71*3c9c7f3bSLORTET	private function getCurrentNamespace($ID, $getMedias = false) {
72*3c9c7f3bSLORTET		if(!is_dir($this->namespaceDir($ID, $getMedias))) {
73*3c9c7f3bSLORTET			$pageNamespaceInfo = $this->getNamespaceInfo($ID);
74*3c9c7f3bSLORTET			if($this->isHomepage($pageNamespaceInfo['pageID'], $pageNamespaceInfo['parentID'])) {
75*3c9c7f3bSLORTET				return $pageNamespaceInfo['parentNamespace'];
76*3c9c7f3bSLORTET			}
77*3c9c7f3bSLORTET		}
78*3c9c7f3bSLORTET
79*3c9c7f3bSLORTET		return $ID;
80*3c9c7f3bSLORTET	}
81*3c9c7f3bSLORTET
82*3c9c7f3bSLORTET    public function render($mode, Doku_Renderer $renderer, $data) {
83*3c9c7f3bSLORTET		if($mode !== 'xhtml' && $mode !== 'wikiedit') return false;
84*3c9c7f3bSLORTET
85*3c9c7f3bSLORTET		global $ID;
86*3c9c7f3bSLORTET
87*3c9c7f3bSLORTET		$getMedias = isset($data['medias']) && $data['medias'] || false;
88*3c9c7f3bSLORTET		$filter = isset($data['filter'])? $data['filter'] : null;
89*3c9c7f3bSLORTET		$desc = isset($data['desc']) && $data['desc'] || false;
90*3c9c7f3bSLORTET
91*3c9c7f3bSLORTET		if($data['namespace'] === '.') { // Récupération du namespace courant
92*3c9c7f3bSLORTET			$namespace = $this->getCurrentNamespace($ID, $getMedias);
93*3c9c7f3bSLORTET		}
94*3c9c7f3bSLORTET		elseif(strpos($data['namespace'], '~') === 0) {
95*3c9c7f3bSLORTET			$relativeNamespace = cleanID(ltrim($data['namespace'], '~'));
96*3c9c7f3bSLORTET			$currentNamespace = $this->getCurrentNamespace($ID, $getMedias);
97*3c9c7f3bSLORTET        	$namespace = $currentNamespace . ':' . $relativeNamespace;
98*3c9c7f3bSLORTET		}
99*3c9c7f3bSLORTET		else {
100*3c9c7f3bSLORTET			$namespace = cleanID($data['namespace']);
101*3c9c7f3bSLORTET		}
102*3c9c7f3bSLORTET
103*3c9c7f3bSLORTET		$items = $this->getItemsAndSubfoldersItems($namespace, $getMedias, $filter, $desc);
104*3c9c7f3bSLORTET		if($items === false) {
105*3c9c7f3bSLORTET			$this->renderInfoMessage($renderer, 'namespace_not_found');
106*3c9c7f3bSLORTET			return true;
107*3c9c7f3bSLORTET		}
108*3c9c7f3bSLORTET		if(empty($items)) {
109*3c9c7f3bSLORTET			$this->renderInfoMessage($renderer, 'empty');
110*3c9c7f3bSLORTET			return true;
111*3c9c7f3bSLORTET		}
112*3c9c7f3bSLORTET
113*3c9c7f3bSLORTET		usort($items, function($a, $b) {
114*3c9c7f3bSLORTET			return $b['sortID'] - $a['sortID'];
115*3c9c7f3bSLORTET		});
116*3c9c7f3bSLORTET
117*3c9c7f3bSLORTET		$textSize = $this->getConf('taille_texte');
118*3c9c7f3bSLORTET		$textColor = $this->getConf('couleur_texte');
119*3c9c7f3bSLORTET
120*3c9c7f3bSLORTET		// -----------------------------
121*3c9c7f3bSLORTET		// ProseMirror / HTML wrapper
122*3c9c7f3bSLORTET		// -----------------------------
123*3c9c7f3bSLORTET		$renderer->doc .= '<span class="plugin_visualindex" '
124*3c9c7f3bSLORTET			.'data-namespace="'.htmlspecialchars($namespace).'" '
125*3c9c7f3bSLORTET			.'data-filter="'.htmlspecialchars($filter).'" '
126*3c9c7f3bSLORTET			.'data-desc="'.($desc ? '1' : '0').'">';
127*3c9c7f3bSLORTET
128*3c9c7f3bSLORTET		// -----------------------------
129*3c9c7f3bSLORTET		// HTML classique pour le rendu visuel
130*3c9c7f3bSLORTET		// -----------------------------
131*3c9c7f3bSLORTET		$renderer->doc .= '<div class="visualindex">';
132*3c9c7f3bSLORTET
133*3c9c7f3bSLORTET		$renderedItems = 0;
134*3c9c7f3bSLORTET		foreach ($items as $item) {
135*3c9c7f3bSLORTET			$pageID = $item['pageID'];
136*3c9c7f3bSLORTET			$namespace = $item['namespace'];
137*3c9c7f3bSLORTET			$pageNamespace = $item['pageNamespace'];
138*3c9c7f3bSLORTET			$sortID = $item['sortID'];
139*3c9c7f3bSLORTET			$isHomepage = $item['isHomepage'];
140*3c9c7f3bSLORTET
141*3c9c7f3bSLORTET			if($pageNamespace == $ID) {
142*3c9c7f3bSLORTET				continue;
143*3c9c7f3bSLORTET			}
144*3c9c7f3bSLORTET
145*3c9c7f3bSLORTET			$permission = auth_quickaclcheck($pageNamespace);
146*3c9c7f3bSLORTET			if($permission < AUTH_READ) {
147*3c9c7f3bSLORTET				continue;
148*3c9c7f3bSLORTET			}
149*3c9c7f3bSLORTET
150*3c9c7f3bSLORTET			$logoUrl = null;
151*3c9c7f3bSLORTET			if(!$getMedias) {
152*3c9c7f3bSLORTET				$title = p_get_first_heading($pageNamespace);
153*3c9c7f3bSLORTET				if(empty($title)) {
154*3c9c7f3bSLORTET					continue;
155*3c9c7f3bSLORTET				}
156*3c9c7f3bSLORTET			}
157*3c9c7f3bSLORTET			else {
158*3c9c7f3bSLORTET				$title = str_replace('_', ' ', $pageID);
159*3c9c7f3bSLORTET				$logoUrl = $this->getMediaItemImage($pageNamespace);
160*3c9c7f3bSLORTET			}
161*3c9c7f3bSLORTET
162*3c9c7f3bSLORTET			if(!$logoUrl) {
163*3c9c7f3bSLORTET				$logoUrl = $this->getPageImage($namespace, $pageID);
164*3c9c7f3bSLORTET			}
165*3c9c7f3bSLORTET
166*3c9c7f3bSLORTET			// Afficher le lien de la page ou du sous-dossier
167*3c9c7f3bSLORTET			$targetAttr = $getMedias ? $this->getMediaLinkTargetAttr() : '';
168*3c9c7f3bSLORTET			$renderer->doc .= '<a class="vi_tile' . ($isHomepage? ' homepage' : '') . '" style="color:' . $textColor . ' ; font-size:' . $textSize . '" href="'. ($getMedias? ml($pageNamespace) : wl($pageNamespace)) . '"' . $targetAttr . '>';
169*3c9c7f3bSLORTET				$renderer->doc .= '<div class="vi_content"><img loading="lazy" src="' . $logoUrl . '" alt="" /><br />' . $title . '</div>';
170*3c9c7f3bSLORTET				$renderer->doc .= '<div class="vi_vertical_align"></div>';
171*3c9c7f3bSLORTET			$renderer->doc .= '</a>';
172*3c9c7f3bSLORTET			$renderedItems++;
173*3c9c7f3bSLORTET		}
174*3c9c7f3bSLORTET
175*3c9c7f3bSLORTET		$renderer->doc .= '</div>';
176*3c9c7f3bSLORTET
177*3c9c7f3bSLORTET		if($renderedItems === 0) {
178*3c9c7f3bSLORTET			$this->renderInfoMessage($renderer, 'empty');
179*3c9c7f3bSLORTET		}
180*3c9c7f3bSLORTET
181*3c9c7f3bSLORTET		$renderer->doc .= '</span>';
182*3c9c7f3bSLORTET		// -----------------------------
183*3c9c7f3bSLORTET		// Fin du node ProseMirror
184*3c9c7f3bSLORTET		// -----------------------------
185*3c9c7f3bSLORTET
186*3c9c7f3bSLORTET		return true;
187*3c9c7f3bSLORTET	}
188*3c9c7f3bSLORTET
189*3c9c7f3bSLORTET	private function getPagesiconHelper() {
190*3c9c7f3bSLORTET		if($this->pagesiconHelper === false) {
191*3c9c7f3bSLORTET			$this->pagesiconHelper = plugin_load('helper', 'pagesicon');
192*3c9c7f3bSLORTET		}
193*3c9c7f3bSLORTET		return $this->pagesiconHelper ?: null;
194*3c9c7f3bSLORTET	}
195*3c9c7f3bSLORTET
196*3c9c7f3bSLORTET	private function getDefaultImageUrl() {
197*3c9c7f3bSLORTET		$defaultImage = cleanID((string)$this->getConf('default_image'));
198*3c9c7f3bSLORTET		if($defaultImage !== '' && @file_exists(mediaFN($defaultImage))) {
199*3c9c7f3bSLORTET			return ml($defaultImage, ['width' => 55]);
200*3c9c7f3bSLORTET		}
201*3c9c7f3bSLORTET
202*3c9c7f3bSLORTET		return '/lib/plugins/visualindex/images/default_image.png';
203*3c9c7f3bSLORTET	}
204*3c9c7f3bSLORTET
205*3c9c7f3bSLORTET	private function getMediaItemImage($mediaID) {
206*3c9c7f3bSLORTET		$mediaID = cleanID((string)$mediaID);
207*3c9c7f3bSLORTET		if($mediaID === '') {
208*3c9c7f3bSLORTET			return $this->getDefaultImageUrl();
209*3c9c7f3bSLORTET		}
210*3c9c7f3bSLORTET
211*3c9c7f3bSLORTET		$helper = $this->getPagesiconHelper();
212*3c9c7f3bSLORTET		if((bool)$this->getConf('use_pagesicon') && $helper) {
213*3c9c7f3bSLORTET			if(method_exists($helper, 'getMediaIconUrl')) {
214*3c9c7f3bSLORTET				$mtime = null;
215*3c9c7f3bSLORTET				$iconUrl = $helper->getMediaIconUrl($mediaID, 'bigorsmall', ['width' => 55], $mtime, false);
216*3c9c7f3bSLORTET				if($iconUrl) return $iconUrl;
217*3c9c7f3bSLORTET			} else if(method_exists($helper, 'getMediaIcon')) {
218*3c9c7f3bSLORTET				$mtime = null;
219*3c9c7f3bSLORTET				$withDefaultSupported = false;
220*3c9c7f3bSLORTET				try {
221*3c9c7f3bSLORTET					$method = new ReflectionMethod($helper, 'getMediaIcon');
222*3c9c7f3bSLORTET					$withDefaultSupported = $method->getNumberOfParameters() >= 5;
223*3c9c7f3bSLORTET				} catch (ReflectionException $e) {
224*3c9c7f3bSLORTET					$withDefaultSupported = false;
225*3c9c7f3bSLORTET				}
226*3c9c7f3bSLORTET
227*3c9c7f3bSLORTET				if($withDefaultSupported) {
228*3c9c7f3bSLORTET					$iconUrl = $helper->getMediaIcon($mediaID, 'bigorsmall', ['width' => 55], $mtime, false);
229*3c9c7f3bSLORTET				} else {
230*3c9c7f3bSLORTET					$iconUrl = $helper->getMediaIcon($mediaID, 'bigorsmall', ['width' => 55], $mtime);
231*3c9c7f3bSLORTET				}
232*3c9c7f3bSLORTET				if($iconUrl) return $iconUrl;
233*3c9c7f3bSLORTET			}
234*3c9c7f3bSLORTET		}
235*3c9c7f3bSLORTET
236*3c9c7f3bSLORTET		$childPathInfo = pathinfo(noNS($mediaID));
237*3c9c7f3bSLORTET		$imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'];
238*3c9c7f3bSLORTET		if(isset($childPathInfo['extension']) && in_array(strtolower((string)$childPathInfo['extension']), $imageExtensions, true)) {
239*3c9c7f3bSLORTET			return ml($mediaID);
240*3c9c7f3bSLORTET		}
241*3c9c7f3bSLORTET
242*3c9c7f3bSLORTET		return $this->getDefaultImageUrl();
243*3c9c7f3bSLORTET	}
244*3c9c7f3bSLORTET
245*3c9c7f3bSLORTET	/**
246*3c9c7f3bSLORTET	 * Renvoie l'URL de l'icone de la page via pagesicon, sinon image par defaut.
247*3c9c7f3bSLORTET	 */
248*3c9c7f3bSLORTET	public function getPageImage($namespace, $pageID = null) {
249*3c9c7f3bSLORTET		if(!$pageID) {
250*3c9c7f3bSLORTET			$pageNamespaceInfo = $this->getNamespaceInfo($namespace);
251*3c9c7f3bSLORTET			$namespace = $pageNamespaceInfo['parentNamespace'];
252*3c9c7f3bSLORTET			$pageID = $pageNamespaceInfo['pageID'];
253*3c9c7f3bSLORTET		}
254*3c9c7f3bSLORTET
255*3c9c7f3bSLORTET		$helper = $this->getPagesiconHelper();
256*3c9c7f3bSLORTET		if((bool)$this->getConf('use_pagesicon') && $helper) {
257*3c9c7f3bSLORTET			if(method_exists($helper, 'getPageIconUrl')) {
258*3c9c7f3bSLORTET				$mtime = null;
259*3c9c7f3bSLORTET				$iconUrl = $helper->getPageIconUrl((string)$namespace, (string)$pageID, 'bigorsmall', ['width' => 55], $mtime, false);
260*3c9c7f3bSLORTET				if($iconUrl) return $iconUrl;
261*3c9c7f3bSLORTET			} else if(method_exists($helper, 'getImageIcon')) {
262*3c9c7f3bSLORTET				$mtime = null;
263*3c9c7f3bSLORTET				$withDefaultSupported = false;
264*3c9c7f3bSLORTET				try {
265*3c9c7f3bSLORTET					$method = new ReflectionMethod($helper, 'getImageIcon');
266*3c9c7f3bSLORTET					$withDefaultSupported = $method->getNumberOfParameters() >= 6;
267*3c9c7f3bSLORTET				} catch (ReflectionException $e) {
268*3c9c7f3bSLORTET					$withDefaultSupported = false;
269*3c9c7f3bSLORTET				}
270*3c9c7f3bSLORTET
271*3c9c7f3bSLORTET				if($withDefaultSupported) {
272*3c9c7f3bSLORTET					$iconUrl = $helper->getImageIcon((string)$namespace, (string)$pageID, 'bigorsmall', ['width' => 55], $mtime, false);
273*3c9c7f3bSLORTET				} else {
274*3c9c7f3bSLORTET					$iconUrl = $helper->getImageIcon((string)$namespace, (string)$pageID, 'bigorsmall', ['width' => 55], $mtime);
275*3c9c7f3bSLORTET				}
276*3c9c7f3bSLORTET				if($iconUrl) return $iconUrl;
277*3c9c7f3bSLORTET			}
278*3c9c7f3bSLORTET		}
279*3c9c7f3bSLORTET
280*3c9c7f3bSLORTET		return $this->getDefaultImageUrl();
281*3c9c7f3bSLORTET	}
282*3c9c7f3bSLORTET
283*3c9c7f3bSLORTET
284*3c9c7f3bSLORTET	public function createListItem($parentNamespace, $pageID, $isHomepage = false) {
285*3c9c7f3bSLORTET		return array(
286*3c9c7f3bSLORTET			'pageID' => $pageID,
287*3c9c7f3bSLORTET			'namespace' => $parentNamespace,
288*3c9c7f3bSLORTET			'pageNamespace' => cleanID("$parentNamespace:$pageID"),
289*3c9c7f3bSLORTET			'sortID' => ($isHomepage? 100 : 0),
290*3c9c7f3bSLORTET			'isHomepage' => $isHomepage
291*3c9c7f3bSLORTET		);
292*3c9c7f3bSLORTET	}
293*3c9c7f3bSLORTET
294*3c9c7f3bSLORTET	/**
295*3c9c7f3bSLORTET	 * Récupère à la fois les pages et les sous-dossiers d'un namespace
296*3c9c7f3bSLORTET	 */
297*3c9c7f3bSLORTET	public function getItemsAndSubfoldersItems($namespace, $getMedias = false, $filter = null, $desc = false) {
298*3c9c7f3bSLORTET		global $conf;
299*3c9c7f3bSLORTET
300*3c9c7f3bSLORTET		$childrens = @scandir($this->namespaceDir($namespace, $getMedias), $desc? SCANDIR_SORT_DESCENDING : SCANDIR_SORT_ASCENDING);
301*3c9c7f3bSLORTET		if($childrens === false) {
302*3c9c7f3bSLORTET			if($getMedias) {
303*3c9c7f3bSLORTET				$childrens = @scandir($this->namespaceDir($namespace));
304*3c9c7f3bSLORTET				if($childrens != false) {
305*3c9c7f3bSLORTET					return [];
306*3c9c7f3bSLORTET				}
307*3c9c7f3bSLORTET			}
308*3c9c7f3bSLORTET
309*3c9c7f3bSLORTET			return false;
310*3c9c7f3bSLORTET		}
311*3c9c7f3bSLORTET
312*3c9c7f3bSLORTET		$start = $conf['start']; // 'accueil' dans la plupart des temps (dans bpnum:d-s:accueil)
313*3c9c7f3bSLORTET
314*3c9c7f3bSLORTET		$finalPattern = null;
315*3c9c7f3bSLORTET		if($filter) {
316*3c9c7f3bSLORTET			$parts = explode('|', $filter);
317*3c9c7f3bSLORTET			$regexParts = [];
318*3c9c7f3bSLORTET			foreach ($parts as $part) {
319*3c9c7f3bSLORTET				$pattern = preg_quote($part, '/');
320*3c9c7f3bSLORTET				$pattern = str_replace('\*', '.*', $pattern);
321*3c9c7f3bSLORTET				$regexParts[] = '^' . $pattern . '$';
322*3c9c7f3bSLORTET			}
323*3c9c7f3bSLORTET
324*3c9c7f3bSLORTET			$finalPattern = '/(' . implode('|', $regexParts) . ')/i';
325*3c9c7f3bSLORTET		}
326*3c9c7f3bSLORTET
327*3c9c7f3bSLORTET		$items = [];
328*3c9c7f3bSLORTET		foreach($childrens as $child) {
329*3c9c7f3bSLORTET			if($child[0] == '.' ) {
330*3c9c7f3bSLORTET				continue;
331*3c9c7f3bSLORTET			}
332*3c9c7f3bSLORTET
333*3c9c7f3bSLORTET			if($finalPattern && !preg_match($finalPattern, $child)) {
334*3c9c7f3bSLORTET				continue;
335*3c9c7f3bSLORTET			}
336*3c9c7f3bSLORTET
337*3c9c7f3bSLORTET			$childPathInfo = pathinfo($child);
338*3c9c7f3bSLORTET			$childID = cleanID($childPathInfo['filename']);
339*3c9c7f3bSLORTET			$childNamespace = cleanID("$namespace:$childID");
340*3c9c7f3bSLORTET
341*3c9c7f3bSLORTET			$childHasExtension = isset($childPathInfo['extension']) && $childPathInfo['extension'] !== '';
342*3c9c7f3bSLORTET			$isDirNamespace = is_dir($this->namespaceDir($childNamespace, $getMedias));
343*3c9c7f3bSLORTET			$isPageNamespace = page_exists($childNamespace);
344*3c9c7f3bSLORTET
345*3c9c7f3bSLORTET			if($getMedias) {
346*3c9c7f3bSLORTET				if($childHasExtension) {
347*3c9c7f3bSLORTET					$items[] = $this->createListItem($namespace, $child);
348*3c9c7f3bSLORTET				}
349*3c9c7f3bSLORTET				continue;
350*3c9c7f3bSLORTET			}
351*3c9c7f3bSLORTET
352*3c9c7f3bSLORTET			if(!$childHasExtension && $isDirNamespace) { // Si dossier
353*3c9c7f3bSLORTET				if(page_exists("$childNamespace:$start")) { // S'il y a une page d'accueil
354*3c9c7f3bSLORTET					$items[] = $this->createListItem($childNamespace, $start);
355*3c9c7f3bSLORTET				}
356*3c9c7f3bSLORTET				else if(page_exists("$childNamespace:$childID")) { // S'il y a une page du même nom que le dossier dans le dossier
357*3c9c7f3bSLORTET					$items[] = $this->createListItem($childNamespace, $childID);
358*3c9c7f3bSLORTET				}
359*3c9c7f3bSLORTET				else if($isPageNamespace) { // S'il y a une page du même nom que le dossier au même niveau que le dossier
360*3c9c7f3bSLORTET					$items[] = $this->createListItem($namespace, $childID);
361*3c9c7f3bSLORTET				}
362*3c9c7f3bSLORTET
363*3c9c7f3bSLORTET				continue;
364*3c9c7f3bSLORTET			}
365*3c9c7f3bSLORTET
366*3c9c7f3bSLORTET			if(!$isDirNamespace && $isPageNamespace) {
367*3c9c7f3bSLORTET				$skipRegex = $this->getConf('skip_file');
368*3c9c7f3bSLORTET				if (!empty($skipRegex) && preg_match($skipRegex, $childNamespace)) {
369*3c9c7f3bSLORTET					continue;
370*3c9c7f3bSLORTET				}
371*3c9c7f3bSLORTET
372*3c9c7f3bSLORTET				$isHomepage = false;
373*3c9c7f3bSLORTET				$pageNamespaceInfo = $this->getNamespaceInfo("$namespace:$childID");
374*3c9c7f3bSLORTET				if($this->isHomepage($childID, $pageNamespaceInfo['parentID'])) {
375*3c9c7f3bSLORTET					$isHomepage = true;
376*3c9c7f3bSLORTET				}
377*3c9c7f3bSLORTET
378*3c9c7f3bSLORTET				$items[] = $this->createListItem($namespace, $childID, $isHomepage);
379*3c9c7f3bSLORTET			}
380*3c9c7f3bSLORTET		}
381*3c9c7f3bSLORTET
382*3c9c7f3bSLORTET		return $items;
383*3c9c7f3bSLORTET	}
384*3c9c7f3bSLORTET
385*3c9c7f3bSLORTET	public function isHomepage($pageID, $parentID) {
386*3c9c7f3bSLORTET		global $conf;
387*3c9c7f3bSLORTET		$startPageID = $conf['start'];
388*3c9c7f3bSLORTET
389*3c9c7f3bSLORTET		return $pageID == $startPageID || $pageID == $parentID;
390*3c9c7f3bSLORTET	}
391*3c9c7f3bSLORTET
392*3c9c7f3bSLORTET	public function namespaceDir($namespace, $getMedias = false) {
393*3c9c7f3bSLORTET		global $conf;
394*3c9c7f3bSLORTET
395*3c9c7f3bSLORTET		// Choix du dossier selon le mode
396*3c9c7f3bSLORTET		$baseDir = $getMedias ? $conf['mediadir'] : $conf['datadir'];
397*3c9c7f3bSLORTET
398*3c9c7f3bSLORTET		// Remplacement des deux-points par des slashs et encodage UTF-8
399*3c9c7f3bSLORTET		return $baseDir . '/' . utf8_encodeFN(str_replace(':', '/', $namespace));
400*3c9c7f3bSLORTET	}
401*3c9c7f3bSLORTET
402*3c9c7f3bSLORTET	public function getNamespaceInfo($namespace) {
403*3c9c7f3bSLORTET		$namespaces = explode(':', $namespace);
404*3c9c7f3bSLORTET
405*3c9c7f3bSLORTET		return array(
406*3c9c7f3bSLORTET			'pageNamespace' => $namespace,
407*3c9c7f3bSLORTET			'pageID' => array_pop($namespaces),
408*3c9c7f3bSLORTET			'parentNamespace' => implode(':', $namespaces),
409*3c9c7f3bSLORTET			'parentID' => array_pop($namespaces)
410*3c9c7f3bSLORTET		);
411*3c9c7f3bSLORTET	}
412*3c9c7f3bSLORTET}
413