Completed
Push — master ( dbd801...d0a1e5 )
by recca
02:19
created

src/DebuggerManager.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
                $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
        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'])
0 ignored issues
show
new \ErrorException($err...file'], $error['line']) is of type object<ErrorException>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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);
0 ignored issues
show
$exception is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
231 2
            $this->blueScreen->render($exception);
0 ignored issues
show
$exception is of type object<Exception>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

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