fix serving presets
[mdref/mdref] / mdref / Action.php
index 511e3a6c8f412d21210f780b2e9b4ab68f494939..19cf9106f363c9edb6e89e1b83a9cd6fa6aa5ac0 100644 (file)
 
 namespace mdref;
 
-use http\Controller\Observer;
-
-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;
-               }
+use http\Env\Request;
+use http\Env\Response;
+
+/**
+ * Request handler
+ */
+class Action {
+       /**
+        * The reference
+        * @var \mdref\Reference
+        */
+       private $reference;
+
+       /**
+        * @var \http\Request
+        */
+       private $request;
+
+       /**
+        * @var \http\Response
+        */
+       private $response;
+
+       /**
+        * @var \http\Url
+        */
+       private $baseUrl;
+       
+       /**
+        * Initialize the reference
+        */
+       public function __construct(Reference $ref, Request $req, Response $res, BaseUrl $baseUrl) {
+               $this->reference = $ref;
+               $this->request = $req;
+               $this->response = $res;
+               $this->baseUrl = $baseUrl;
+               ob_start($res);
+       }
+
+       function esc($txt) {
+               return htmlspecialchars($txt);
+       }
+       
+       /**
+        * Create the view payload
+        * @param \http\Controller $ctl
+        * @return \stdClass
+        */
+       private function createPayload() {
+               $pld = new \stdClass;
+               
+               $pld->esc = "htmlspecialchars";
+               $pld->quick = [$this->reference, "formatString"];
+               $pld->file = [$this->reference, "formatFile"];
+
+               $pld->ref = $this->baseUrl->pathinfo(
+                       $this->baseUrl->mod($this->request->getRequestUrl()));
+
+               $pld->refs = $this->reference;
+               $pld->baseUrl = $this->baseUrl;
+                       
+               return $pld;
+       }
+       
+       /**
+        * Redirect to canononical url
+        * @param string $cnn
+        */
+       private function serveCanonical($cnn) {
+               $this->response->setHeader("Location", $this->baseUrl->mod(["path" => $cnn]));
+               $this->response->setResponseCode(301);
+               $this->response->send();
+       }
+       
+       /**
+        * Serve index.css
+        */
+       private function serveStylesheet() {
+               $this->response->setHeader("Content-Type", "text/css");
+               $this->response->setBody(new \http\Message\Body(fopen(ROOT."/public/index.css", "r")));
+               $this->response->send();
+       }
+       
+       /**
+        * Serve index.js
+        */
+       private function serveJavascript() {
+               $this->response->setHeader("Content-Type", "application/javascript");
+               $this->response->setBody(new \http\Message\Body(fopen(ROOT."/public/index.js", "r")));
+               $this->response->send();
        }
        
-       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, $this->baseUrl)) {
-                       throw new \http\Controller\Exception(404, "Could not find '$path'");
+       /**
+        * Serve a preset
+        * @param \stdClass $pld
+        * @return true to continue serving the payload
+        * @throws Exception
+        */
+       private function servePreset($pld) {
+               switch ($pld->ref) {
+               case "AUTHORS":
+               case "LICENSE":
+               case "VERSION":
+                       $pld->text = file_get_contents(ROOT."/$pld->ref");
+                       return true;
+               case "index.css":
+                       $this->serveStylesheet();
+                       break;
+               case "index.js":
+                       $this->serveJavascript();
+                       break;
+               default:
+                       throw new Exception(404, "$pld->ref not found");
                }
+               return false;
        }
 
-       function update(\SplSubject $ctl) {
-               /* @var \http\Controller $ctl */
+       private function serve() {
+               extract((array) func_get_arg(0));
+               include ROOT."/views/layout.phtml";
+               $this->response->send();
+       }
+       
+       public function handle() {
                try {
-                       $ctl->getPayload()->baseUrl = $this->baseUrl;
 
-                       if (!$this->serveReference($ctl)) {
-                               $this->serveInternal($ctl);
+                       $pld = $this->createPayload();
+
+                       if (strlen($pld->ref)) {
+                               $cnn = null;
+                               if (($repo = $this->reference->getRepoForEntry($pld->ref, $cnn))) {
+                                       if (strlen($cnn)) {
+                                               /* redirect */
+                                               return $this->serveCanonical($cnn);
+                                       } else {
+                                               /* direct match */
+                                               $pld->entry = $repo->getEntry($pld->ref);
+                                       }
+                               } elseif (!$this->servePreset($pld)) {
+                                       return;
+                               }
                        }
+               
                } catch (\Exception $e) {
-                       $ctl->getPayload()->exception = $e;
+                       $pld->exception = $e;
                }
+
+               $this->serve($pld);
        }
-}
+}
\ No newline at end of file