19cf9106f363c9edb6e89e1b83a9cd6fa6aa5ac0
[mdref/mdref] / mdref / Action.php
1 <?php
2
3 namespace mdref;
4
5 use http\Env\Request;
6 use http\Env\Response;
7
8 /**
9 * Request handler
10 */
11 class Action {
12 /**
13 * The reference
14 * @var \mdref\Reference
15 */
16 private $reference;
17
18 /**
19 * @var \http\Request
20 */
21 private $request;
22
23 /**
24 * @var \http\Response
25 */
26 private $response;
27
28 /**
29 * @var \http\Url
30 */
31 private $baseUrl;
32
33 /**
34 * Initialize the reference
35 */
36 public function __construct(Reference $ref, Request $req, Response $res, BaseUrl $baseUrl) {
37 $this->reference = $ref;
38 $this->request = $req;
39 $this->response = $res;
40 $this->baseUrl = $baseUrl;
41 ob_start($res);
42 }
43
44 function esc($txt) {
45 return htmlspecialchars($txt);
46 }
47
48 /**
49 * Create the view payload
50 * @param \http\Controller $ctl
51 * @return \stdClass
52 */
53 private function createPayload() {
54 $pld = new \stdClass;
55
56 $pld->esc = "htmlspecialchars";
57 $pld->quick = [$this->reference, "formatString"];
58 $pld->file = [$this->reference, "formatFile"];
59
60 $pld->ref = $this->baseUrl->pathinfo(
61 $this->baseUrl->mod($this->request->getRequestUrl()));
62
63 $pld->refs = $this->reference;
64 $pld->baseUrl = $this->baseUrl;
65
66 return $pld;
67 }
68
69 /**
70 * Redirect to canononical url
71 * @param string $cnn
72 */
73 private function serveCanonical($cnn) {
74 $this->response->setHeader("Location", $this->baseUrl->mod(["path" => $cnn]));
75 $this->response->setResponseCode(301);
76 $this->response->send();
77 }
78
79 /**
80 * Serve index.css
81 */
82 private function serveStylesheet() {
83 $this->response->setHeader("Content-Type", "text/css");
84 $this->response->setBody(new \http\Message\Body(fopen(ROOT."/public/index.css", "r")));
85 $this->response->send();
86 }
87
88 /**
89 * Serve index.js
90 */
91 private function serveJavascript() {
92 $this->response->setHeader("Content-Type", "application/javascript");
93 $this->response->setBody(new \http\Message\Body(fopen(ROOT."/public/index.js", "r")));
94 $this->response->send();
95 }
96
97 /**
98 * Serve a preset
99 * @param \stdClass $pld
100 * @return true to continue serving the payload
101 * @throws Exception
102 */
103 private function servePreset($pld) {
104 switch ($pld->ref) {
105 case "AUTHORS":
106 case "LICENSE":
107 case "VERSION":
108 $pld->text = file_get_contents(ROOT."/$pld->ref");
109 return true;
110 case "index.css":
111 $this->serveStylesheet();
112 break;
113 case "index.js":
114 $this->serveJavascript();
115 break;
116 default:
117 throw new Exception(404, "$pld->ref not found");
118 }
119 return false;
120 }
121
122 private function serve() {
123 extract((array) func_get_arg(0));
124 include ROOT."/views/layout.phtml";
125 $this->response->send();
126 }
127
128 public function handle() {
129 try {
130
131 $pld = $this->createPayload();
132
133 if (strlen($pld->ref)) {
134 $cnn = null;
135 if (($repo = $this->reference->getRepoForEntry($pld->ref, $cnn))) {
136 if (strlen($cnn)) {
137 /* redirect */
138 return $this->serveCanonical($cnn);
139 } else {
140 /* direct match */
141 $pld->entry = $repo->getEntry($pld->ref);
142 }
143 } elseif (!$this->servePreset($pld)) {
144 return;
145 }
146 }
147
148 } catch (\Exception $e) {
149 $pld->exception = $e;
150 }
151
152 $this->serve($pld);
153 }
154 }