[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/diviner/publisher/ -> DivinerStaticPublisher.php (source)

   1  <?php
   2  
   3  final class DivinerStaticPublisher extends DivinerPublisher {
   4  
   5    private $publishCache;
   6    private $atomNameMap;
   7  
   8    private function getPublishCache() {
   9      if (!$this->publishCache) {
  10        $dir = implode(
  11          DIRECTORY_SEPARATOR,
  12          array(
  13            $this->getConfig('root'),
  14            '.divinercache',
  15            $this->getConfig('name'),
  16            'static',
  17          ));
  18        $this->publishCache = new DivinerPublishCache($dir);
  19      }
  20  
  21      return $this->publishCache;
  22    }
  23  
  24    protected function loadAllPublishedHashes() {
  25      return array_keys($this->getPublishCache()->getPathMap());
  26    }
  27  
  28    protected function deleteDocumentsByHash(array $hashes) {
  29      $root = $this->getConfig('root');
  30      $cache = $this->getPublishCache();
  31  
  32      foreach ($hashes as $hash) {
  33        $paths = $cache->getAtomPathsFromCache($hash);
  34        foreach ($paths as $path) {
  35          $abs = $root.DIRECTORY_SEPARATOR.$path;
  36          Filesystem::remove($abs);
  37  
  38          // If the parent directory is now empty, clean it up.
  39          $dir = dirname($abs);
  40          while (true) {
  41            if (!Filesystem::isDescendant($dir, $root)) {
  42              // Directory is outside of the root.
  43              break;
  44            }
  45            if (Filesystem::listDirectory($dir)) {
  46              // Directory is not empty.
  47              break;
  48            }
  49  
  50            Filesystem::remove($dir);
  51            $dir = dirname($dir);
  52          }
  53        }
  54  
  55        $cache->removeAtomPathsFromCache($hash);
  56        $cache->deleteAtomFromIndex($hash);
  57      }
  58    }
  59  
  60    protected function createDocumentsByHash(array $hashes) {
  61      $indexes = array();
  62  
  63      $cache = $this->getPublishCache();
  64  
  65      foreach ($hashes as $hash) {
  66        $atom = $this->getAtomFromGraphHash($hash);
  67  
  68        $paths = array();
  69        if ($this->shouldGenerateDocumentForAtom($atom)) {
  70          $content = $this->getRenderer()->renderAtom($atom);
  71  
  72          $this->writeDocument($atom, $content);
  73  
  74          $paths[] = $this->getAtomRelativePath($atom);
  75          if ($this->getAtomSimilarIndex($atom) !== null) {
  76            $index = dirname($this->getAtomRelativePath($atom)).'index.html';
  77            $indexes[$index] = $atom;
  78            $paths[] = $index;
  79          }
  80  
  81          $this->addAtomToIndex($hash, $atom);
  82        }
  83  
  84        $cache->addAtomPathsToCache($hash, $paths);
  85      }
  86  
  87      foreach ($indexes as $index => $atoms) {
  88        // TODO: Publish disambiguation pages.
  89      }
  90  
  91      $this->publishIndex();
  92  
  93      $cache->writePathMap();
  94      $cache->writeIndex();
  95    }
  96  
  97    private function publishIndex() {
  98      $index = $this->getPublishCache()->getIndex();
  99      $refs = array();
 100      foreach ($index as $hash => $dictionary) {
 101        $refs[$hash] = DivinerAtomRef::newFromDictionary($dictionary);
 102      }
 103  
 104      $content = $this->getRenderer()->renderAtomIndex($refs);
 105  
 106      $path = implode(
 107        DIRECTORY_SEPARATOR,
 108        array(
 109          $this->getConfig('root'),
 110          'docs',
 111          $this->getConfig('name'),
 112          'index.html',
 113        ));
 114  
 115      Filesystem::writeFile($path, $content);
 116    }
 117  
 118    public function findAtomByRef(DivinerAtomRef $ref) {
 119      if ($ref->getBook() != $this->getConfig('name')) {
 120        return null;
 121      }
 122  
 123      if ($this->atomNameMap === null) {
 124        $name_map = array();
 125        foreach ($this->getPublishCache()->getIndex() as $hash => $dict) {
 126          $name_map[$dict['name']][$hash] = $dict;
 127        }
 128        $this->atomNameMap = $name_map;
 129      }
 130  
 131      $name = $ref->getName();
 132      if (empty($this->atomNameMap[$name])) {
 133        return null;
 134      }
 135  
 136      $candidates = $this->atomNameMap[$name];
 137      foreach ($candidates as $key => $dict) {
 138        $candidates[$key] = DivinerAtomRef::newFromDict($dict);
 139        if ($ref->getType()) {
 140          if ($candidates[$key]->getType() != $ref->getType()) {
 141            unset($candidates[$key]);
 142          }
 143        }
 144  
 145        if ($ref->getContext()) {
 146          if ($candidates[$key]->getContext() != $ref->getContext()) {
 147            unset($candidates[$key]);
 148          }
 149        }
 150      }
 151  
 152      // If we have exactly one uniquely identifiable atom, return it.
 153      if (count($candidates) == 1) {
 154        return $this->getAtomFromNodeHash(last_key($candidates));
 155      }
 156  
 157      return null;
 158    }
 159  
 160    private function addAtomToIndex($hash, DivinerAtom $atom) {
 161      $ref = $atom->getRef();
 162      $ref->setIndex($this->getAtomSimilarIndex($atom));
 163      $ref->setSummary($this->getRenderer()->renderAtomSummary($atom));
 164  
 165      $this->getPublishCache()->addAtomToIndex($hash, $ref->toDictionary());
 166    }
 167  
 168    private function writeDocument(DivinerAtom $atom, $content) {
 169      $root = $this->getConfig('root');
 170      $path = $root.DIRECTORY_SEPARATOR.$this->getAtomRelativePath($atom);
 171  
 172      if (!Filesystem::pathExists($path)) {
 173        Filesystem::createDirectory($path, $umask = 0755, $recursive = true);
 174      }
 175  
 176      Filesystem::writeFile($path.'index.html', $content);
 177  
 178      return $this;
 179    }
 180  
 181    private function getAtomRelativePath(DivinerAtom $atom) {
 182      $ref = $atom->getRef();
 183  
 184      $book = $ref->getBook();
 185      $type = $ref->getType();
 186      $context = $ref->getContext();
 187      $name = $ref->getName();
 188  
 189      $path = array(
 190        'docs',
 191        $book,
 192        $type,
 193      );
 194      if ($context !== null) {
 195        $path[] = $context;
 196      }
 197      $path[] = $name;
 198  
 199      $index = $this->getAtomSimilarIndex($atom);
 200      if ($index !== null) {
 201        $path[] = '@'.$index;
 202      }
 203  
 204      $path[] = null;
 205  
 206      return implode(DIRECTORY_SEPARATOR, $path);
 207    }
 208  
 209  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1