Completed
Push — master ( 53fb95...674a62 )
by recca
31:52 queued 27:07
created

DebuggerManager::render()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3.004

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 3
dl 0
loc 22
ccs 12
cts 13
cp 0.9231
crap 3.004
rs 9.568
c 0
b 0
f 0
1
<?php
2
3
namespace Recca0120\LaravelTracy;
4
5
use Exception;
6
use Tracy\Bar;
7
use Tracy\Helpers;
8
use ErrorException;
9
use Tracy\Debugger;
10
use Tracy\BlueScreen;
11
use Illuminate\Support\Arr;
12
use Illuminate\Contracts\Routing\UrlGenerator;
13
14
class DebuggerManager
15
{
16
    /**
17
     * $config.
18
     *
19
     * @var array
20
     */
21
    protected $config;
22
23
    /**
24
     * $bar.
25
     *
26
     * @var \Tracy\Bar
27
     */
28
    protected $bar;
29
30
    /**
31
     * $blueScreen.
32
     *
33
     * @var \Tracy\BlueScreen
34
     */
35
    protected $blueScreen;
36
37
    /**
38
     * $session.
39
     *
40
     * @var \Recca0120\LaravelTracy\Session
41
     */
42
    protected $session;
43
44
    /**
45
     * $urlGenerator.
46
     *
47
     * @var \Illuminate\Contracts\Routing\UrlGenerator
48
     */
49
    protected $urlGenerator;
50
51
    /**
52
     * __construct.
53
     *
54
     * @param array $config
55
     * @param \Tracy\Bar $bar
56
     * @param \Tracy\BlueScreen $blueScreen
57
     */
58 9
    public function __construct($config = [], Bar $bar = null, BlueScreen $blueScreen = null, Session $session = null)
59
    {
60 9
        $this->config = $config;
61 9
        $this->bar = $bar ?: Debugger::getBar();
62 9
        $this->blueScreen = $blueScreen ?: Debugger::getBlueScreen();
63 9
        $this->session = $session ?: new Session;
64 9
    }
65
66
    /**
67
     * init.
68
     *
69
     * @param array $config
70
     * @return array
71
     */
72 1
    public static function init($config = [])
73
    {
74 1
        $config = array_merge([
75 1
            'accepts' => [],
76 1
            'appendTo' => 'body',
77
            'showBar' => false,
78 1
            'editor' => Debugger::$editor,
79 1
            'maxDepth' => Debugger::$maxDepth,
80 1
            'maxLength' => Debugger::$maxLength,
81
            'scream' => true,
82
            'showLocation' => true,
83
            'strictMode' => true,
84 1
            'currentTime' => $_SERVER['REQUEST_TIME_FLOAT'] ?: microtime(true),
85 1
            'editorMapping' => isset(Debugger::$editorMapping) === true ? Debugger::$editorMapping : [],
86
        ], $config);
87
88 1
        Debugger::$editor = $config['editor'];
89 1
        Debugger::$maxDepth = $config['maxDepth'];
90 1
        Debugger::$maxLength = $config['maxLength'];
91 1
        Debugger::$scream = $config['scream'];
92 1
        Debugger::$showLocation = $config['showLocation'];
93 1
        Debugger::$strictMode = $config['strictMode'];
94 1
        Debugger::$time = $config['currentTime'];
95
96 1
        if (isset(Debugger::$editorMapping) === true) {
97 1
            Debugger::$editorMapping = $config['editorMapping'];
98
        }
99
100 1
        return $config;
101
    }
102
103
    /**
104
     * enabled.
105
     *
106
     * @return bool
107
     */
108 1
    public function enabled()
109
    {
110 1
        return Arr::get($this->config, 'enabled', true) === true;
111
    }
112
113
    /**
114
     * showBar.
115
     *
116
     * @return bool
117
     */
118 1
    public function showBar()
119
    {
120 1
        return Arr::get($this->config, 'showBar', true) === true;
121
    }
122
123
    /**
124
     * accepts.
125
     *
126
     * @return array
127
     */
128 1
    public function accepts()
129
    {
130 1
        return Arr::get($this->config, 'accepts', []);
131
    }
132
133
    /**
134
     * setUrlGenerator.
135
     *
136
     * @param \Illuminate\Contracts\Routing\UrlGenerator $urlGenerator
137
     * @return $this
138
     */
139 1
    public function setUrlGenerator(UrlGenerator $urlGenerator)
140
    {
141 1
        $this->urlGenerator = $urlGenerator;
142
143 1
        return $this;
144
    }
145
146
    /**
147
     * dispatchAssets.
148
     *
149
     * @param string $type
150
     * @return array
151
     */
152
    public function dispatchAssets($type)
153
    {
154
        switch ($type) {
155
            case 'css':
156
            case 'js':
157
                $headers = [
158
                    'Content-Type' => $type === 'css' ? 'text/css; charset=utf-8' : 'text/javascript; charset=utf-8',
159
                    'Cache-Control' => 'max-age=86400',
160
                ];
161
                $content = $this->renderBuffer(function () {
162
                    return $this->bar->dispatchAssets();
163
                });
164
                break;
165
            default:
166
                $headers = [
167
                    'Content-Type' => 'text/javascript; charset=utf-8',
168
                ];
169
                $content = $this->dispatch();
170
                break;
171
        }
172
173
        return [
174
            array_merge($headers, [
175
                'Content-Length' => strlen($content),
176
            ]),
177
            $content,
178
        ];
179
    }
180
181
    /**
182
     * dispatch.
183
     *
184
     * @return string
185
     */
186
    public function dispatch()
187
    {
188
        if ($this->session->isStarted() === false) {
189
            $this->session->start();
190
        }
191
192
        return $this->renderBuffer(function () {
193
            return $this->bar->dispatchAssets();
194
        });
195
    }
196
197
    /**
198
     * shutdownHandler.
199
     *
200
     * @param string $content
201
     * @param bool $ajax
202
     * @param int $error
203
     * @return string
204
     */
205 5
    public function shutdownHandler($content, $ajax = false, $error = null)
206
    {
207 5
        $error = $error ?: error_get_last();
208 5
        if (in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE, E_RECOVERABLE_ERROR, E_USER_ERROR], true)) {
209 1
            return $this->exceptionHandler(
210 1
                Helpers::fixStack(
211 1
                    new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line'])
212
                )
213
            );
214
        }
215
216
        return array_reduce(['renderLoader', 'renderBar'], function ($content, $method) use ($ajax) {
217 4
            return call_user_func([$this, $method], $content, $ajax);
218 4
        }, $content);
219
    }
220
221
    /**
222
     * exceptionHandler.
223
     *
224
     * @param \Exception $exception
225
     * @return string
226
     */
227 2
    public function exceptionHandler(Exception $exception)
228
    {
229
        return $this->renderBuffer(function () use ($exception) {
230 2
            Helpers::improveException($exception);
231 2
            $this->blueScreen->render($exception);
232 2
        });
233
    }
234
235
    /**
236
     * renderLoader.
237
     *
238
     * @param string $content
239
     * @param bool $ajax
240
     * @return string
241
     */
242 4
    protected function renderLoader($content, $ajax = false)
243
    {
244 4
        if ($ajax === true || $this->session->isStarted() === false) {
245 1
            return $content;
246
        }
247
248 3
        return $this->render($content, 'renderLoader', ['head', 'body']);
249
    }
250
251
    /**
252
     * renderBar.
253
     *
254
     * @param string $content
255
     * @return string
256
     */
257 4
    protected function renderBar($content)
258
    {
259 4
        return $this->render(
260 4
            $content,
261 4
            'render',
262 4
            [Arr::get($this->config, 'appendTo', 'body'), 'body']
263
        );
264
    }
265
266
    /**
267
     * render.
268
     *
269
     * @param string $content
270
     * @param string $method
271
     * @param array $appendTo
0 ignored issues
show
Bug introduced by
There is no parameter named $appendTo. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
272
     * @return string
273
     */
274 4
    protected function render($content, $method, $appendTags = ['body'])
275
    {
276
        $appendHtml = $this->renderBuffer(function () use ($method) {
277 4
            $requestUri = Arr::get($_SERVER, 'REQUEST_URI');
278 4
            Arr::set($_SERVER, 'REQUEST_URI', '');
279 4
            Arr::set($_SERVER, 'REQUEST_URI', '');
280 4
            call_user_func([$this->bar, $method]);
281 4
            Arr::set($_SERVER, 'REQUEST_URI', $requestUri);
282 4
        });
283
284 4
        $appendTags = array_unique($appendTags);
285
286 4
        foreach ($appendTags as $appendTag) {
287 4
            $pos = strripos($content, '</'.$appendTag.'>');
288
289 4
            if ($pos !== false) {
290 4
                return substr_replace($content, $appendHtml, $pos, 0);
291
            }
292
        }
293
294
        return $content.$appendHtml;
295
    }
296
297
    /**
298
     * renderBuffer.
299
     *
300
     * @param callable $callback
301
     * @return string
302
     */
303 6
    protected function renderBuffer(callable $callback)
304
    {
305 6
        ob_start();
306 6
        $callback();
307
308 6
        return $this->replacePath(ob_get_clean());
309
    }
310
311
    /**
312
     * replacePath.
313
     *
314
     * @param string $content
315
     * @return string
316
     */
317 6
    protected function replacePath($content)
318
    {
319 6
        static $path;
320
321 6
        if (is_null($path) === true) {
322 6
            $path = is_null($this->urlGenerator) === false
323 1
                ? $this->urlGenerator->route(Arr::get($this->config, 'route.as').'bar')
324 6
                : null;
325
        }
326
327 6
        return is_null($path) === false
328 1
            ? str_replace('?_tracy_bar', $path.'?_tracy_bar', $content)
329 6
            : $content;
330
    }
331
}
332