X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=mdref%2FAction.php;h=37b3d51321ebab4400b8400420b621f91e07d5ec;hb=31c2b666caffa28ea1576ed9c2f4c2280f2a2d45;hp=18f60691b21b0d96a1176f43ac760509355b4c70;hpb=d5aa9488b908561542745f7e2a1f6061b63b181a;p=mdref%2Fmdref diff --git a/mdref/Action.php b/mdref/Action.php index 18f6069..37b3d51 100644 --- a/mdref/Action.php +++ b/mdref/Action.php @@ -5,52 +5,136 @@ namespace mdref; use http\Controller\Observer; /** - * The sole action controller of mdref + * Request handler */ -class Action extends Observer -{ - private function serveReference(\http\Controller $ctl) { - $payload = $ctl->getPayload(); - $finder = new Finder($this->baseUrl, REFS); - $path = $finder->find(new \http\Url($ctl->getRequest()->getRequestUrl())); - $payload->listing = new RefListing($path, - $finder->glob($path, "/[_a-zA-Z]*.md")); - $payload->title = $payload->listing->getSelf()->formatLink(); - $payload->refs = $finder; - if ($path->isFile()) { - $payload->html = new Markdown($path); - $payload->sublisting = new RefListing($path, - $finder->glob($path, "/[_a-z]*.md")); - return true; +class Action extends Observer { + /** + * Reference paths + * @var string + */ + protected $refpath; + + /** + * The reference + * @var \mdref\Reference + */ + private $reference; + + /** + * Initialize the reference + */ + protected function init() { + $this->reference = new Reference(explode(PATH_SEPARATOR, $this->refpath)); + } + + /** + * Create the view payload + * @param \http\Controller $ctl + * @return \stdClass + */ + private function createPayload(\http\Controller $ctl) { + $pld = new \stdClass; + + try { + $pld->quick = [$this->reference, "formatString"]; + $pld->file = [$this->reference, "formatFile"]; + + $pld->ref = implode("/", $this->baseUrl->params( + $this->baseUrl->mod($ctl->getRequest()->getRequestUrl()))); + + $pld->refs = $this->reference; + $pld->baseUrl = $this->baseUrl; + + } catch (\Exception $e) { + $pld->exception = $e; } + + return $pld; + } + + /** + * Redirect to canononical url + * @param \http\Controller $ctl + * @param string $cnn + */ + private function serveCanonical($ctl, $cnn) { + $ctl->detachAll(Observer\View::class); + $ctl->getResponse()->setHeader("Location", $this->baseUrl->mod(["path" => $cnn])); + $ctl->getResponse()->setResponseCode(301); } - private function serveInternal(\http\Controller $ctl) { - $payload = $ctl->getPayload(); - $finder = new Finder($this->baseUrl, ROOT); - $url = new \http\Url($ctl->getRequest()->getRequestUrl()); - $path = $finder->find($url, ""); - if ($path->isFile("")) { - $payload->html = $path->toHtml(); - } else if (strcmp($url->path, $this->baseUrl->path)) { - throw new \http\Controller\Exception(404, "Could not find '$path'"); + /** + * Serve index.css + * @param \http\Controller $ctl + */ + private function serveStylesheet($ctl) { + $ctl->detachAll(Observer\View::class); + $ctl->getResponse()->setHeader("Content-Type", "text/css"); + $ctl->getResponse()->setBody(new \http\Message\Body(fopen(ROOT."/public/index.css", "r"))); + } + + /** + * Serve index.js + * @param \http\Controller $ctl + */ + private function serveJavascript($ctl) { + $ctl->detachAll(Observer\View::class); + $ctl->getResponse()->setHeader("Content-Type", "application/javascript"); + $ctl->getResponse()->setBody(new \http\Message\Body(fopen(ROOT."/public/index.js", "r"))); + } + + /** + * Serve a preset + * @param \http\Controller $ctl + * @param \stdClass $pld + * @throws \http\Controller\Exception + */ + private function servePreset($ctl, $pld) { + switch ($pld->ref) { + case "AUTHORS": + case "LICENSE": + case "VERSION": + $pld->text = file_get_contents(ROOT."/$pld->ref"); + break; + case "index.css": + $this->serveStylesheet($ctl); + break; + case "index.js": + $this->serveJavascript($ctl); + break; + default: + throw new \http\Controller\Exception(404, "$pld->ref not found"); } } - + /** - * Implements \SplObserver - * @param \SplSubject $ctl + * Implements Observer + * @param \SplSubject $ctl \http\Controller */ - function update(\SplSubject $ctl) { - /* @var \http\Controller $ctl */ - try { - $ctl->getPayload()->baseUrl = $this->baseUrl; - - if (!$this->serveReference($ctl)) { - $this->serveInternal($ctl); + public function update(\SplSubject $ctl) { + /* @var http\Controller $ctl */ + $pld = $this->createPayload($ctl); + $ctl[Observer\View::class] = function() use($pld) { + return $pld; + }; + + if (!isset($pld->ref) || !strlen($pld->ref)) { + /* front page */ + return; + } + + $cnn = null; + if (($repo = $this->reference->getRepoForEntry($pld->ref, $cnn))) { + if (strlen($cnn)) { + /* redirect */ + $this->serveCanonical($ctl, $cnn); + } else { + /* direct match */ + $pld->entry = $repo->getEntry($pld->ref); } - } catch (\Exception $e) { - $ctl->getPayload()->exception = $e; + } else { + $this->servePreset($ctl, $pld); } } -} + +} \ No newline at end of file