Path: blob/master/src/applications/diviner/publisher/DivinerStaticPublisher.php
12256 views
<?php12final class DivinerStaticPublisher extends DivinerPublisher {34private $publishCache;5private $atomNameMap;67private function getPublishCache() {8if (!$this->publishCache) {9$dir = implode(10DIRECTORY_SEPARATOR,11array(12$this->getConfig('root'),13'.divinercache',14$this->getConfig('name'),15'static',16));17$this->publishCache = new DivinerPublishCache($dir);18}1920return $this->publishCache;21}2223protected function loadAllPublishedHashes() {24return array_keys($this->getPublishCache()->getPathMap());25}2627protected function deleteDocumentsByHash(array $hashes) {28$root = $this->getConfig('root');29$cache = $this->getPublishCache();3031foreach ($hashes as $hash) {32$paths = $cache->getAtomPathsFromCache($hash);33foreach ($paths as $path) {34$abs = $root.DIRECTORY_SEPARATOR.$path;35Filesystem::remove($abs);3637// If the parent directory is now empty, clean it up.38$dir = dirname($abs);39while (true) {40if (!Filesystem::isDescendant($dir, $root)) {41// Directory is outside of the root.42break;43}44if (Filesystem::listDirectory($dir)) {45// Directory is not empty.46break;47}4849Filesystem::remove($dir);50$dir = dirname($dir);51}52}5354$cache->removeAtomPathsFromCache($hash);55$cache->deleteAtomFromIndex($hash);56}57}5859protected function createDocumentsByHash(array $hashes) {60$indexes = array();61$cache = $this->getPublishCache();6263foreach ($hashes as $hash) {64$atom = $this->getAtomFromGraphHash($hash);6566$paths = array();67if ($this->shouldGenerateDocumentForAtom($atom)) {68$content = $this->getRenderer()->renderAtom($atom);6970$this->writeDocument($atom, $content);7172$paths[] = $this->getAtomRelativePath($atom);73if ($this->getAtomSimilarIndex($atom) !== null) {74$index = dirname($this->getAtomRelativePath($atom)).'index.html';75$indexes[$index] = $atom;76$paths[] = $index;77}7879$this->addAtomToIndex($hash, $atom);80}8182$cache->addAtomPathsToCache($hash, $paths);83}8485foreach ($indexes as $index => $atoms) {86// TODO: Publish disambiguation pages.87}8889$this->publishIndex();90$cache->writePathMap();91$cache->writeIndex();92}9394private function publishIndex() {95$index = $this->getPublishCache()->getIndex();96$refs = array();9798foreach ($index as $hash => $dictionary) {99$refs[$hash] = DivinerAtomRef::newFromDictionary($dictionary);100}101102$content = $this->getRenderer()->renderAtomIndex($refs);103104$path = implode(105DIRECTORY_SEPARATOR,106array(107$this->getConfig('root'),108'docs',109$this->getConfig('name'),110'index.html',111));112113Filesystem::writeFile($path, $content);114}115116public function findAtomByRef(DivinerAtomRef $ref) {117if ($ref->getBook() != $this->getConfig('name')) {118return null;119}120121if ($this->atomNameMap === null) {122$name_map = array();123foreach ($this->getPublishCache()->getIndex() as $hash => $dict) {124$name_map[$dict['name']][$hash] = $dict;125}126$this->atomNameMap = $name_map;127}128129$name = $ref->getName();130if (empty($this->atomNameMap[$name])) {131return null;132}133134$candidates = $this->atomNameMap[$name];135foreach ($candidates as $key => $dict) {136$candidates[$key] = DivinerAtomRef::newFromDictionary($dict);137if ($ref->getType()) {138if ($candidates[$key]->getType() != $ref->getType()) {139unset($candidates[$key]);140}141}142143if ($ref->getContext()) {144if ($candidates[$key]->getContext() != $ref->getContext()) {145unset($candidates[$key]);146}147}148}149150// If we have exactly one uniquely identifiable atom, return it.151if (count($candidates) == 1) {152return $this->getAtomFromNodeHash(last_key($candidates));153}154155return null;156}157158private function addAtomToIndex($hash, DivinerAtom $atom) {159$ref = $atom->getRef();160$ref->setIndex($this->getAtomSimilarIndex($atom));161$ref->setSummary($this->getRenderer()->renderAtomSummary($atom));162163$this->getPublishCache()->addAtomToIndex($hash, $ref->toDictionary());164}165166private function writeDocument(DivinerAtom $atom, $content) {167$root = $this->getConfig('root');168$path = $root.DIRECTORY_SEPARATOR.$this->getAtomRelativePath($atom);169170if (!Filesystem::pathExists($path)) {171Filesystem::createDirectory($path, $umask = 0755, $recursive = true);172}173174Filesystem::writeFile($path.'index.html', $content);175176return $this;177}178179private function getAtomRelativePath(DivinerAtom $atom) {180$ref = $atom->getRef();181182$book = $ref->getBook();183$type = $ref->getType();184$context = $ref->getContext();185$name = $ref->getName();186187$path = array(188'docs',189$book,190$type,191);192if ($context !== null) {193$path[] = $context;194}195$path[] = $name;196197$index = $this->getAtomSimilarIndex($atom);198if ($index !== null) {199$path[] = '@'.$index;200}201202$path[] = null;203204return implode(DIRECTORY_SEPARATOR, $path);205}206207}208209210