Completed
Push — master ( f5c0e9...da30f7 )
by recca
03:41
created

DebuggerManager::replacePath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 8
ccs 4
cts 5
cp 0.8
crap 2.032
rs 9.4285
1
<?php
2
3
namespace Recca0120\LaravelTracy;
4
5
use Closure;
6
use Exception;
7
use Tracy\Bar;
8
use Tracy\Helpers;
9
use ErrorException;
10
use Tracy\Debugger;
11
use Tracy\BlueScreen;
12
use Illuminate\Support\Arr;
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
     * __construct.
39
     *
40
     * @param array $config
41
     * @param \Tracy\Bar $bar
42
     * @param \Tracy\BlueScreen $blueScreen
43
     */
44 12
    public function __construct($config = [], Bar $bar = null, BlueScreen $blueScreen = null)
45
    {
46 12
        $this->config = $config;
47 12
        $this->bar = $bar ?: Debugger::getBar();
48 12
        $this->blueScreen = $blueScreen ?: Debugger::getBlueScreen();
49 12
    }
50
51
    /**
52
     * init.
53
     *
54
     * @param array $config
55
     * @return array
56
     */
57 3
    public static function init($config = [])
58
    {
59 3
        $config = array_merge([
60 3
            'accepts' => [],
61 3
            'appendTo' => 'body',
62
            'showBar' => false,
63 3
            'editor' => Debugger::$editor,
64 3
            'maxDepth' => Debugger::$maxDepth,
65 3
            'maxLength' => Debugger::$maxLength,
66
            'scream' => true,
67
            'showLocation' => true,
68
            'strictMode' => true,
69 3
            'currentTime' => $_SERVER['REQUEST_TIME_FLOAT'] ?: microtime(true),
70 3
            'editorMapping' => isset(Debugger::$editorMapping) === true ? Debugger::$editorMapping : [],
71 3
        ], $config);
72
73 3
        Debugger::$editor = $config['editor'];
74 3
        Debugger::$maxDepth = $config['maxDepth'];
75 3
        Debugger::$maxLength = $config['maxLength'];
76 3
        Debugger::$scream = $config['scream'];
77 3
        Debugger::$showLocation = $config['showLocation'];
78 3
        Debugger::$strictMode = $config['strictMode'];
79 3
        Debugger::$time = $config['currentTime'];
80
81 3
        if (isset(Debugger::$editorMapping) === true) {
82 3
            Debugger::$editorMapping = $config['editorMapping'];
83
        }
84
85 3
        return $config;
86
    }
87
88
    /**
89
     * enabled.
90
     *
91
     * @return bool
92
     */
93 1
    public function enabled()
94
    {
95 1
        return Arr::get($this->config, 'enabled', true) === true;
96
    }
97
98
    /**
99
     * showBar.
100
     *
101
     * @return bool
102
     */
103 1
    public function showBar()
104
    {
105 1
        return Arr::get($this->config, 'showBar', true) === true;
106
    }
107
108
    /**
109
     * accepts.
110
     *
111
     * @return array
112
     */
113 1
    public function accepts()
114
    {
115 1
        return Arr::get($this->config, 'accepts', []);
116
    }
117
118
    /**
119
     * dispatchAssets.
120
     *
121
     * @param string $type
122
     * @return array
123
     */
124 4
    public function dispatchAssets($type)
125
    {
126
        switch ($type) {
127 4
            case 'css':
128 3
            case 'js':
129 2
            case 'assets':
130
                $headers = [
131 3
                    'Content-Type' => $type === 'css' ? 'text/css; charset=utf-8' : 'text/javascript; charset=utf-8',
132 3
                    'Cache-Control' => 'max-age=86400',
133
                ];
134 3
                $content = $this->replacePath(
135
                    $this->renderBuffer(function () {
136 3
                        return $this->bar->dispatchAssets();
137 3
                    })
138
                );
139 3
                break;
140
            default:
141
                $headers = [
142 1
                    'Content-Type' => 'text/javascript; charset=utf-8',
143
                ];
144 1
                $content = $this->dispatch();
145 1
                break;
146
        }
147
148
        return [
149 4
            array_merge($headers, [
150 4
                'Content-Length' => strlen($content),
151
            ]),
152 4
            $content,
153
        ];
154
    }
155
156
    /**
157
     * dispatch.
158
     *
159
     * @return string
160
     */
161 1
    public function dispatch()
162
    {
163 1
        if (session_status() !== PHP_SESSION_ACTIVE) {
164 1
            ini_set('session.use_cookies', '1');
165 1
            ini_set('session.use_only_cookies', '1');
166 1
            ini_set('session.use_trans_sid', '0');
167 1
            ini_set('session.cookie_path', '/');
168 1
            ini_set('session.cookie_httponly', '1');
169 1
            session_start();
170
        }
171
172 1
        return $this->replacePath(
173
            $this->renderBuffer(function () {
174 1
                return method_exists($this->bar, 'dispatchContent') === true ?
175 1
                        $this->bar->dispatchContent() : $this->bar->dispatchAssets();
176 1
            })
177
        );
178
    }
179
180
    /**
181
     * shutdownHandler.
182
     *
183
     * @param string $content
184
     * @return string
185
     */
186 3
    public function shutdownHandler($content, $error = null)
187
    {
188 3
        $error = $error ?: error_get_last();
189 3
        if (in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE, E_RECOVERABLE_ERROR, E_USER_ERROR], true)) {
190 1
            return $this->exceptionHandler(
191 1
                Helpers::fixStack(
192 1
                    new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line'])
193
                )
194
            );
195
        }
196
197 2
        $bar = $this->replacePath(
198
                $this->renderBuffer(function () {
199 2
                    $this->bar->render();
200 2
                })
201
        );
202
203 2
        $appendTo = Arr::get($this->config, 'appendTo', 'body');
204 2
        $pos = strripos($content, '</'.$appendTo.'>');
205
206 2
        return $pos !== false
207 2
            ? substr($content, 0, $pos).$bar.substr($content, $pos)
208 2
            : $content.$bar;
209
    }
210
211
    /**
212
     * exceptionHandler.
213
     *
214
     * @param \Exception $exception
215
     * @return string
216
     */
217
    public function exceptionHandler(Exception $exception)
218
    {
219 2
        return $this->renderBuffer(function () use ($exception) {
220 2
            Helpers::improveException($exception);
221 2
            $this->blueScreen->render($exception);
222 2
        });
223
    }
224
225
    /**
226
     * renderBuffer.
227
     *
228
     * @param \Closure $callback
229
     * @return string
230
     */
231 8
    protected function renderBuffer(Closure $callback)
232
    {
233 8
        ob_start();
234 8
        $callback();
235
236 8
        return ob_get_clean();
237
    }
238
239
    /**
240
     * replacePath.
241
     *
242
     * @param string $content
243
     * @return string
244
     */
245 6
    protected function replacePath($content)
246
    {
247 6
        $root = Arr::get($this->config, 'root');
248
249 6
        return empty($root) === false
250
            ? str_replace('?_tracy_bar', $root.'/tracy/bar?_tracy_bar', $content)
251 6
            : $content;
252
    }
253
}
254