[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/File/ -> Resolver.php (source)

   1  <?php
   2  
   3  namespace dokuwiki\File;
   4  
   5  /**
   6   * Resolving relative IDs to absolute ones
   7   */
   8  abstract class Resolver
   9  {
  10  
  11      /** @var string context page ID */
  12      protected $contextID;
  13      /** @var string namespace of context page ID */
  14      protected $contextNS;
  15  
  16      /**
  17       * @param string $contextID the current pageID that's the context to resolve relative IDs to
  18       */
  19      public function __construct($contextID)
  20      {
  21          $this->contextID = $contextID;
  22          $this->contextNS = (string)getNS($contextID);
  23      }
  24  
  25      /**
  26       * Resolves a given ID to be absolute
  27       *
  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
  32       */
  33      public function resolveId($id, $rev = '', $isDateAt = false)
  34      {
  35          global $conf;
  36  
  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);
  41  
  42          $id = $this->resolvePrefix($id);
  43          return $this->resolveRelatives($id);
  44      }
  45  
  46      /**
  47       * Handle IDs starting with . or ~ and prepend the proper prefix
  48       *
  49       * @param string $id
  50       * @return string
  51       */
  52      protected function resolvePrefix($id)
  53      {
  54          // relative to current page (makes the current page a start page)
  55          if ($id[0] === '~') {
  56              $id = $this->contextID . ':' . substr($id, 1);
  57          }
  58  
  59          // relative to current namespace
  60          if ($id[0] === '.') {
  61              // normalize initial dots without a colon
  62              $id = preg_replace('/^((\.+:)*)(\.+)(?=[^:\.])/', '\1\3:', $id);
  63              $id = $this->contextNS . ':' . $id;
  64          }
  65  
  66          // auto-relative, because there is a context namespace but no namespace in the ID
  67          if ($this->contextID !== '' && strpos($id, ':') === false) {
  68              $id = $this->contextNS . ':' . $id;
  69          }
  70  
  71          return $id;
  72      }
  73  
  74      /**
  75       * Handle . and .. within IDs
  76       *
  77       * @param string $id
  78       * @return string
  79       */
  80      protected function resolveRelatives($id)
  81      {
  82          if ($id === '') return '';
  83          $trail = ($id[-1] === ':') ? ':' : ''; // keep trailing colon
  84  
  85          $result = [];
  86          $parts = explode(':', $id);
  87  
  88          foreach ($parts as $dir) {
  89              if ($dir === '.') continue;
  90              if ($dir === '') continue;
  91              if ($dir === '..') {
  92                  array_pop($result);
  93                  continue;
  94              }
  95              array_push($result, $dir);
  96          }
  97  
  98          $id = implode(':', $result);
  99          $id .= $trail;
 100  
 101          return $id;
 102      }
 103  
 104  }