Passed
Push — main ( 7d5b4b...15f1b6 )
by Sammy
18:04 queued 11:18
created

Hopper.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
* huppel konijntje huppel and wiebel
5
* Hommage to Grace Hopper, programmer & expert in *litteral* duck taping
6
***/
7
8
namespace HexMakina\Hopper;
9
10
class Hopper extends \AltoRouter implements \HexMakina\BlackBox\RouterInterface
11
{
12
    private Request $request;
13
    private Response $response;
14
15
    private $file_root = null;
16
17
    public function __construct($route_home, $web_base, $file_root)
18
    {
19
      $this->mapHomeRoute($route_home);
20
      $this->basePath($web_base);
21
      $this->filePath($file_root);
22
    }
23
24
  //----------------------------------------------------------- INITIALISATION
25
26
    public function mapHomeRoute($route)
27
    {
28
        $this->map(self::REQUEST_GET, '', $route, self::ROUTE_HOME_NAME);
29
    }
30
31
    public function __debugInfo(): array
32
    {
33
        $dbg = get_object_vars($this);
34
        $dbg['routes'] = count($dbg['routes']);
35
        $dbg['namedRoutes'] = count($dbg['namedRoutes']);
36
        unset($dbg['matchTypes']);
37
        return $dbg;
38
    }
39
40
    // -- MATCHING REQUESTS
41
    public function match($requestUrl = null, $requestMethod = null)
42
    {
43
        $match = parent::match($requestUrl, $requestMethod);
44
45
        if ($match === false) {
46
            throw new RouterException('ROUTE_MATCH_FALSE');
47
        }
48
49
        $this->request = new Request($match);
50
        $this->response = new Response($this->request);
51
52
        return [$this->response->controller(), $this->response->method()];
53
    }
54
55
    // DEPRECATE
56
    public function params($param_name = null)
57
    {
58
        return $this->request->params($param_name);
59
    }
60
61
    // DEPRECATE
62
    public function submitted($param_name = null)
63
    {
64
        return $this->request->submitted($param_name);
65
    }
66
67
    // DEPRECATE
68
    public function name()
69
    {
70
        return $this->request->name();
71
    }
72
73
    // DEPRECATE
74
    public function target()
75
    {
76
        return $this->match['target'];
0 ignored issues
show
The property match does not exist on HexMakina\Hopper\Hopper. Did you mean matchTypes?
Loading history...
77
    }
78
79
    // DEPRECATE
80
    public function targetController()
81
    {
82
        return $this->response->controller();
83
    }
84
85
    // DEPRECATE
86
    public function targetMethod()
87
    {
88
        return $this->response->method();
89
    }
90
91
  // -- ROUTING TOOLS
92
    public function routeExists($route): bool
93
    {
94
        return isset($this->namedRoutes[$route]);
95
    }
96
97
    public function namedRoutes()
98
    {
99
        return $this->namedRoutes;
100
    }
101
102
  /* Generates HYPertext reference
103
   * @param route_name string  requires
104
   *  - a valid AltoRouter route name
105
   *  - OR a Descendant of Model
106
   * @route_params requires
107
   *  - an assoc_array of url params (strongly AltoRouter-based)
108
   * returns: something to put in a href="", action="" or header('Location:');
109
   */
110
    public function hyp($route, $route_params = [])
111
    {
112
        try {
113
            $url = $this->generate($route, $route_params);
114
        } catch (\Exception $e) {
115
            $url = $this->hyp(self::ROUTE_HOME_NAME);
116
        }
117
118
        return $url;
119
    }
120
121
  /*
122
   * @params $route is
123
   *    - empty: default is ROUTE_HOME_NAME
124
   *    - an existing route name: make url with optional [$route_params])
125
   *    - a url, go there
126
   * @params $route_params, assoc_data for url creation (i:id, a:format, ..)
127
   */
128
    public function hop($route = null, $route_params = [])
129
    {
130
        $url = null;
131
132
        if (is_null($route)) {
133
            $url = $this->hyp(self::ROUTE_HOME_NAME, $route_params);
134
        } elseif (is_string($route) && $this->routeExists($route)) {
135
            $url = $this->hyp($route, $route_params);
136
        } else {
137
            $url = $route;
138
        }
139
140
        $this->hopURL($url);
141
    }
142
143
    public function stay($url = null)
144
    {
145
        return $url ?? $_SERVER['REQUEST_URI'];
146
    }
147
148
  // hops back to previous page (referer()), or home if no referer
149
    public function hopBack()
150
    {
151
        if (!is_null($back = $this->referer())) {
152
            $this->hopURL($back);
153
        }
154
155
        $this->hop();
156
    }
157
158
    public function hopURL($url)
159
    {
160
        header('Cache-Control: no-cache, must-revalidate');
161
        header('Expires: Mon, 01 Jan 1970 00:00:00 GMT');
162
        header('Location: ' . $url);
163
        exit();
164
    }
165
166
  // returns full URL of the refering URL
167
  // returns null if same as current URL (prevents endless redirection loop)
168
    public function referer()
169
    {
170
        if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != $this->webHost() . $_SERVER['REQUEST_URI']) {
171
            return $_SERVER['HTTP_REFERER'];
172
        }
173
174
        return null;
175
    }
176
177
    public function sendFile($file_path)
178
    {
179
        if (!file_exists($file_path)) {
180
            throw new RouterException('SENDING_NON_EXISTING_FILE');
181
        }
182
183
        $file_name = basename($file_path);
184
185
      //Get file type and set it as Content Type
186
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
187
188
        header('Content-Type: ' . finfo_file($finfo, $file_path));
189
190
        finfo_close($finfo);
191
192
      //Use Content-Disposition: attachment to specify the filename
193
        header('Content-Disposition: attachment; filename=' . $file_name);
194
195
      //No cache
196
        header('Expires: 0');
197
        header('Cache-Control: must-revalidate');
198
        header('Pragma: public');
199
200
      //Define file size
201
        header('Content-Length: ' . filesize($file_path));
202
203
        ob_clean();
204
        flush();
205
        readfile($file_path);
206
        // die; // might be useless after all
207
    }
208
209
  // -- PROCESSING REQUESTS
210
    public function requests(): bool
211
    {
212
        return $_SERVER['REQUEST_METHOD'] === self::REQUEST_GET;
213
    }
214
215
    public function submits(): bool
216
    {
217
        return $_SERVER['REQUEST_METHOD'] === self::REQUEST_POST;
218
    }
219
220
    public function webHost(): string
221
    {
222
        return $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
223
    }
224
225
    public function webRoot(): string
226
    {
227
        return $this->webHost() . $this->basePath();
228
    }
229
230
    // return web base
231
    public function basePath($setter = null): string
232
    {
233
        if (!is_null($setter)) {
234
            $this->basePath = $setter;
235
        }
236
237
        return $this->basePath ?? '';
238
    }
239
240
    // returns root filepath for project
241
    // default out of vendor/hexmakina/Hopper
242
    public function filePath($setter = null): string
243
    {
244
        if (!is_null($setter)) {
245
            $this->file_root = realpath($setter) . '/';
246
        }
247
248
        return $this->file_root ?? __DIR__ . '/../../';
249
    }
250
251
252
253
}
254