Completed
Push — master ( 1ba24b...6a81f3 )
by recca
01:24
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.072

Importance

Changes 0
Metric Value
cc 3
eloc 9
c 0
b 0
f 0
nc 3
nop 3
dl 0
loc 18
ccs 8
cts 10
cp 0.8
crap 3.072
rs 9.4285
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
     * $urlGenerator.
39
     *
40
     * @var \Illuminate\Contracts\Routing\UrlGenerator
41
     */
42
    protected $urlGenerator;
43
44
    /**
45
     * __construct.
46
     *
47
     * @param array $config
48
     * @param \Tracy\Bar $bar
49
     * @param \Tracy\BlueScreen $blueScreen
50
     */
51 13
    public function __construct($config = [], Bar $bar = null, BlueScreen $blueScreen = null, Session $session = null)
52
    {
53 13
        $this->config = $config;
54 13
        $this->bar = $bar ?: Debugger::getBar();
55 13
        $this->blueScreen = $blueScreen ?: Debugger::getBlueScreen();
56 13
        $this->session = $session ?: new Session;
0 ignored issues
show
Bug introduced by
The property session does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
57 13
    }
58
59
    /**
60
     * init.
61
     *
62
     * @param array $config
63
     * @return array
64
     */
65 3
    public static function init($config = [])
66
    {
67 3
        $config = array_merge([
68 3
            'accepts' => [],
69 3
            'appendTo' => 'body',
70 3
            'showBar' => false,
71 3
            'editor' => Debugger::$editor,
72 3
            'maxDepth' => Debugger::$maxDepth,
73 3
            'maxLength' => Debugger::$maxLength,
74 3
            'scream' => true,
75 3
            'showLocation' => true,
76 3
            'strictMode' => true,
77 3
            'currentTime' => $_SERVER['REQUEST_TIME_FLOAT'] ?: microtime(true),
78 3
            'editorMapping' => isset(Debugger::$editorMapping) === true ? Debugger::$editorMapping : [],
79 3
        ], $config);
80
81 3
        Debugger::$editor = $config['editor'];
82 3
        Debugger::$maxDepth = $config['maxDepth'];
83 3
        Debugger::$maxLength = $config['maxLength'];
84 3
        Debugger::$scream = $config['scream'];
85 3
        Debugger::$showLocation = $config['showLocation'];
86 3
        Debugger::$strictMode = $config['strictMode'];
87 3
        Debugger::$time = $config['currentTime'];
88
89 3
        if (isset(Debugger::$editorMapping) === true) {
90 3
            Debugger::$editorMapping = $config['editorMapping'];
91 3
        }
92
93 3
        return $config;
94
    }
95
96
    /**
97
     * enabled.
98
     *
99
     * @return bool
100
     */
101 1
    public function enabled()
102
    {
103 1
        return Arr::get($this->config, 'enabled', true) === true;
104
    }
105
106
    /**
107
     * showBar.
108
     *
109
     * @return bool
110
     */
111 1
    public function showBar()
112
    {
113 1
        return Arr::get($this->config, 'showBar', true) === true;
114
    }
115
116
    /**
117
     * accepts.
118
     *
119
     * @return array
120
     */
121 1
    public function accepts()
122
    {
123 1
        return Arr::get($this->config, 'accepts', []);
124
    }
125
126
    /**
127
     * setUrlGenerator.
128
     *
129
     * @param \Illuminate\Contracts\Routing\UrlGenerator $urlGenerator
130
     * @return $this
131
     */
132 2
    public function setUrlGenerator(UrlGenerator $urlGenerator)
133
    {
134 2
        $this->urlGenerator = $urlGenerator;
135
136 2
        return $this;
137
    }
138
139
    /**
140
     * dispatchAssets.
141
     *
142
     * @param string $type
143
     * @return array
144
     */
145 3
    public function dispatchAssets($type)
146
    {
147
        switch ($type) {
148 3
            case 'css':
149 3
            case 'js':
150
                $headers = [
151 2
                    'Content-Type' => $type === 'css' ? 'text/css; charset=utf-8' : 'text/javascript; charset=utf-8',
152 2
                    'Cache-Control' => 'max-age=86400',
153 2
                ];
154
                $content = $this->renderBuffer(function () {
155 2
                    return $this->bar->dispatchAssets();
156 2
                });
157 2
                break;
158 1
            default:
159
                $headers = [
160 1
                    'Content-Type' => 'text/javascript; charset=utf-8',
161 1
                ];
162 1
                $content = $this->dispatch();
163 1
                break;
164 1
        }
165
166 3
        $content = $this->replacePath($content);
167
168
        return [
169 3
            array_merge($headers, [
170 3
                'Content-Length' => strlen($content),
171 3
            ]),
172 3
            $content,
173 3
        ];
174
    }
175
176
    /**
177
     * dispatch.
178
     *
179
     * @return string
180
     */
181 1
    public function dispatch()
182
    {
183 1
        if ($this->session->isStarted() === false) {
184 1
            $this->session->start();
185 1
        }
186
187
        return $this->renderBuffer(function () {
188 1
            return $this->bar->dispatchAssets();
189 1
        });
190
    }
191
192
    /**
193
     * shutdownHandler.
194
     *
195
     * @param string $content
196
     * @return string
197
     */
198 5
    public function shutdownHandler($content, $error = null)
199
    {
200 5
        $error = $error ?: error_get_last();
201 5
        if (in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE, E_RECOVERABLE_ERROR, E_USER_ERROR], true)) {
202 1
            return $this->exceptionHandler(
203 1
                Helpers::fixStack(
204 1
                    new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line'])
205 1
                )
206 1
            );
207
        }
208
209
        return array_reduce(['renderLoader', 'renderBar', 'replacePath'], function ($content, $method) {
210 4
            return call_user_func([$this, $method], $content);
211 4
        }, $content);
212
    }
213
214
    /**
215
     * exceptionHandler.
216
     *
217
     * @param \Exception $exception
218
     * @return string
219
     */
220 2
    public function exceptionHandler(Exception $exception)
221
    {
222 2
        return $this->replacePath(
223
            $this->renderBuffer(function () use ($exception) {
224 2
                Helpers::improveException($exception);
225 2
                $this->blueScreen->render($exception);
226 2
            })
227 2
        );
228
    }
229
230
    /**
231
     * renderLoader.
232
     *
233
     * @param string $content
234
     * @return string
235
     */
236 4
    protected function renderLoader($content)
237
    {
238 4
        if ($this->session->isStarted() === false) {
239 1
            return $content;
240
        }
241
242 3
        return $this->render($content, 'renderLoader', ['head', 'body']);
243
    }
244
245
    /**
246
     * renderBar.
247
     *
248
     * @param string $content
249
     * @return string
250
     */
251 4
    protected function renderBar($content)
252
    {
253 4
        return $this->render(
254 4
            $content,
255 4
            'render',
256 4
            [Arr::get($this->config, 'appendTo', 'body'), 'body']
257 4
        );
258
    }
259
260
    /**
261
     * render.
262
     *
263
     * @param string $content
264
     * @param string $method
265
     * @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...
266
     * @return string
267
     */
268
    protected function render($content, $method, $appendTags = ['body'])
269
    {
270 4
        $appendHtml = $this->renderBuffer(function () use ($method) {
271 4
            call_user_func([$this->bar, $method]);
272 4
        });
273
274 4
        $appendTags = array_unique($appendTags);
275
276 4
        foreach ($appendTags as $appendTag) {
277 4
            $pos = strripos($content, '</'.$appendTag.'>');
278
279 4
            if ($pos !== false) {
280 4
                return substr($content, 0, $pos).$appendHtml.substr($content, $pos);
281
            }
282
        }
283
284
        return $content.$appendHtml;
285
    }
286
287
    /**
288
     * renderBuffer.
289
     *
290
     * @param callable $callback
291
     * @return string
292
     */
293 9
    protected function renderBuffer(callable $callback)
294
    {
295 9
        ob_start();
296 9
        $callback();
297
298 9
        return ob_get_clean();
299
    }
300
301
    /**
302
     * replacePath.
303
     *
304
     * @param string $content
305
     * @return string
306
     */
307 9
    protected function replacePath($content)
308
    {
309 9
        $path = is_null($this->urlGenerator) === false
310 9
            ? $this->urlGenerator->route(Arr::get($this->config, 'route.as').'bar')
311 9
            : null;
312
313 9
        return empty($path) === false
314 9
            ? str_replace('?_tracy_bar', $path.'?_tracy_bar', $content)
315 9
            : $content;
316
    }
317
}
318