X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=mdref%2FAction.php;h=0c48dd6b403c448d5d6f9538b141e448aadc01d1;hb=a94ecb1009610a763dd74a7eebc4754b6643d832;hp=68f64a7edb8f41a4293af90ae4ce3d162187a68d;hpb=dc54ba07d9e53d8ca8d49c6132d3d4d2a194e669;p=mdref%2Fmdref diff --git a/mdref/Action.php b/mdref/Action.php index 68f64a7..0c48dd6 100644 --- a/mdref/Action.php +++ b/mdref/Action.php @@ -4,6 +4,12 @@ namespace mdref; use http\Env\Request; use http\Env\Response; +use http\Message\Body; +use stdClass; +use function file_get_contents; +use function htmlspecialchars; +use function ob_start; +use const ROOT; /** * Request handler @@ -16,137 +22,205 @@ class Action { private $reference; /** - * @var \http\Request + * @var \http\Env\Request */ private $request; /** - * @var \http\Response + * @var \http\Env\Response */ private $response; + /** + * @var resource + */ + private $output; + /** * @var \http\Url */ private $baseUrl; - + /** * Initialize the reference */ - public function __construct(Reference $ref, Request $req, Response $res, BaseUrl $baseUrl) { + public function __construct(Reference $ref, Request $req, Response $res, BaseUrl $baseUrl, $output = null) { $this->reference = $ref; $this->request = $req; $this->response = $res; $this->baseUrl = $baseUrl; + $this->output = $output; ob_start($res); } - function esc($txt) { + /** + * Shorthand for \htmlspecialchars() + * @param $txt string + * @return string + */ + function esc(string $txt) : string { return htmlspecialchars($txt); } - + /** * Create the view payload - * @param \http\Controller $ctl * @return \stdClass */ - private function createPayload() { - $pld = new \stdClass; - + private function createPayload() : object { + $pld = new stdClass; + $pld->esc = "htmlspecialchars"; + $pld->anchor = [$this->reference, "formatAnchor"]; $pld->quick = [$this->reference, "formatString"]; $pld->file = [$this->reference, "formatFile"]; $pld->ref = $this->baseUrl->pathinfo( $this->baseUrl->mod($this->request->getRequestUrl())); + $pld->markup = function($page) use($pld) { + return $this->reference->getFormatter()->markup($page, $pld); + }; + $pld->refs = $this->reference; $pld->baseUrl = $this->baseUrl; - + return $pld; } - + /** - * Redirect to canononical url + * Redirect to canonical url * @param string $cnn */ - private function serveCanonical($cnn) { + private function serveCanonical(string $cnn) : void { $this->response->setHeader("Location", $this->baseUrl->mod(["path" => $cnn])); $this->response->setResponseCode(301); - $this->response->send(); + if (is_resource($this->output)) { + $this->response->send($this->output); + } else { + $this->response->send(); + } } - + /** * Serve index.css */ - private function serveStylesheet() { + private function serveStylesheet() : void { $this->response->setHeader("Content-Type", "text/css"); - $this->response->setBody(new \http\Message\Body(fopen(ROOT."/public/index.css", "r"))); - $this->response->send(); + $this->response->setBody(new Body(\fopen(ROOT."/public/index.css", "r"))); + if (is_resource($this->output)) { + $this->response->send($this->output); + } else { + $this->response->send(); + } } - + /** * Serve index.js */ - private function serveJavascript() { + private function serveJavascript() : void { $this->response->setHeader("Content-Type", "application/javascript"); - $this->response->setBody(new \http\Message\Body(fopen(ROOT."/public/index.js", "r"))); - $this->response->send(); + $this->response->setBody(new Body(\fopen(ROOT."/public/index.js", "r"))); + if (is_resource($this->output)) { + $this->response->send($this->output); + } else { + $this->response->send(); + } } - + + /** + * Server a PHP stub + * @throws Exception + * + */ + private function serveStub() : void { + $name = $this->request->getQuery("ref", "s"); + $repo = $this->reference->getRepoForEntry($name); + if (!$repo->hasStub($stub)) { + throw new Exception(404, "Stub not found"); + } + $this->response->setHeader("Content-Type", "application/x-php"); + $this->response->setContentDisposition(["attachment" => ["filename" => "$name.stub.php"]]); + $this->response->setBody(new Body(\fopen($stub, "r"))); + if (is_resource($this->output)) { + $this->response->send($this->output); + } else { + $this->response->send(); + } + } + /** * Serve a preset - * @param \stdClass $pld + * @param object $pld + * @return true to continue serving the payload * @throws Exception */ - private function servePreset($pld) { + private function servePreset(object $pld) : bool { switch ($pld->ref) { case "AUTHORS": case "LICENSE": case "VERSION": $pld->text = file_get_contents(ROOT."/$pld->ref"); - break; + return true; case "index.css": - $this->serveStylesheet($ctl); + $this->serveStylesheet(); break; case "index.js": - $this->serveJavascript($ctl); + $this->serveJavascript(); + break; + case "stub": + $this->serveStub(); break; default: throw new Exception(404, "$pld->ref not found"); } + return false; } - private function serve() { + /** + * Serve a payload + */ + private function serve() : void { extract((array) func_get_arg(0)); include ROOT."/views/layout.phtml"; - $this->response->send(); + $this->response->addHeader("Link", "<" . $this->baseUrl->path . "index.css>; rel=preload; as=style"); + $this->response->addHeader("Link", "<" . $this->baseUrl->path . "index.js>; rel=preload; as=script"); + if (isset($exception) && $exception->getCode()) { + $this->response->setResponseCode($exception->getCode()); + } + if (is_resource($this->output)) { + $this->response->send($this->output); + } else { + $this->response->send(); + } } - - public function handle() { - try { + /** + * Request handler + */ + public function handle() : void { + try { $pld = $this->createPayload(); - if (strlen($pld->ref)) { + if (isset($pld->ref) && strlen($pld->ref)) { $cnn = null; if (($repo = $this->reference->getRepoForEntry($pld->ref, $cnn))) { - if (strlen($cnn)) { + if (isset($cnn) && strlen($cnn)) { /* redirect */ - return $this->serveCanonical($cnn); + $this->serveCanonical($cnn); + return; } else { /* direct match */ $pld->entry = $repo->getEntry($pld->ref); } - } else { - return $this->servePreset($pld); + } elseif (!$this->servePreset($pld)) { + return; } } - + } catch (\Exception $e) { $pld->exception = $e; } $this->serve($pld); } -} \ No newline at end of file +}