ServiceProvider   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 385
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 83
dl 0
loc 385
rs 9.52
c 0
b 0
f 0
wmc 36

18 Methods

Rating   Name   Duplication   Size   Complexity  
A sharedData() 0 3 1
A yieldView() 0 3 1
A markdown() 0 27 4
A __isset() 0 3 1
A escape() 0 3 1
A back() 0 11 2
A __set() 0 3 1
A refresh() 0 7 1
A layout() 0 9 2
A __unset() 0 3 1
A flashes() 0 20 4
A render() 0 22 4
A bind() 0 7 3
A __construct() 0 7 1
A flash() 0 13 4
A __get() 0 3 1
A partial() 0 6 1
A startSession() 0 10 3
1
<?php
2
/**
3
 * Klein (klein.php) - A fast & flexible router for PHP
4
 *
5
 * @author      Chris O'Hara <[email protected]>
6
 * @author      Trevor Suarez (Rican7) (contributor and v2 refactorer)
7
 * @copyright   (c) Chris O'Hara
8
 * @link        https://github.com/klein/klein.php
9
 * @license     MIT
10
 */
11
12
namespace app\framework\Component\Routing;
13
14
use app\framework\Component\Routing\DataCollection\DataCollection;
15
16
/**
17
 * ServiceProvider
18
 *
19
 * Service provider class for handling logic extending between
20
 * a request's data and a response's behavior
21
 * @package app\framework\Component\Routing
22
 */
23
class ServiceProvider
24
{
25
26
    /**
27
     * Class properties
28
     */
29
30
    /**
31
     * The Request instance containing HTTP request data and behaviors
32
     *
33
     * @type Request
34
     */
35
    protected $request;
36
37
    /**
38
     * The Response instance containing HTTP response data and behaviors
39
     *
40
     * @type AbstractResponse
41
     */
42
    protected $response;
43
44
    /**
45
     * The id of the current PHP session
46
     *
47
     * @type string|boolean
48
     */
49
    protected $session_id;
50
51
    /**
52
     * The view layout
53
     *
54
     * @type string
55
     */
56
    protected $layout;
57
58
    /**
59
     * The view to render
60
     *
61
     * @type string
62
     */
63
    protected $view;
64
65
    /**
66
     * Shared data collection
67
     *
68
     * @type DataCollection
69
     */
70
    protected $shared_data;
71
72
73
    /**
74
     * Methods
75
     */
76
77
    /**
78
     * Constructor
79
     *
80
     * @param Request $request              Object containing all HTTP request data and behaviors
81
     * @param AbstractResponse $response    Object containing all HTTP response data and behaviors
82
     */
83
    public function __construct(Request $request = null, AbstractResponse $response = null)
84
    {
85
        // Bind our objects
86
        $this->bind($request, $response);
87
88
        // Instantiate our shared data collection
89
        $this->shared_data = new DataCollection();
90
    }
91
92
    /**
93
     * Bind object instances to this service
94
     *
95
     * @param Request $request              Object containing all HTTP request data and behaviors
96
     * @param AbstractResponse $response    Object containing all HTTP response data and behaviors
97
     * @return ServiceProvider
98
     */
99
    public function bind(Request $request = null, AbstractResponse $response = null)
100
    {
101
        // Keep references
102
        $this->request  = $request  ?: $this->request;
103
        $this->response = $response ?: $this->response;
104
105
        return $this;
106
    }
107
108
    /**
109
     * Returns the shared data collection object
110
     *
111
     * @return \app\framework\Component\Routing\DataCollection\DataCollection
112
     */
113
    public function sharedData()
114
    {
115
        return $this->shared_data;
116
    }
117
118
    /**
119
     * Get the current session's ID
120
     *
121
     * This will start a session if the current session id is null
122
     *
123
     * @return string|false
124
     */
125
    public function startSession()
126
    {
127
        if (session_id() === '') {
128
            // Attempt to start a session
129
            session_start();
130
131
            $this->session_id = session_id() ?: false;
132
        }
133
134
        return $this->session_id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->session_id also could return the type boolean which is incompatible with the documented return type false|string.
Loading history...
135
    }
136
137
    /**
138
     * Stores a flash message of $type
139
     *
140
     * @param string $msg       The message to flash
141
     * @param string $type      The flash message type
142
     * @param array $params     Optional params to be parsed by markdown
143
     * @return void
144
     */
145
    public function flash($msg, $type = 'info', $params = null)
146
    {
147
        $this->startSession();
148
        if (is_array($type)) {
0 ignored issues
show
introduced by
The condition is_array($type) is always false.
Loading history...
149
            $params = $type;
150
            $type = 'info';
151
        }
152
        if (!isset($_SESSION['__flashes'])) {
153
            $_SESSION['__flashes'] = array($type => array());
154
        } elseif (!isset($_SESSION['__flashes'][$type])) {
155
            $_SESSION['__flashes'][$type] = array();
156
        }
157
        $_SESSION['__flashes'][$type][] = $this->markdown($msg, $params);
158
    }
159
160
    /**
161
     * Returns and clears all flashes of optional $type
162
     *
163
     * @param string $type  The name of the flash message type
164
     * @return array
165
     */
166
    public function flashes($type = null)
167
    {
168
        $this->startSession();
169
170
        if (!isset($_SESSION['__flashes'])) {
171
            return array();
172
        }
173
174
        if (null === $type) {
175
            $flashes = $_SESSION['__flashes'];
176
            unset($_SESSION['__flashes']);
177
        } else {
178
            $flashes = array();
179
            if (isset($_SESSION['__flashes'][$type])) {
180
                $flashes = $_SESSION['__flashes'][$type];
181
                unset($_SESSION['__flashes'][$type]);
182
            }
183
        }
184
185
        return $flashes;
186
    }
187
188
    /**
189
     * Render a text string as markdown
190
     *
191
     * Supports basic markdown syntax
192
     *
193
     * Also, this method takes in EITHER an array of optional arguments (as the second parameter)
194
     * ... OR this method will simply take a variable number of arguments (after the initial str arg)
195
     *
196
     * @param string $str   The text string to parse
197
     * @param array $args   Optional arguments to be parsed by markdown
198
     * @return string
199
     */
200
    public static function markdown($str, $args = null)
201
    {
202
        // Create our markdown parse/conversion regex's
203
        $md = array(
204
            '/\[([^\]]++)\]\(([^\)]++)\)/' => '<a href="$2">$1</a>',
205
            '/\*\*([^\*]++)\*\*/'          => '<strong>$1</strong>',
206
            '/\*([^\*]++)\*/'              => '<em>$1</em>'
207
        );
208
209
        // Let's make our arguments more "magical"
210
        $args = func_get_args(); // Grab all of our passed args
211
        $str = array_shift($args); // Remove the initial arg from the array (and set the $str to it)
212
        if (isset($args[0]) && is_array($args[0])) {
213
            /**
214
             * If our "second" argument (now the first array item is an array)
215
             * just use the array as the arguments and forget the rest
216
             */
217
            $args = $args[0];
218
        }
219
220
        // Encode our args so we can insert them into an HTML string
221
        foreach ($args as &$arg) {
222
            $arg = htmlentities($arg, ENT_QUOTES, 'UTF-8');
223
        }
224
225
        // Actually do our markdown conversion
226
        return vsprintf(preg_replace(array_keys($md), $md, $str), $args);
227
    }
228
229
    /**
230
     * Escapes a string for UTF-8 HTML displaying
231
     *
232
     * This is a quick macro for escaping strings designed
233
     * to be shown in a UTF-8 HTML environment. Its options
234
     * are otherwise limited by design
235
     *
236
     * @param string $str   The string to escape
237
     * @param int $flags    A bitmask of `htmlentities()` compatible flags
238
     * @return string
239
     */
240
    public static function escape($str, $flags = ENT_QUOTES)
241
    {
242
        return htmlentities($str, $flags, 'UTF-8');
243
    }
244
245
    /**
246
     * Redirects the request to the current URL
247
     *
248
     * @return ServiceProvider
249
     */
250
    public function refresh()
251
    {
252
        $this->response->redirect(
253
            $this->request->uri()
254
        );
255
256
        return $this;
257
    }
258
259
    /**
260
     * Redirects the request back to the referrer
261
     *
262
     * @return ServiceProvider
263
     */
264
    public function back()
265
    {
266
        $referer = $this->request->server()->get('HTTP_REFERER');
267
268
        if (null !== $referer) {
269
            $this->response->redirect($referer);
270
        } else {
271
            $this->refresh();
272
        }
273
274
        return $this;
275
    }
276
277
    /**
278
     * Get (or set) the view's layout
279
     *
280
     * Simply calling this method without any arguments returns the current layout.
281
     * Calling with an argument, however, sets the layout to what was provided by the argument.
282
     *
283
     * @param string $layout    The layout of the view
284
     * @return string|ServiceProvider
285
     */
286
    public function layout($layout = null)
287
    {
288
        if (null !== $layout) {
289
            $this->layout = $layout;
290
291
            return $this;
292
        }
293
294
        return $this->layout;
295
    }
296
297
    /**
298
     * Renders the current view
299
     *
300
     * @return void
301
     */
302
    public function yieldView()
303
    {
304
        require $this->view;
305
    }
306
307
    /**
308
     * Renders a view + optional layout
309
     *
310
     * @param string $view  The view to render
311
     * @param array $data   The data to render in the view
312
     * @return void
313
     */
314
    public function render($view, array $data = array())
315
    {
316
        $original_view = $this->view;
317
318
        if (!empty($data)) {
319
            $this->shared_data->merge($data);
320
        }
321
322
        $this->view = $view;
323
324
        if (null === $this->layout) {
325
            $this->yieldView();
326
        } else {
327
            require $this->layout;
328
        }
329
330
        if (false !== $this->response->chunked) {
331
            $this->response->chunk();
332
        }
333
334
        // restore state for parent render()
335
        $this->view = $original_view;
336
    }
337
338
    /**
339
     * Renders a view without a layout
340
     *
341
     * @param string $view  The view to render
342
     * @param array $data   The data to render in the view
343
     * @return void
344
     */
345
    public function partial($view, array $data = array())
346
    {
347
        $layout = $this->layout;
348
        $this->layout = null;
349
        $this->render($view, $data);
350
        $this->layout = $layout;
351
    }
352
353
    /**
354
     * Magic "__isset" method
355
     *
356
     * Allows the ability to arbitrarily check the existence of shared data
357
     * from this instance while treating it as an instance property
358
     *
359
     * @param string $key     The name of the shared data
360
     * @return boolean
361
     */
362
    public function __isset($key)
363
    {
364
        return $this->shared_data->exists($key);
365
    }
366
367
    /**
368
     * Magic "__get" method
369
     *
370
     * Allows the ability to arbitrarily request shared data from this instance
371
     * while treating it as an instance property
372
     *
373
     * @param string $key     The name of the shared data
374
     * @return string
375
     */
376
    public function __get($key)
377
    {
378
        return $this->shared_data->get($key);
379
    }
380
381
    /**
382
     * Magic "__set" method
383
     *
384
     * Allows the ability to arbitrarily set shared data from this instance
385
     * while treating it as an instance property
386
     *
387
     * @param string $key     The name of the shared data
388
     * @param mixed $value      The value of the shared data
389
     * @return void
390
     */
391
    public function __set($key, $value)
392
    {
393
        $this->shared_data->set($key, $value);
394
    }
395
396
    /**
397
     * Magic "__unset" method
398
     *
399
     * Allows the ability to arbitrarily remove shared data from this instance
400
     * while treating it as an instance property
401
     *
402
     * @param string $key     The name of the shared data
403
     * @return void
404
     */
405
    public function __unset($key)
406
    {
407
        $this->shared_data->remove($key);
408
    }
409
}
410