static generation does not work with overlapping namespaces
[mdref/mdref] / mdref / Action.php
1 <?php
2
3 namespace mdref;
4
5 use http\Controller\Observer;
6
7 /**
8 * Request handler
9 */
10 class Action extends Observer {
11 /**
12 * Reference paths
13 * @var string
14 */
15 protected $refpath;
16
17 /**
18 * The reference
19 * @var \mdref\Reference
20 */
21 private $reference;
22
23 /**
24 * Initialize the reference
25 */
26 protected function init() {
27 $this->reference = new Reference(explode(PATH_SEPARATOR, $this->refpath));
28 }
29
30 /**
31 * Create the view payload
32 * @param \http\Controller $ctl
33 * @return \stdClass
34 */
35 private function createPayload(\http\Controller $ctl) {
36 $pld = new \stdClass;
37
38 try {
39 $pld->quick = [$this->reference, "formatString"];
40 $pld->file = [$this->reference, "formatFile"];
41
42 $pld->ref = implode("/", $this->baseUrl->params(
43 $this->baseUrl->mod($ctl->getRequest()->getRequestUrl())));
44
45 $pld->refs = $this->reference;
46 $pld->baseUrl = $this->baseUrl;
47
48 } catch (\Exception $e) {
49 $pld->exception = $e;
50 }
51
52 return $pld;
53 }
54
55 /**
56 * Redirect to canononical url
57 * @param \http\Controller $ctl
58 * @param string $cnn
59 */
60 private function serveCanonical($ctl, $cnn) {
61 $ctl->detachAll(Observer\View::class);
62 $ctl->getResponse()->setHeader("Location", $this->baseUrl->mod(["path" => $cnn]));
63 $ctl->getResponse()->setResponseCode(301);
64 }
65
66 /**
67 * Serve index.css
68 * @param \http\Controller $ctl
69 */
70 private function serveStylesheet($ctl) {
71 $ctl->detachAll(Observer\View::class);
72 $ctl->getResponse()->setHeader("Content-Type", "text/css");
73 $ctl->getResponse()->setBody(new \http\Message\Body(fopen(ROOT."/public/index.css", "r")));
74 }
75
76 /**
77 * Serve index.js
78 * @param \http\Controller $ctl
79 */
80 private function serveJavascript($ctl) {
81 $ctl->detachAll(Observer\View::class);
82 $ctl->getResponse()->setHeader("Content-Type", "application/javascript");
83 $ctl->getResponse()->setBody(new \http\Message\Body(fopen(ROOT."/public/index.js", "r")));
84 }
85
86 /**
87 * Serve a preset
88 * @param \http\Controller $ctl
89 * @param \stdClass $pld
90 * @throws \http\Controller\Exception
91 */
92 private function servePreset($ctl, $pld) {
93 switch ($pld->ref) {
94 case "AUTHORS":
95 case "LICENSE":
96 case "VERSION":
97 $pld->text = file_get_contents(ROOT."/$pld->ref");
98 break;
99 case "index.css":
100 $this->serveStylesheet($ctl);
101 break;
102 case "index.js":
103 $this->serveJavascript($ctl);
104 break;
105 default:
106 throw new \http\Controller\Exception(404, "$pld->ref not found");
107 }
108 }
109
110 /**
111 * Implements Observer
112 * @param \SplSubject $ctl \http\Controller
113 */
114 public function update(\SplSubject $ctl) {
115 /* @var http\Controller $ctl */
116 $pld = $this->createPayload($ctl);
117 $ctl[Observer\View::class] = function() use($pld) {
118 return $pld;
119 };
120
121 if (!isset($pld->ref) || !strlen($pld->ref)) {
122 /* front page */
123 return;
124 }
125
126 $cnn = null;
127 if (($repo = $this->reference->getRepoForEntry($pld->ref, $cnn))) {
128 if (strlen($cnn)) {
129 /* redirect */
130 $this->serveCanonical($ctl, $cnn);
131 } else {
132 /* direct match */
133 $pld->entry = $repo->getEntry($pld->ref);
134 }
135 } else {
136 $this->servePreset($ctl, $pld);
137 }
138 }
139
140 }