cli server fixes
[mdref/mdref] / mdref / Action.php
1 <?php
2
3 namespace mdref;
4
5 use http\Controller\Observer;
6
7 /**
8 * The sole action controller of mdref
9 */
10 class Action extends Observer
11 {
12 private function serveReference(\http\Url $url, \http\Controller\Payload $payload) {
13 $finder = new Finder($this->baseUrl, REFS);
14 $path = $finder->find($url);
15 $payload->listing = new RefListing($path,
16 $finder->glob($path, "/[_a-zA-Z]*.md"));
17 $payload->title = $payload->listing->getSelf()->formatLink();
18 $payload->refs = $finder;
19 if ($path->isFile()) {
20 $payload->html = new Markdown($path);
21 $payload->sublisting = new RefListing($path,
22 $finder->glob($path, "/[_a-z]*.md"));
23 return true;
24 }
25 }
26
27 private function serveInternal(\http\Url $url, \http\Controller\Payload $payload) {
28 $finder = new Finder($this->baseUrl, ROOT);
29 $path = $finder->find($url, "");
30 if ($path->isFile("")) {
31 $payload->html = $path->toHtml();
32 return true;
33 }
34 }
35
36 private function getType($file) {
37 static $inf = null;
38 static $typ = array(".css" => "text/css", ".js" => "applicatin/javascript");
39
40 $ext = strrchr($file, ".");
41 if (isset($typ[$ext])) {
42 return $typ[$ext];
43 }
44
45 if (!$inf) {
46 $inf = new \FINFO(FILEINFO_MIME_TYPE);
47 }
48 return $inf->file($file);
49 }
50
51 private function servePublic(\http\Url $url, \http\Env\Response $res) {
52 $finder = new Finder($this->baseUrl, ROOT."/public");
53 $path = $finder->find($url, "");
54 if ($path->isFile("")) {
55 $res->setHeader("Content-Type", $this->getType($path->getFullPath("")));
56 $res->setBody(new \http\Message\Body(fopen($path->getFullPath(""),"r")));
57 return true;
58 }
59 }
60
61 /**
62 * Implements \SplObserver
63 * @param \SplSubject $ctl
64 */
65 function update(\SplSubject $ctl) {
66 /* @var \http\Controller $ctl */
67 try {
68 $pld = $ctl->getPayload();
69 $pld->baseUrl = $this->baseUrl;
70 $url = $this->baseUrl->mod($ctl->getRequest()->getRequestUrl());
71
72 if ($this->serveReference($url, $pld) || $this->serveInternal($url, $pld)) {
73 return;
74 } elseif ($this->servePublic($url, $ctl->getResponse())) {
75 $ctl->detachAll("\\http\\Controller\\Observer\\View");
76 return;
77 }
78
79 /* fallthrough */
80 if (strcmp($url->path, $this->baseUrl->path)) {
81 throw new \http\Controller\Exception(404, "Could not find '$url'");
82 }
83 } catch (\Exception $e) {
84 $ctl->getPayload()->exception = $e;
85 }
86 }
87 }