Passed
Push — master ( d1ec6d...cf8234 )
by Thomas
14:18
created

DebugBarMiddleware::afterRequest()   D

Complexity

Conditions 18
Paths 69

Size

Total Lines 76
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 3
Metric Value
cc 18
eloc 42
c 6
b 0
f 3
nc 69
nop 2
dl 0
loc 76
rs 4.8666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace LeKoala\DebugBar\Middleware;
4
5
use LeKoala\DebugBar\DebugBar;
6
use SilverStripe\Control\Middleware\HTTPMiddleware;
7
use SilverStripe\Control\Director;
8
use SilverStripe\Control\HTTPRequest;
9
use SilverStripe\Control\HTTPResponse;
10
use SilverStripe\View\Requirements;
11
12
class DebugBarMiddleware implements HTTPMiddleware
13
{
14
    public function process(HTTPRequest $request, callable $delegate)
15
    {
16
        $this->beforeRequest($request);
17
        $response = $delegate($request);
18
        if ($response) {
19
            $this->afterRequest($request, $response);
20
        }
21
        return $response;
22
    }
23
24
    /**
25
     * Track the start up of the framework boot
26
     *
27
     * @param HTTPRequest $request
28
     * @return void
29
     */
30
    protected function beforeRequest(HTTPRequest $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

30
    protected function beforeRequest(/** @scrutinizer ignore-unused */ HTTPRequest $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
31
    {
32
        DebugBar::withDebugBar(function (\DebugBar\DebugBar $debugbar) {
33
            /** @var \DebugBar\DataCollector\TimeDataCollector|null $timeData */
34
            $timeData = $debugbar->getCollector('time');
35
36
            if (!$timeData) {
0 ignored issues
show
introduced by
$timeData is of type DebugBar\DataCollector\TimeDataCollector, thus it always evaluated to true.
Loading history...
37
                return;
38
            }
39
40
            // Allows a more realistic view
41
            // Define FRAMEWORK_BOOT_TIME in your index.php after composer autoload
42
            if (defined('FRAMEWORK_BOOT_TIME')) {
43
                if (isset($_SERVER['REQUEST_TIME_FLOAT'])) {
44
                    $timeData = $debugbar['time'];
45
                    $timeData->addMeasure(
0 ignored issues
show
Bug introduced by
The method addMeasure() does not exist on DebugBar\DataCollector\DataCollectorInterface. It seems like you code against a sub-type of DebugBar\DataCollector\DataCollectorInterface such as DebugBar\DataCollector\TimeDataCollector. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
                    $timeData->/** @scrutinizer ignore-call */ 
46
                               addMeasure(
Loading history...
46
                        'php boot',
47
                        $_SERVER['REQUEST_TIME_FLOAT'],
48
                        constant('FRAMEWORK_BOOT_TIME')
49
                    );
50
                    $timeData->addMeasure(
51
                        'framework boot',
52
                        constant('FRAMEWORK_BOOT_TIME'),
53
                        microtime(true)
54
                    );
55
                } else {
56
                    $timeData = $debugbar['time'];
57
                    $timeData->addMeasure(
58
                        'framework boot',
59
                        constant('FRAMEWORK_BOOT_TIME'),
60
                        microtime(true)
61
                    );
62
                }
63
            } elseif (isset($_SERVER['REQUEST_TIME_FLOAT'])) {
64
                $timeData = $debugbar['time'];
65
                $timeData->addMeasure(
66
                    'framework boot',
67
                    $_SERVER['REQUEST_TIME_FLOAT'],
68
                    microtime(true)
69
                );
70
            }
71
72
            DebugBar::closeExtraTime();
73
            $timeData->startMeasure('pre_request', 'pre request');
0 ignored issues
show
Bug introduced by
The method startMeasure() does not exist on DebugBar\DataCollector\DataCollectorInterface. It seems like you code against a sub-type of DebugBar\DataCollector\DataCollectorInterface such as DebugBar\DataCollector\TimeDataCollector. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
            $timeData->/** @scrutinizer ignore-call */ 
74
                       startMeasure('pre_request', 'pre request');
Loading history...
74
        });
75
    }
76
77
    /**
78
     * Inject DebugBar requirements for the frontend
79
     *
80
     * @param HTTPRequest  $request
81
     * @param HTTPResponse $response
82
     * @return void
83
     */
84
    protected function afterRequest(HTTPRequest $request, HTTPResponse $response)
85
    {
86
        $debugbar = DebugBar::getDebugBar();
87
        if (!$debugbar) {
0 ignored issues
show
introduced by
$debugbar is of type DebugBar\DebugBar, thus it always evaluated to true.
Loading history...
88
            return;
89
        }
90
        DebugBar::setRequest($request);
91
92
        // All queries have been displayed
93
        if (DebugBar::getShowQueries()) {
94
            exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
95
        }
96
97
        $script = DebugBar::renderDebugBar();
98
99
        // If the bar is not renderable, return early
100
        if (!$script) {
101
            return;
102
        }
103
104
        // Use module to make sure it's deferred and does not cause side effects
105
        $script = str_replace('<script type="text/javascript">', '<script type="module">', $script);
106
107
        // Inject init script into the HTML response
108
        $body = (string)$response->getBody();
109
        if (strpos($body, '</body>') !== false) {
110
            $customScripts = '';
111
            if (DebugBar::$suppressJquery) {
112
                // Move scripts after the latest script
113
                $matches = [];
114
                preg_match_all('/<script(.*) src="(.*)\/debugbar\/(.*)"><\/script>/', $body, $matches);
115
                $body = preg_replace('/<script(.*) src="(.*)\/debugbar\/(.*)"><\/script>\n/', '', $body);
116
                $customScripts = implode("\n", $matches[0]);
117
            }
118
119
            $scriptsToInsert = $customScripts . "\n" . $script;
120
            // You can use a placeholder if somehow you have a </body> string somewhere else in the body
121
            // @link https://github.com/lekoala/silverstripe-debugbar/issues/154
122
            $debugbarPlaceholder = "<!-- debugbar -->";
123
            if (strpos($body, $debugbarPlaceholder) !== false) {
124
                $body = str_replace($debugbarPlaceholder, $scriptsToInsert, $body);
125
            } else {
126
                if (Requirements::get_write_js_to_body()) {
127
                    // Replace the last occurence of </body>
128
                    $pos = strrpos($body, '</body>');
129
                    if ($pos !== false) {
130
                        $body = substr_replace($body, $scriptsToInsert . '</body>', $pos, strlen('</body>'));
131
                    }
132
                } else {
133
                    // Replace the first occurence of </head>
134
                    $pos = strpos($body, '</head>');
135
                    if ($pos !== false) {
136
                        $body = substr_replace($body, $scriptsToInsert . '</head>', $pos, strlen('</head>'));
137
                    }
138
                }
139
            }
140
            $response->setBody($body);
0 ignored issues
show
Bug introduced by
It seems like $body can also be of type array; however, parameter $body of SilverStripe\Control\HTTPResponse::setBody() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

140
            $response->setBody(/** @scrutinizer ignore-type */ $body);
Loading history...
141
        }
142
143
        // Ajax support
144
        if (Director::is_ajax() && !headers_sent()) {
145
            if (DebugBar::isAdminUrl() && !DebugBar::config()->get('enabled_in_admin')) {
146
                return;
147
            }
148
            // Skip anything that is not a GET request
149
            if (!$request->isGET()) {
150
                return;
151
            }
152
            // Always enable in admin because everything is mostly loaded through ajax
153
            if (DebugBar::config()->get('ajax') || DebugBar::isAdminUrl()) {
154
                $headers = $debugbar->getDataAsHeaders();
155
156
                // Prevent throwing js errors in case header size is too large
157
                if (is_array($headers)) {
0 ignored issues
show
introduced by
The condition is_array($headers) is always true.
Loading history...
158
                    $maxHeaderLength = DebugBar::config()->get('max_header_length');
159
                    $debugbar->sendDataInHeaders(null, 'phpdebugbar', $maxHeaderLength);
160
                }
161
            }
162
        }
163
    }
164
}
165