Completed
Push — master ( 49c4da...13ab8c )
by recca
06:41
created

DebuggerManager::render()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.0123

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 3
nop 3
dl 0
loc 18
ccs 8
cts 9
cp 0.8889
crap 3.0123
rs 9.4285
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 13
    public function __construct($config = [], Bar $bar = null, BlueScreen $blueScreen = null, Session $session = null)
59
    {
60 13
        $this->config = $config;
61 13
        $this->bar = $bar ?: Debugger::getBar();
62 13
        $this->blueScreen = $blueScreen ?: Debugger::getBlueScreen();
63 13
        $this->session = $session ?: new Session;
64 13
    }
65
66
    /**
67
     * init.
68
     *
69
     * @param array $config
70
     * @return array
71
     */
72 3
    public static function init($config = [])
73
    {
74 3
        $config = array_merge([
75 3
            'accepts' => [],
76 3
            'appendTo' => 'body',
77
            'showBar' => false,
78 3
            'editor' => Debugger::$editor,
79 3
            'maxDepth' => Debugger::$maxDepth,
80 3
            'maxLength' => Debugger::$maxLength,
81
            'scream' => true,
82
            'showLocation' => true,
83
            'strictMode' => true,
84 3
            'currentTime' => $_SERVER['REQUEST_TIME_FLOAT'] ?: microtime(true),
85 3
            'editorMapping' => isset(Debugger::$editorMapping) === true ? Debugger::$editorMapping : [],
86 3
        ], $config);
87
88 3
        Debugger::$editor = $config['editor'];
89 3
        Debugger::$maxDepth = $config['maxDepth'];
90 3
        Debugger::$maxLength = $config['maxLength'];
91 3
        Debugger::$scream = $config['scream'];
92 3
        Debugger::$showLocation = $config['showLocation'];
93 3
        Debugger::$strictMode = $config['strictMode'];
94 3
        Debugger::$time = $config['currentTime'];
95
96 3
        if (isset(Debugger::$editorMapping) === true) {
97 3
            Debugger::$editorMapping = $config['editorMapping'];
98
        }
99
100 3
        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 2
    public function setUrlGenerator(UrlGenerator $urlGenerator)
140
    {
141 2
        $this->urlGenerator = $urlGenerator;
142
143 2
        return $this;
144
    }
145
146
    /**
147
     * dispatchAssets.
148
     *
149
     * @param string $type
150
     * @return array
151
     */
152 3
    public function dispatchAssets($type)
153
    {
154
        switch ($type) {
155 3
            case 'css':
156 2
            case 'js':
157
                $headers = [
158 2
                    'Content-Type' => $type === 'css' ? 'text/css; charset=utf-8' : 'text/javascript; charset=utf-8',
159 2
                    'Cache-Control' => 'max-age=86400',
160
                ];
161 2
                $content = $this->renderBuffer(function () {
162 2
                    return $this->bar->dispatchAssets();
163 2
                });
164 2
                break;
165
            default:
166
                $headers = [
167 1
                    'Content-Type' => 'text/javascript; charset=utf-8',
168
                ];
169 1
                $content = $this->dispatch();
170 1
                break;
171
        }
172
173
        return [
174 3
            array_merge($headers, [
175 3
                'Content-Length' => strlen($content),
176
            ]),
177 3
            $content,
178
        ];
179
    }
180
181
    /**
182
     * dispatch.
183
     *
184
     * @return string
185
     */
186 1
    public function dispatch()
187
    {
188 1
        if ($this->session->isStarted() === false) {
189 1
            $this->session->start();
190
        }
191
192 1
        return $this->renderBuffer(function () {
193 1
            return $this->bar->dispatchAssets();
194 1
        });
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 4
        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
    public function exceptionHandler(Exception $exception)
228
    {
229 2
        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
    protected function render($content, $method, $appendTags = ['body'])
275
    {
276 4
        $appendHtml = $this->renderBuffer(function () use ($method) {
277 4
            call_user_func([$this->bar, $method]);
278 4
        });
279
280 4
        $appendTags = array_unique($appendTags);
281
282 4
        foreach ($appendTags as $appendTag) {
283 4
            $pos = strripos($content, '</'.$appendTag.'>');
284
285 4
            if ($pos !== false) {
286 4
                return substr_replace($content, $appendHtml, $pos, 0);
287
            }
288
        }
289
290
        return $content.$appendHtml;
291
    }
292
293
    /**
294
     * renderBuffer.
295
     *
296
     * @param callable $callback
297
     * @return string
298
     */
299 9
    protected function renderBuffer(callable $callback)
300
    {
301 9
        ob_start();
302 9
        $callback();
303
304 9
        return $this->replacePath(ob_get_clean());
305
    }
306
307
    /**
308
     * replacePath.
309
     *
310
     * @param string $content
311
     * @return string
312
     */
313 9
    protected function replacePath($content)
314
    {
315 9
        static $path;
316
317 9
        if (is_null($path) === true) {
318 9
            $path = is_null($this->urlGenerator) === false
319 1
                ? $this->urlGenerator->route(Arr::get($this->config, 'route.as').'bar')
320 9
                : null;
321
        }
322
323 9
        return is_null($path) === false
324 1
            ? str_replace('?_tracy_bar', $path.'?_tracy_bar', $content)
325 9
            : $content;
326
    }
327
}
328