Completed
Push — master ( 4f9c8e...9e0130 )
by Thomas
01:26
created

DebugBar::isAdminController()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 6 and the first side effect is on line 349.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
/**
4
 * A simple helper
5
 */
6
class DebugBar extends Object
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
7
{
8
9
    /**
10
     * @var DebugBar\DebugBar
11
     */
12
    protected static $debugbar = null;
13
14
    /**
15
     *
16
     * @var bool
17
     */
18
    public static $bufferingEnabled = false;
19
20
    /**
21
     * @var DebugBar\JavascriptRenderer
22
     */
23
    protected static $renderer = null;
24
25
    /**
26
     *
27
     * @var bool
28
     */
29
    protected static $showQueries = false;
30
31
    /**
32
     * Get the Debug Bar instance
33
     * @return \DebugBar\StandardDebugBar
34
     * @throws Exception
35
     * @global array $databaseConfig
36
     */
37
    public static function getDebugBar()
38
    {
39
        if (self::$debugbar !== null) {
40
            return self::$debugbar;
41
        }
42
43
        if (!Director::isDev() || self::isDisabled() || self::vendorNotInstalled() ||
44
            self::notLocalIp() || Director::is_cli() || self::isDevUrl() ||
45
            (self::isAdminUrl() && !self::config()->enabled_in_admin)
46
        ) {
47
            self::$debugbar = null; // No need to check again
48
            return;
49
        }
50
51
        self::initDebugBar();
52
53
        if (!self::$debugbar) {
54
            throw new Exception("Failed to initialize the DebugBar");
55
        }
56
57
        return self::$debugbar;
58
    }
59
60
    /**
61
     * Init the debugbar instance
62
     *
63
     * @global array $databaseConfig
64
     * @return DebugBar\StandardDebugBar
65
     */
66
    public static function initDebugBar()
67
    {
68
        // Prevent multiple inits
69
        if (self::$debugbar) {
70
            return self::$debugbar;
71
        }
72
73
        // Add the controller extension programmaticaly because it might not be added properly through yml
74
        Controller::add_extension('DebugBarControllerExtension');
75
76
        // Add a custom logger that logs everything under the Messages tab
77
        SS_Log::add_writer(new DebugBarLogWriter(), SS_Log::DEBUG, '<=');
78
79
        self::$debugbar = $debugbar = new DebugBar\DebugBar();
80
81
        if (isset($_REQUEST['showqueries'])) {
82
            self::setShowQueries(true);
83
            echo "The queries above have been run before we started DebugBar";
84
            echo '<hr>';
85
            unset($_REQUEST['showqueries']);
86
        }
87
88
        $debugbar->addCollector(new DebugBar\DataCollector\PhpInfoCollector());
89
        $debugbar->addCollector(new DebugBarTimeDataCollector());
90
        $debugbar->addCollector(new DebugBar\DataCollector\MemoryCollector());
91
92
        if (!DB::get_conn()) {
93
            global $databaseConfig;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
94
            if ($databaseConfig) {
95
                DB::connect($databaseConfig);
96
            }
97
        }
98
99
        $connector = DB::get_connector();
100
        if (!self::config()->force_proxy && $connector instanceof PDOConnector) {
101
            // Use a little bit of magic to replace the pdo instance
102
            $refObject = new ReflectionObject($connector);
103
            $refProperty = $refObject->getProperty('pdoConnection');
104
            $refProperty->setAccessible(true);
105
            $traceablePdo = new DebugBar\DataCollector\PDO\TraceablePDO($refProperty->getValue($connector));
106
            $refProperty->setValue($connector, $traceablePdo);
107
108
            $debugbar->addCollector(new DebugBar\DataCollector\PDO\PDOCollector($traceablePdo));
109
        } else {
110
            DB::set_conn($db = new DebugBarDatabaseNewProxy(DB::get_conn()));
111
            $db->setShowQueries(self::getShowQueries());
112
            $debugbar->addCollector(new DebugBarDatabaseCollector);
113
        }
114
115
        } else {
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_ELSE, expecting T_FUNCTION or T_CONST
Loading history...
116
            DB::set_conn($db = new DebugBarDatabaseNewProxy(DB::get_conn()));
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $db.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
117
            $db->setShowQueries(self::getShowQueries());
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $db.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
118
            $debugbar->addCollector(new DebugBarDatabaseCollector($db));
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
Coding Style introduced by
The visibility should be declared for property $debugbar.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
119
        }
120
121
        // Add message collector last so other collectors can send messages to the console using it
122
        $debugbar->addCollector(new DebugBar\DataCollector\MessagesCollector());
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $debugbar.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
123
124
        // Add some SilverStripe specific infos
125
        $debugbar->addCollector(new DebugBarSilverStripeCollector());
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $debugbar.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
126
127
        if (self::config()->enable_storage) {
128
            $debugbar->setStorage(new DebugBar\Storage\FileStorage(TEMP_FOLDER . '/debugbar'));
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $debugbar.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
129
        }
130
131
        // Since we buffer everything, why not enable all dev options ?
132
        if (self::config()->auto_debug) {
133
            $_REQUEST['debug'] = true;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_REQUEST.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
134
            $_REQUEST['debug_request'] = true;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_REQUEST.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
135
        }
136
137
        if (isset($_REQUEST['debug']) || isset($_REQUEST['debug_request'])) {
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
Coding Style introduced by
The visibility should be declared for property $_REQUEST.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
138
            self::$bufferingEnabled = true;
139
            ob_start(); // We buffer everything until we have called an action
140
        }
141
142
        return $debugbar;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $debugbar.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
143
    }
144
145
    public static function clearDebugBar()
146
    {
147
        self::$debugbar = null;
148
    }
149
150
    public static function getShowQueries()
151
    {
152
        return self::$showQueries;
153
    }
154
155
    public static function setShowQueries($showQueries)
156
    {
157
        self::$showQueries = $showQueries;
158
    }
159
160
    public static function includeRequirements()
161
    {
162
        $debugbar = self::getDebugBar();
163
164
        if (!$debugbar) {
165
            return;
166
        }
167
168
        // Already called
169
        if (self::$renderer) {
170
            return;
171
        }
172
173
        $renderer = $debugbar->getJavascriptRenderer();
174
175
        // We don't need the true path since we are going to use Requirements API that appends the BASE_PATH
176
        $renderer->setBasePath(DEBUGBAR_DIR . '/assets');
177
        $renderer->setBaseUrl(DEBUGBAR_DIR . '/assets');
178
179
        $includeJquery = self::config()->include_jquery;
180
        // In CMS, jQuery is already included
181
        if (self::isAdminController()) {
182
            $includeJquery = false;
183
        }
184
        // If jQuery is already included, set to false
185
        $js = Requirements::backend()->get_javascript();
186
        foreach ($js as $url) {
187
            $name = basename($url);
188
            if ($name == 'jquery.js' || $name == 'jquery.min.js') {
189
                $includeJquery = false;
190
                break;
191
            }
192
        }
193
194
        if ($includeJquery) {
195
            $renderer->setEnableJqueryNoConflict(true);
196
        } else {
197
            $renderer->disableVendor('jquery');
198
            $renderer->setEnableJqueryNoConflict(false);
199
        }
200
201
        if (DebugBar::config()->enable_storage) {
202
            $renderer->setOpenHandlerUrl('__debugbar');
203
        }
204
205
        foreach ($renderer->getAssets('css') as $cssFile) {
206
            Requirements::css(ltrim($cssFile, '/'));
207
        }
208
209
        foreach ($renderer->getAssets('js') as $jsFile) {
210
            Requirements::javascript(ltrim($jsFile, '/'));
211
        }
212
213
        self::$renderer = $renderer;
214
    }
215
216
    public static function renderDebugBar()
217
    {
218
        if (!self::$renderer) {
219
            return;
220
        }
221
222
        // Requirements may have been cleared (CMS iframes...) or not set (Security...)
223
        $js = Requirements::backend()->get_javascript();
224
        if (!in_array('debugbar/assets/debugbar.js', $js)) {
225
            return;
226
        }
227
        $initialize = true;
228
        if (Director::is_ajax()) {
229
            $initialize = false;
230
        }
231
232
        $script = self::$renderer->render($initialize);
233
        return $script;
234
    }
235
236
    /**
237
     * Determine why DebugBar is disabled
238
     *
239
     * @return string
240
     */
241
    public static function whyDisabled()
242
    {
243
        if (!Director::isDev()) {
244
            return 'Not in dev mode';
245
        }
246
        if (self::isDisabled()) {
247
            return 'Disabled by a constant or configuration';
248
        }
249
        if (self::vendorNotInstalled()) {
250
            return 'DebugBar is not installed in vendors';
251
        }
252
        if (self::notLocalIp()) {
253
            return 'Not a local ip';
254
        }
255
        if (Director::is_cli()) {
256
            return 'In CLI mode';
257
        }
258
        if (self::isDevUrl()) {
259
            return 'Dev tools';
260
        }
261
        if (self::isAdminUrl() && !self::config()->enabled_in_admin) {
262
            return 'In admin';
263
        }
264
        return "I don't know why";
265
    }
266
267
    public static function vendorNotInstalled()
268
    {
269
        return !class_exists('DebugBar\\StandardDebugBar');
270
    }
271
272
    public static function notLocalIp()
273
    {
274
        if (!self::config()->check_local_ip) {
275
            return false;
276
        }
277
        if (isset($_SERVER['REMOTE_ADDR'])) {
278
            return !in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1', '1'));
279
        }
280
        return false;
281
    }
282
283
    public static function isDisabled()
284
    {
285
        if ((defined('DEBUGBAR_DISABLE') && DEBUGBAR_DISABLE) || static::config()->disabled) {
286
            return true;
287
        }
288
        return false;
289
    }
290
291
    public static function isDevUrl()
292
    {
293
        return strpos(self::getRequestUrl(), '/dev/') === 0;
294
    }
295
296
    public static function isAdminUrl()
297
    {
298
        return strpos(self::getRequestUrl(), '/admin/') === 0;
299
    }
300
301
    public static function isAdminController()
302
    {
303
        if (Controller::curr()) {
304
            return Controller::curr() instanceof LeftAndMain;
305
        }
306
        return self::isAdminUrl();
307
    }
308
309
    /**
310
     * Avoid triggering data collection for open handler
311
     *
312
     * @return boolean
313
     */
314
    public static function isDebugBarRequest()
315
    {
316
        if ($url = self::getRequestUrl()) {
317
            return strpos($url, '/__debugbar') === 0;
318
        }
319
        return true;
320
    }
321
322
    /**
323
     * Get request url
324
     *
325
     * @return string
326
     */
327
    public static function getRequestUrl()
328
    {
329
        if (isset($_REQUEST['url'])) {
330
            return $_REQUEST['url'];
331
        }
332
        if (isset($_SERVER['REQUEST_URI'])) {
333
            return $_SERVER['REQUEST_URI'];
334
        }
335
        return '';
336
    }
337
338
    /**
339
     * Helper to make code cleaner
340
     *
341
     * @param callable $callback
342
     */
343
    public static function withDebugBar($callback)
344
    {
345
        if (self::getDebugBar() && !self::isDebugBarRequest()) {
346
            $callback(self::getDebugBar());
347
        }
348
    }
349
}
350