Passed
Push — main ( 5b7f53...c506ee )
by Sammy
01:28
created

Hopper::url()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 3
rs 10
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
    // DEPRECATE
73
    // public function target()
74
    // {
75
    //     return $this->match['target'];
76
    // }
77
78
    // DEPRECATE
79
    public function targetController()
80
    {
81
        return $this->target->controller();
82
    }
83
84
    // DEPRECATE
85
    public function targetMethod()
86
    {
87
        return $this->target->method();
88
    }
89
90
  // -- ROUTING TOOLS
91
    public function routeExists($route): bool
92
    {
93
        return isset($this->namedRoutes[$route]);
94
    }
95
96
    public function namedRoutes()
97
    {
98
        return $this->namedRoutes;
99
    }
100
101
  /* Generates HYPertext reference
102
   * @param route_name string  requires
103
   *  - a valid AltoRouter route name
104
   *  - OR a Descendant of Model
105
   * @route_params requires
106
   *  - an assoc_array of url params (strongly AltoRouter-based)
107
   * returns: something to put in a href="", action="" or header('Location:');
108
   */
109
    public function hyp($route, $route_params = [])
110
    {
111
        try {
112
            $url = $this->generate($route, $route_params);
113
        } catch (\Exception $e) {
114
            $url = $this->hyp(self::ROUTE_HOME_NAME);
115
        }
116
117
        return $url;
118
    }
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 url(): string
144
    {
145
        return $this->webHost() . $_SERVER['REQUEST_URI'];
146
    }
147
148
    public function stay($url = null)
149
    {
150
        return $url ?? $_SERVER['REQUEST_URI'];
151
    }
152
153
  // hops back to previous page (referer()), or home if no referer
154
    public function hopBack()
155
    {
156
        if (!is_null($back = $this->referer())) {
157
            $this->hopURL($back);
158
        }
159
160
        $this->hop();
161
    }
162
163
    public function hopURL($url)
164
    {
165
        header('Cache-Control: no-cache, must-revalidate');
166
        header('Expires: Mon, 01 Jan 1970 00:00:00 GMT');
167
        header('Location: ' . $url);
168
        exit();
169
    }
170
171
  // returns full URL of the refering URL
172
  // returns null if same as current URL (prevents endless redirection loop)
173
    public function referer(): ?string
174
    {
175
        if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != $this->webHost() . $_SERVER['REQUEST_URI']) {
176
            return $_SERVER['HTTP_REFERER'];
177
        }
178
179
        return null;
180
    }
181
182
    public function sendFile($file_path)
183
    {
184
        if (!file_exists($file_path)) {
185
            throw new RouterException('SENDING_NON_EXISTING_FILE');
186
        }
187
188
        $file_name = basename($file_path);
189
190
      //Get file type and set it as Content Type
191
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
192
193
        header('Content-Type: ' . finfo_file($finfo, $file_path));
194
195
        finfo_close($finfo);
196
197
      //Use Content-Disposition: attachment to specify the filename
198
        header('Content-Disposition: attachment; filename=' . $file_name);
199
200
      //No cache
201
        header('Expires: 0');
202
        header('Cache-Control: must-revalidate');
203
        header('Pragma: public');
204
205
      //Define file size
206
        header('Content-Length: ' . filesize($file_path));
207
208
        ob_clean();
209
        flush();
210
        readfile($file_path);
211
        // die; // might be useless after all
212
    }
213
214
  // -- PROCESSING REQUESTS
215
    public function requests(): bool
216
    {
217
        return $_SERVER['REQUEST_METHOD'] === self::REQUEST_GET;
218
    }
219
220
    public function submits(): bool
221
    {
222
        return $_SERVER['REQUEST_METHOD'] === self::REQUEST_POST;
223
    }
224
225
    public function webHost(): string
226
    {
227
        return $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
228
    }
229
230
    public function webRoot(): string
231
    {
232
        return $this->webHost() . $this->basePath();
233
    }
234
235
    // return web base
236
    public function basePath($setter = null): string
237
    {
238
        if (!is_null($setter)) {
239
            $this->basePath = $setter;
240
        }
241
242
        return $this->basePath ?? '';
243
    }
244
245
    // returns root filepath for project
246
    // default out of vendor/hexmakina/Hopper
247
    public function filePath($setter = null): string
248
    {
249
        if (!is_null($setter)) {
250
            $this->file_root = realpath($setter) . '/';
251
        }
252
253
        return $this->file_root ?? __DIR__ . '/../../';
254
    }
255
256
257
258
}
259