do not try to resolve prefixes of an empty ID
[dokuwiki.git] / inc / File / Resolver.php
blobe3734cf6977efe99f4e8f65274209588029ba0bd
1 <?php
3 namespace dokuwiki\File;
5 /**
6 * Resolving relative IDs to absolute ones
7 */
8 abstract class Resolver
11 /** @var string context page ID */
12 protected $contextID;
13 /** @var string namespace of context page ID */
14 protected $contextNS;
16 /**
17 * @param string $contextID the current pageID that's the context to resolve relative IDs to
19 public function __construct($contextID)
21 $this->contextID = $contextID;
22 $this->contextNS = (string)getNS($contextID);
25 /**
26 * Resolves a given ID to be absolute
28 * @param string $id The ID to resolve
29 * @param string|int|false $rev The revision time to use when resolving
30 * @param bool $isDateAt Is the given revision only a datetime hint not an exact revision?
31 * @return string
33 public function resolveId($id, $rev = '', $isDateAt = false)
35 global $conf;
37 // some pre cleaning for useslash:
38 if ($conf['useslash']) $id = str_replace('/', ':', $id);
39 // on some systems, semicolons might be used instead of colons:
40 $id = str_replace(';', ':', $id);
42 $id = $this->resolvePrefix($id);
43 return $this->resolveRelatives($id);
46 /**
47 * Handle IDs starting with . or ~ and prepend the proper prefix
49 * @param string $id
50 * @return string
52 protected function resolvePrefix($id)
54 if($id === '') return $id;
56 // relative to current page (makes the current page a start page)
57 if ($id[0] === '~') {
58 $id = $this->contextID . ':' . substr($id, 1);
61 // relative to current namespace
62 if ($id[0] === '.') {
63 // normalize initial dots without a colon
64 $id = preg_replace('/^((\.+:)*)(\.+)(?=[^:\.])/', '\1\3:', $id);
65 $id = $this->contextNS . ':' . $id;
68 // auto-relative, because there is a context namespace but no namespace in the ID
69 if ($this->contextID !== '' && strpos($id, ':') === false) {
70 $id = $this->contextNS . ':' . $id;
73 return $id;
76 /**
77 * Handle . and .. within IDs
79 * @param string $id
80 * @return string
82 protected function resolveRelatives($id)
84 if ($id === '') return '';
85 $trail = ($id[-1] === ':') ? ':' : ''; // keep trailing colon
87 $result = [];
88 $parts = explode(':', $id);
90 foreach ($parts as $dir) {
91 if ($dir === '.') continue;
92 if ($dir === '') continue;
93 if ($dir === '..') {
94 array_pop($result);
95 continue;
97 array_push($result, $dir);
100 $id = implode(':', $result);
101 $id .= $trail;
103 return $id;