Hopper   A
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 249
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 37
eloc 77
c 2
b 0
f 1
dl 0
loc 249
rs 9.44

26 Methods

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