"name": "m6w6/mdref",
"description": "Quick Markdown Reference Browser",
"license": "BSD-2-Clause",
- "require": {
- "m6w6/autocracy": "dev-master"
- }
}
namespace mdref;
-use http\Controller\Observer;
+use http\Env\Request;
+use http\Env\Response;
/**
* Request handler
*/
-class Action extends Observer {
- /**
- * Reference paths
- * @var string
- */
- protected $refpath;
-
+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
*/
- protected function init() {
- $this->reference = new Reference(explode(PATH_SEPARATOR, $this->refpath));
+ public function __construct(Reference $ref, Request $req, Response $res, BaseUrl $baseUrl) {
+ $this->reference = $ref;
+ $this->request = $req;
+ $this->response = $res;
+ $this->baseUrl = $baseUrl;
+ }
+
+ function esc($txt) {
+ return htmlspecialchars($txt);
}
/**
* @param \http\Controller $ctl
* @return \stdClass
*/
- private function createPayload(\http\Controller $ctl) {
+ private function createPayload() {
$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;
+ $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;
- } 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 serveCanonical($cnn) {
+ $this->response->setHeader("Location", $this->baseUrl->mod(["path" => $cnn]));
+ $this->response->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")));
+ private function serveStylesheet() {
+ $this->response->setHeader("Content-Type", "text/css");
+ $this->esponse->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")));
+ private function serveJavascript() {
+ $this->response->setHeader("Content-Type", "application/javascript");
+ $this->response->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
+ * @throws Exception
*/
- private function servePreset($ctl, $pld) {
+ private function servePreset($pld) {
switch ($pld->ref) {
case "AUTHORS":
case "LICENSE":
$this->serveJavascript($ctl);
break;
default:
- throw new \http\Controller\Exception(404, "$pld->ref not found");
+ throw new Exception(404, "$pld->ref not found");
}
}
+
+ private function serve() {
+ extract((array) func_get_arg(0));
+ include ROOT."/views/layout.phtml";
+ }
- /**
- * 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);
+ public function handle() {
+ try {
+
+ $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);
+ }
+ } else {
+ return $this->servePreset($pld);
+ }
}
- } else {
- $this->servePreset($ctl, $pld);
+
+ } catch (\Exception $e) {
+ $pld->exception = $e;
}
- }
+ $this->serve($pld);
+ }
}
\ No newline at end of file
--- /dev/null
+<?php
+
+namespace mdref;
+
+use http\Url;
+
+class BaseUrl extends Url {
+ /**
+ * Create base URL
+ * @param mixed $url
+ */
+ function __construct($url = null) {
+ $self = array(
+ "scheme" => filter_input(INPUT_SERVER, "HTTPS", FILTER_VALIDATE_BOOLEAN) ? "https":"http",
+ "path" => dirname(filter_input(INPUT_SERVER, "SCRIPT_NAME"))."/"
+ );
+ parent::__construct($self, $url,
+ self::JOIN_PATH |
+ self::SANITIZE_PATH |
+ self::STRIP_QUERY |
+ self::STRIP_AUTH |
+ self::FROM_ENV
+ );
+ }
+ /**
+ * Extract path info
+ *
+ * @param mixed $url full request url
+ * @return string
+ */
+ function pathinfo($url) {
+ $url = new Url($this, $url, Url::FROM_ENV | Url::STRIP_QUERY);
+ $info = substr($url, strlen($this));
+ return urldecode($info);
+ }
+
+
+}
* @return \mdref\Entry
*/
public function getParent() {
- if ("." !== ($dirn = dirname($this->name))) {
+ switch ($dirn = dirname($this->name)) {
+ case ".":
+ case "/":
+ break;
+ default:
return $this->repo->getEntry($dirn);
}
}
--- /dev/null
+<?php
+
+namespace mdref;
+
+use http\Response;
+
+class Exception extends \Exception
+{
+ function __construct($code, $message) {
+ parent::__construct($message, $code);
+ }
+
+ function send(Response $res) {
+ $res->setResponseCode($this->code);
+ $res->setBody(new http\Message\Body);
+ $res->getBody()->append($this->message);
+ }
+}
* @return string
*/
public static function htmlException(\Exception $e, array $title_tag = ["h1"], array $message_tag = ["p"], array $trace_tag = ["pre", "style='font-size:smaller;overflow-x:scroll'"]) {
- if ($e instanceof \http\Controller\Exception) {
+ if ($e instanceof Exception) {
$code = $e->getCode() ?: 500;
foreach ($e->getHeaders() as $key => $val) {
HTTP::setResponseHeader($key, $val);
if (-1 !== (j = s.lastIndexOf("\\")) && s.substr(j+1,1) !== "n") {
t = s.substring(j+1);
if (!mdref.is_constant(t)) {
- return "<a href=\"" + s.replace(/\\/g, "/").replace(/::|$/, "#") + "\">";
+ return "<a href=\"" + s.replace(/\\/g, "/").replace(/::/, "#") + "\">";
}
return "<a href=\"" + s.substring(0,j).replace(/\\/g, "/") + "#" + t + "\">";
}
$n.text().split(/([^a-zA-Z0-9_\\\$:]+)/).forEach(function(v) {
var t;
- if ((t = mdref.type(v, nn))) {
+ if ((t = mdref.type(v.replace(/:$/, ""), nn))) {
a.push($(t).text(v));
} else if (a.length && a[a.length-1].nodeName === "#text") {
/* if we already have a text node and the next is also gonna be a text
<?php
+use mdref\Action;
+use mdref\BaseUrl;
+use mdref\Reference;
+use mdref\ExceptionHandler;
+
+use http\Env\Request;
+use http\Env\Response;
+
define("ROOT", dirname(__DIR__));
-define("REFS", getenv("REFPATH") ?: implode(PATH_SEPARATOR, glob(ROOT."/refs/*")));
#ini_set("open_basedir", ROOT.":".REFS);
/* @var $loader \Composer\Autoload\ClassLoader */
$loader->add("mdref", ROOT);
-use http\Controller;
-use http\Controller\Url;
-use http\Controller\Observer\Layout;
-
-use mdref\ExceptionHandler;
-use mdref\Action;
-
new ExceptionHandler;
-$ctl = new Controller;
-$ctl->setDependency("baseUrl", new Url)
- ->attach(new Action(["refpath" => REFS]))
- ->attach(new Layout)
- ->notify()
- ->getResponse()
- ->send();
+$reference = new Reference(($refs = getenv("REFPATH")) ? explode(PATH_SEPARATOR, $refs) : glob(ROOT."/refs/*"));
+$action = new Action($reference, new Request, new Response, new BaseUrl);
+
+ob_start($response);
+$action->handle();
+ob_end_flush();
+$response->send();
<?php if (isset($html)) : ?>
<?= $html ?>
<?php elseif (isset($text)) : ?>
- <p style="white-space:pre-wrap"><?= $view->esc($text) ?></p>
+ <p style="white-space:pre-wrap"><?= $esc($text) ?></p>
<?php elseif (isset($refs)) : ?>
<?php foreach ($refs as $repo) : /* @var \mdref\Repo $repo */ ?>
<?php foreach ($repo as $entry) : /* @var \mdref\Entry $entry */ ?>
<h2>
- <a href="<?= $view->esc($entry->getName()) ?>"
- ><?= $view->esc($entry->getTitle()) ?></a></h2>
+ <a href="<?= $esc($entry->getName()) ?>"
+ ><?= $esc($entry->getTitle()) ?></a></h2>
<div><?= $quick($entry->getIntro()) ?></div>
<?php endforeach; ?>
<?php endforeach; ?>
<ul>
<?php foreach($entry as $sub) : if (!$sub->isFunction()) continue; ?>
<li>
- <h3><a href="<?= $view->esc($sub->getName()) ?>"><?= $view->esc($sub) ?></a></h3>
+ <h3><a href="<?= $esc($sub->getName()) ?>"><?= $esc($sub) ?></a></h3>
<p><?= $quick($sub->getDescription()) ?></p>
- <p><?= $view->esc($sub->getTitle()) ?></p>
+ <p><?= $esc($sub->getTitle()) ?></p>
</li>
<?php endforeach; ?>
</ul>
<ul>
<?php foreach ($entry as $sub) : if (!$sub->isNsClass()) continue; ?>
<li>
- <h3><a href="<?= $view->esc($sub->getName()) ?>"><?= $view->esc($sub) ?></a></h3>
+ <h3><a href="<?= $esc($sub->getName()) ?>"><?= $esc($sub) ?></a></h3>
<p><?= $quick($sub->getDescription()) ?></p>
- <p><?= $view->esc($sub->getTitle()) ?></p>
+ <p><?= $esc($sub->getTitle()) ?></p>
</li>
<?php endforeach; ?>
</ul>
<div class="sidebar">
<?php
if (isset($baseUrl) || !isset($entry)) {
- $up = "";
+ $up = "./";
} else {
$up = str_repeat("../", count($entry->getParents()));
}
<li>
<?php foreach ($entry->getParents() as $parent) if ($parent->isFile()) : ?>
↑
- <a href="<?= $up.$view->esc($parent->getName()) ?>">
- <?= $view->esc($entry->getRepo()->getEntry($parent)) ?>
+ <a href="<?= $up.$esc($parent->getName()) ?>">
+ <?= $esc($entry->getRepo()->getEntry($parent)) ?>
</a>
<ul>
<li>
<?php endif; ?>
- ↻ <a href="<?= $up.$view->esc($entry->getName()) ?>"
- ><?= $view->esc($entry) ?></a>
+ ↻ <a href="<?= $up.$esc($entry->getName()) ?>"
+ ><?= $esc($entry) ?></a>
<ul>
<?php foreach ($entry as $sub) : /* @var \mdref\Entry $sub */ ?>
<li>
- ↳ <a href="<?= $up.$view->esc($sub->getName()) ?>"
- ><?= $view->esc($sub) ?></a>
+ ↳ <a href="<?= $up.$esc($sub->getName()) ?>"
+ ><?= $esc($sub) ?></a>
</li>
<?php endforeach; ?>
</ul>
<?php foreach ($refs as $repo) : /* @var \mdref\Repo $repo */ ?>
<?php foreach ($repo as $sub) : /* @var \mdref\Entry $entry */ ?>
<li>
- ↳ <a href="<?= $view->esc($sub->getName()) ?>"
- ><?= $view->esc($sub->getTitle()) ?></a>
+ ↳ <a href="<?= $esc($sub->getName()) ?>"
+ ><?= $esc($sub->getTitle()) ?></a>
</li>
<?php endforeach; ?>
<?php endforeach; ?>