123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- <?php
- namespace dokuwiki\File;
- /**
- * Resolving relative IDs to absolute ones
- */
- abstract class Resolver
- {
- /** @var string context page ID */
- protected $contextID;
- /** @var string namespace of context page ID */
- protected $contextNS;
- /**
- * @param string $contextID the current pageID that's the context to resolve relative IDs to
- */
- public function __construct($contextID)
- {
- $this->contextID = $contextID;
- $this->contextNS = (string)getNS($contextID);
- }
- /**
- * Resolves a given ID to be absolute
- *
- * @param string $id The ID to resolve
- * @param string|int|false $rev The revision time to use when resolving
- * @param bool $isDateAt Is the given revision only a datetime hint not an exact revision?
- * @return string
- */
- public function resolveId($id, $rev = '', $isDateAt = false)
- {
- global $conf;
- // some pre cleaning for useslash:
- if ($conf['useslash']) $id = str_replace('/', ':', $id);
- // on some systems, semicolons might be used instead of colons:
- $id = str_replace(';', ':', $id);
- $id = $this->resolvePrefix($id);
- return $this->resolveRelatives($id);
- }
- /**
- * Handle IDs starting with . or ~ and prepend the proper prefix
- *
- * @param string $id
- * @return string
- */
- protected function resolvePrefix($id)
- {
- if($id === '') return $id;
- // relative to current page (makes the current page a start page)
- if ($id[0] === '~') {
- $id = $this->contextID . ':' . substr($id, 1);
- }
- // relative to current namespace
- if ($id[0] === '.') {
- // normalize initial dots without a colon
- $id = preg_replace('/^((\.+:)*)(\.+)(?=[^:\.])/', '\1\3:', $id);
- $id = $this->contextNS . ':' . $id;
- }
- // auto-relative, because there is a context namespace but no namespace in the ID
- if ($this->contextID !== '' && strpos($id, ':') === false) {
- $id = $this->contextNS . ':' . $id;
- }
- return $id;
- }
- /**
- * Handle . and .. within IDs
- *
- * @param string $id
- * @return string
- */
- protected function resolveRelatives($id)
- {
- if ($id === '') return '';
- $trail = ($id[-1] === ':') ? ':' : ''; // keep trailing colon
- $result = [];
- $parts = explode(':', $id);
- foreach ($parts as $dir) {
- if ($dir === '.') continue;
- if ($dir === '') continue;
- if ($dir === '..') {
- array_pop($result);
- continue;
- }
- array_push($result, $dir);
- }
- $id = implode(':', $result);
- $id .= $trail;
- return $id;
- }
- }
|