static generation does not work with overlapping namespaces
[mdref/mdref] / mdref / Action.php
index 223e532ca00d934f5143c6c12a3b5e0784442065..37b3d51321ebab4400b8400420b621f91e07d5ec 100644 (file)
@@ -4,38 +4,137 @@ namespace mdref;
 
 use http\Controller\Observer;
 
-class Action extends Observer
-{
-       function update(\SplSubject $ctl) {
-               /* @var \http\Controller $ctl */
+/**
+ * Request handler
+ */
+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 {
-                       $payload = $ctl->getPayload();
-                       $request = $ctl->getRequest();
-
-                       $finder = new Finder($this->baseUrl, REFS);
-                       $url = new \http\Url($request->getRequestUrl());
-                       if (!$path = $finder->find($url)) {
-                               $path = new Path;
-                       }
-
-                       $payload->baseUrl = $this->baseUrl;
-                       $payload->requestUrl = $url;
-
-                       $payload->listing = new RefListing($path, 
-                                       $finder->glob($path, "/[_a-zA-Z]*.md"));
-
-                       if ($path->isFile()) {
-                               $payload->markdown = new Markdown($path);
-                               $payload->sublisting = new RefListing($path, 
-                                               $finder->glob($path, "/[_a-z]*.md"));
-                       } else if ($path($url)->isFile("")) {
-                               $payload->markdown = $path->toHtml();
-                       } else if (strcmp($url, $this->baseUrl)) {
-                               throw new \http\Controller\Exception(404, "Could not find '$url'");
-                       }
+                       $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) {
-                       $payload->baseUrl = $this->baseUrl;
-                       $ctl->getPayload()->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);
+       }
+       
+       /**
+        * 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 Observer
+        * @param \SplSubject $ctl \http\Controller
+        */
+       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);
+                       }
+               } else {
+                       $this->servePreset($ctl, $pld);
+               }
+       }
+
+}
\ No newline at end of file