1<?php 2 3namespace dokuwiki\File; 4 5/** 6 * Creates an absolute page ID from a relative one 7 */ 8class PageResolver extends Resolver 9{ 10 /** 11 * Resolves a given ID to be absolute 12 * 13 * This handles all kinds of relative shortcuts, startpages and autoplurals 14 * @inheritDoc 15 */ 16 public function resolveId($id, $rev = '', $isDateAt = false) 17 { 18 global $conf; 19 $id = (string) $id; 20 21 // pages may have a hash attached, we separate it on resolving 22 if (strpos($id, '#') !== false) { 23 [$id, $hash] = sexplode('#', $id, 2); 24 $hash = cleanID($hash); 25 } else { 26 $hash = ''; 27 } 28 29 if ($id !== '') { 30 $id = parent::resolveId($id, $rev, $isDateAt); 31 $id = $this->resolveStartPage($id, $rev, $isDateAt); 32 if ($conf['autoplural']) { 33 $id = $this->resolveAutoPlural($id, $rev, $isDateAt); 34 } 35 } else { 36 $id = $this->contextID; 37 } 38 39 $id = cleanID($id); // FIXME always? or support parameter 40 // readd hash if any 41 if ($hash !== '') $id .= "#$hash"; 42 return $id; 43 } 44 45 /** 46 * IDs ending in : 47 * 48 * @param string $id 49 * @param string|int|false $rev 50 * @param bool $isDateAt 51 * @return string 52 */ 53 protected function resolveStartPage($id, $rev, $isDateAt) 54 { 55 global $conf; 56 57 if ($id === '' || $id[-1] !== ':') return $id; 58 59 if (page_exists($id . $conf['start'], $rev, true, $isDateAt)) { 60 // start page inside namespace 61 return $id . $conf['start']; 62 } elseif (page_exists($id . noNS(cleanID($id)), $rev, true, $isDateAt)) { 63 // page named like the NS inside the NS 64 return $id . noNS(cleanID($id)); 65 } elseif (page_exists(substr($id, 0, -1), $rev, true, $isDateAt)) { 66 // page named like the NS outside the NS 67 return substr($id, 0, -1); 68 } 69 70 // fall back to default start page 71 return $id . $conf['start']; 72 } 73 74 /** 75 * Try alternative plural/singular form 76 * 77 * @param string $id 78 * @param int $rev 79 * @param bool $isDateAt 80 * @return string 81 */ 82 protected function resolveAutoPlural($id, $rev, $isDateAt) 83 { 84 if (page_exists($id, $rev, $isDateAt)) return $id; 85 86 if ($id[-1] === 's') { 87 $try = substr($id, 0, -1); 88 } else { 89 $try = $id . 's'; 90 } 91 92 if (page_exists($try, $rev, true, $isDateAt)) { 93 return $try; 94 } 95 return $id; 96 } 97} 98