| Total Complexity | 103 | 
| Total Lines | 619 | 
| Duplicated Lines | 0 % | 
| Changes | 12 | ||
| Bugs | 2 | Features | 0 | 
Complex classes like DebugBar often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use DebugBar, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 53 | class DebugBar  | 
            ||
| 54 | { | 
            ||
| 55 | use Configurable;  | 
            ||
| 56 | use Injectable;  | 
            ||
| 57 | |||
| 58 | /**  | 
            ||
| 59 | * @var BaseDebugBar  | 
            ||
| 60 | */  | 
            ||
| 61 | protected static $debugbar;  | 
            ||
| 62 | |||
| 63 | /**  | 
            ||
| 64 | * @var bool  | 
            ||
| 65 | */  | 
            ||
| 66 | public static $bufferingEnabled = false;  | 
            ||
| 67 | |||
| 68 | /**  | 
            ||
| 69 | * @var JavascriptRenderer  | 
            ||
| 70 | */  | 
            ||
| 71 | protected static $renderer;  | 
            ||
| 72 | |||
| 73 | /**  | 
            ||
| 74 | * @var bool  | 
            ||
| 75 | */  | 
            ||
| 76 | protected static $showQueries = false;  | 
            ||
| 77 | |||
| 78 | /**  | 
            ||
| 79 | * @var HTTPRequest  | 
            ||
| 80 | */  | 
            ||
| 81 | protected static $request;  | 
            ||
| 82 | |||
| 83 | /**  | 
            ||
| 84 | * @var array  | 
            ||
| 85 | */  | 
            ||
| 86 | protected static $extraTimes = [];  | 
            ||
| 87 | |||
| 88 | /**  | 
            ||
| 89 | * Get the Debug Bar instance  | 
            ||
| 90 | * @throws Exception  | 
            ||
| 91 | * @global array $databaseConfig  | 
            ||
| 92 | * @return BaseDebugBar  | 
            ||
| 93 | */  | 
            ||
| 94 | public static function getDebugBar()  | 
            ||
| 95 |     { | 
            ||
| 96 |         if (self::$debugbar !== null) { | 
            ||
| 97 | return self::$debugbar;  | 
            ||
| 98 | }  | 
            ||
| 99 | |||
| 100 | $reasons = self::disabledCriteria();  | 
            ||
| 101 |         if (!empty($reasons)) { | 
            ||
| 102 | self::$debugbar = false; // no need to check again  | 
            ||
| 
                                                                                                    
                        
                         | 
                |||
| 103 | return;  | 
            ||
| 104 | }  | 
            ||
| 105 | |||
| 106 | self::initDebugBar();  | 
            ||
| 107 | |||
| 108 |         if (!self::$debugbar) { | 
            ||
| 109 |             throw new Exception("Failed to initialize the DebugBar"); | 
            ||
| 110 | }  | 
            ||
| 111 | |||
| 112 | return self::$debugbar;  | 
            ||
| 113 | }  | 
            ||
| 114 | |||
| 115 | /**  | 
            ||
| 116 | * Init the debugbar instance  | 
            ||
| 117 | *  | 
            ||
| 118 | * @global array $databaseConfig  | 
            ||
| 119 | * @return BaseDebugBar|null  | 
            ||
| 120 | */  | 
            ||
| 121 | public static function initDebugBar()  | 
            ||
| 122 |     { | 
            ||
| 123 | // Prevent multiple inits  | 
            ||
| 124 |         if (self::$debugbar) { | 
            ||
| 125 | return self::$debugbar;  | 
            ||
| 126 | }  | 
            ||
| 127 | |||
| 128 | self::$debugbar = $debugbar = new BaseDebugBar();  | 
            ||
| 129 | |||
| 130 |         if (isset($_REQUEST['showqueries']) && Director::isDev()) { | 
            ||
| 131 | self::setShowQueries(true);  | 
            ||
| 132 | unset($_REQUEST['showqueries']);  | 
            ||
| 133 | }  | 
            ||
| 134 | |||
| 135 | $debugbar->addCollector(new PhpInfoCollector());  | 
            ||
| 136 | $debugbar->addCollector(new TimeDataCollector());  | 
            ||
| 137 | self::measureExtraTime();  | 
            ||
| 138 | $debugbar->addCollector(new MemoryCollector());  | 
            ||
| 139 | |||
| 140 | // Add config proxy replacing the core config manifest  | 
            ||
| 141 |         if (self::config()->config_collector) { | 
            ||
| 142 | /** @var ConfigLoader $configLoader */  | 
            ||
| 143 | $configLoader = Injector::inst()->get(Kernel::class)->getConfigLoader();  | 
            ||
| 144 | // There is no getManifests method on ConfigLoader  | 
            ||
| 145 | $manifests = self::getProtectedValue($configLoader, 'manifests');  | 
            ||
| 146 |             foreach ($manifests as $manifestIdx => $manifest) { | 
            ||
| 147 |                 if ($manifest instanceof CachedConfigCollection) { | 
            ||
| 148 | $manifest = new ConfigManifestProxy($manifest);  | 
            ||
| 149 | $manifests[$manifestIdx] = $manifest;  | 
            ||
| 150 | }  | 
            ||
| 151 |                 if ($manifest instanceof DeltaConfigCollection) { | 
            ||
| 152 | $manifest = DeltaConfigManifestProxy::createFromOriginal($manifest);  | 
            ||
| 153 | $manifests[$manifestIdx] = $manifest;  | 
            ||
| 154 | }  | 
            ||
| 155 | }  | 
            ||
| 156 | // Don't push as it may change stack order  | 
            ||
| 157 | self::setProtectedValue($configLoader, 'manifests', $manifests);  | 
            ||
| 158 | }  | 
            ||
| 159 | |||
| 160 |         if (self::config()->db_collector) { | 
            ||
| 161 | $connector = DB::get_connector();  | 
            ||
| 162 |             if (!self::config()->get('force_proxy') && $connector instanceof PDOConnector) { | 
            ||
| 163 | // Use a little bit of magic to replace the pdo instance  | 
            ||
| 164 | $refObject = new ReflectionObject($connector);  | 
            ||
| 165 |                 $refProperty = $refObject->getProperty('pdoConnection'); | 
            ||
| 166 | $refProperty->setAccessible(true);  | 
            ||
| 167 | $traceablePdo = new TraceablePDO($refProperty->getValue($connector));  | 
            ||
| 168 | $refProperty->setValue($connector, $traceablePdo);  | 
            ||
| 169 | |||
| 170 | $debugbar->addCollector(new PDOCollector($traceablePdo));  | 
            ||
| 171 |             } else { | 
            ||
| 172 | $debugbar->addCollector(new DatabaseCollector);  | 
            ||
| 173 | }  | 
            ||
| 174 | }  | 
            ||
| 175 | |||
| 176 | // Add message collector last so other collectors can send messages to the console using it  | 
            ||
| 177 | $debugbar->addCollector(new MessagesCollector());  | 
            ||
| 178 | |||
| 179 | // Aggregate monolog into messages  | 
            ||
| 180 | $logger = Injector::inst()->get(LoggerInterface::class);  | 
            ||
| 181 |         if ($logger instanceof Logger) { | 
            ||
| 182 | $logCollector = new MonologCollector($logger);  | 
            ||
| 183 | $logCollector->setFormatter(new LogFormatter);  | 
            ||
| 184 | $debugbar['messages']->aggregate($logCollector);  | 
            ||
| 185 | }  | 
            ||
| 186 | |||
| 187 | // Add some SilverStripe specific infos  | 
            ||
| 188 | $debugbar->addCollector(new SilverStripeCollector);  | 
            ||
| 189 | |||
| 190 |         if (self::config()->get('enable_storage')) { | 
            ||
| 191 | $debugBarTempFolder = TEMP_FOLDER . '/debugbar';  | 
            ||
| 192 | $debugbar->setStorage($fileStorage = new FileStorage($debugBarTempFolder));  | 
            ||
| 193 |             if (isset($_GET['flush']) && is_dir($debugBarTempFolder)) { | 
            ||
| 194 | // FileStorage::clear() is implemented with \DirectoryIterator which throws UnexpectedValueException if dir can not be opened  | 
            ||
| 195 | $fileStorage->clear();  | 
            ||
| 196 | }  | 
            ||
| 197 | }  | 
            ||
| 198 | |||
| 199 |         if (self::config()->config_collector) { | 
            ||
| 200 | // Add the config collector  | 
            ||
| 201 | $debugbar->addCollector(new ConfigCollector);  | 
            ||
| 202 | }  | 
            ||
| 203 | |||
| 204 | // Partial cache  | 
            ||
| 205 |         if (self::config()->partial_cache_collector) { | 
            ||
| 206 | $debugbar->addCollector(new PartialCacheCollector);  | 
            ||
| 207 | }  | 
            ||
| 208 | |||
| 209 | // Email logging  | 
            ||
| 210 |         if (self::config()->email_collector) { | 
            ||
| 211 | $mailer = Injector::inst()->get(Mailer::class);  | 
            ||
| 212 |             if ($mailer instanceof SwiftMailer) { | 
            ||
| 213 | $swiftInst = $mailer->getSwiftMailer();  | 
            ||
| 214 | $debugbar['messages']->aggregate(new SwiftLogCollector($swiftInst));  | 
            ||
| 215 | $debugbar->addCollector(new SwiftMailCollector($swiftInst));  | 
            ||
| 216 | }  | 
            ||
| 217 | }  | 
            ||
| 218 | |||
| 219 | // Since we buffer everything, why not enable all dev options ?  | 
            ||
| 220 |         if (self::config()->get('auto_debug')) { | 
            ||
| 221 | $_REQUEST['debug'] = true;  | 
            ||
| 222 | $_REQUEST['debug_request'] = true;  | 
            ||
| 223 | }  | 
            ||
| 224 | |||
| 225 |         if (isset($_REQUEST['debug']) || isset($_REQUEST['debug_request'])) { | 
            ||
| 226 | self::$bufferingEnabled = true;  | 
            ||
| 227 | ob_start(); // We buffer everything until we have called an action  | 
            ||
| 228 | }  | 
            ||
| 229 | |||
| 230 | return $debugbar;  | 
            ||
| 231 | }  | 
            ||
| 232 | |||
| 233 | /**  | 
            ||
| 234 | * Access a protected property when the api does not allow access  | 
            ||
| 235 | *  | 
            ||
| 236 | * @param object $object  | 
            ||
| 237 | * @param string $property  | 
            ||
| 238 | * @return mixed  | 
            ||
| 239 | */  | 
            ||
| 240 | protected static function getProtectedValue($object, $property)  | 
            ||
| 241 |     { | 
            ||
| 242 | $refObject = new ReflectionObject($object);  | 
            ||
| 243 | $refProperty = $refObject->getProperty($property);  | 
            ||
| 244 | $refProperty->setAccessible(true);  | 
            ||
| 245 | return $refProperty->getValue($object);  | 
            ||
| 246 | }  | 
            ||
| 247 | |||
| 248 | /**  | 
            ||
| 249 | * Set a protected property when the api does not allow access  | 
            ||
| 250 | *  | 
            ||
| 251 | * @param object $object  | 
            ||
| 252 | * @param string $property  | 
            ||
| 253 | * @param mixed $newValue  | 
            ||
| 254 | * @return void  | 
            ||
| 255 | */  | 
            ||
| 256 | protected static function setProtectedValue($object, $property, $newValue)  | 
            ||
| 257 |     { | 
            ||
| 258 | $refObject = new ReflectionObject($object);  | 
            ||
| 259 | $refProperty = $refObject->getProperty($property);  | 
            ||
| 260 | $refProperty->setAccessible(true);  | 
            ||
| 261 | return $refProperty->setValue($object, $newValue);  | 
            ||
| 262 | }  | 
            ||
| 263 | |||
| 264 | /**  | 
            ||
| 265 | * Clear the current instance of DebugBar  | 
            ||
| 266 | *  | 
            ||
| 267 | * @return void  | 
            ||
| 268 | */  | 
            ||
| 269 | public static function clearDebugBar()  | 
            ||
| 270 |     { | 
            ||
| 271 | self::$debugbar = null;  | 
            ||
| 272 | self::$bufferingEnabled = false;  | 
            ||
| 273 | self::$renderer = null;  | 
            ||
| 274 | self::$showQueries = false;  | 
            ||
| 275 | self::$request = null;  | 
            ||
| 276 | self::$extraTimes = [];  | 
            ||
| 277 | ProxyDBExtension::resetQueries();  | 
            ||
| 278 | }  | 
            ||
| 279 | |||
| 280 | /**  | 
            ||
| 281 | * @return boolean  | 
            ||
| 282 | */  | 
            ||
| 283 | public static function getShowQueries()  | 
            ||
| 284 |     { | 
            ||
| 285 | return self::$showQueries;  | 
            ||
| 286 | }  | 
            ||
| 287 | |||
| 288 | /**  | 
            ||
| 289 | * Override default showQueries mode  | 
            ||
| 290 | *  | 
            ||
| 291 | * @param boolean $showQueries  | 
            ||
| 292 | * @return void  | 
            ||
| 293 | */  | 
            ||
| 294 | public static function setShowQueries($showQueries)  | 
            ||
| 295 |     { | 
            ||
| 296 | self::$showQueries = $showQueries;  | 
            ||
| 297 | }  | 
            ||
| 298 | |||
| 299 | /**  | 
            ||
| 300 | * Helper to access this module resources  | 
            ||
| 301 | *  | 
            ||
| 302 | * @param string $path  | 
            ||
| 303 | * @return ModuleResource  | 
            ||
| 304 | */  | 
            ||
| 305 | public static function moduleResource($path)  | 
            ||
| 306 |     { | 
            ||
| 307 |         return ModuleLoader::getModule('lekoala/silverstripe-debugbar')->getResource($path); | 
            ||
| 308 | }  | 
            ||
| 309 | |||
| 310 | /**  | 
            ||
| 311 | * Include DebugBar assets using Requirements API  | 
            ||
| 312 | *  | 
            ||
| 313 | * @return void  | 
            ||
| 314 | */  | 
            ||
| 315 | public static function includeRequirements()  | 
            ||
| 370 | }  | 
            ||
| 371 | |||
| 372 | /**  | 
            ||
| 373 | * Returns the script to display the DebugBar  | 
            ||
| 374 | *  | 
            ||
| 375 | * @return string  | 
            ||
| 376 | */  | 
            ||
| 377 | public static function renderDebugBar()  | 
            ||
| 378 |     { | 
            ||
| 379 |         if (!self::$renderer) { | 
            ||
| 380 | return;  | 
            ||
| 381 | }  | 
            ||
| 382 | |||
| 383 | // If we have any extra time pending, add it  | 
            ||
| 384 |         if (!empty(self::$extraTimes)) { | 
            ||
| 385 |             foreach (self::$extraTimes as $extraTime => $extraTimeData) { | 
            ||
| 386 | self::trackTime($extraTime);  | 
            ||
| 387 | }  | 
            ||
| 388 | }  | 
            ||
| 389 | |||
| 390 | // Requirements may have been cleared (CMS iframes...) or not set (Security...)  | 
            ||
| 391 | $js = Requirements::backend()->getJavascript();  | 
            ||
| 392 |         $debugBarResource = self::moduleResource('assets/debugbar.js'); | 
            ||
| 393 | $path = $debugBarResource->getRelativePath();  | 
            ||
| 394 | |||
| 395 | // Url in getJavascript has a / slash, so fix if necessary  | 
            ||
| 396 |         $path = str_replace("assets\\debugbar.js", "assets/debugbar.js", $path); | 
            ||
| 397 |         if (!array_key_exists($path, $js)) { | 
            ||
| 398 | return;  | 
            ||
| 399 | }  | 
            ||
| 400 | $initialize = true;  | 
            ||
| 401 |         if (Director::is_ajax()) { | 
            ||
| 402 | $initialize = false;  | 
            ||
| 403 | }  | 
            ||
| 404 | |||
| 405 | $script = self::$renderer->render($initialize);  | 
            ||
| 406 | return $script;  | 
            ||
| 407 | }  | 
            ||
| 408 | |||
| 409 | /**  | 
            ||
| 410 | * Get all criteria why the DebugBar could be disabled  | 
            ||
| 411 | *  | 
            ||
| 412 | * @return array  | 
            ||
| 413 | */  | 
            ||
| 414 | public static function disabledCriteria()  | 
            ||
| 415 |     { | 
            ||
| 416 | $reasons = array();  | 
            ||
| 417 |         if (self::onlyInDevMode() && Director::isDev()) { | 
            ||
| 418 | $reasons[] = 'Not in dev mode';  | 
            ||
| 419 | }  | 
            ||
| 420 |         if (self::isDisabled()) { | 
            ||
| 421 | $reasons[] = 'Disabled by a constant or configuration';  | 
            ||
| 422 | }  | 
            ||
| 423 |         if (self::vendorNotInstalled()) { | 
            ||
| 424 | $reasons[] = 'DebugBar is not installed in vendors';  | 
            ||
| 425 | }  | 
            ||
| 426 |         if (self::notLocalIp()) { | 
            ||
| 427 | $reasons[] = 'Not a local ip';  | 
            ||
| 428 | }  | 
            ||
| 429 |         if (Director::is_cli()) { | 
            ||
| 430 | $reasons[] = 'In CLI mode';  | 
            ||
| 431 | }  | 
            ||
| 432 |         if (self::isDevUrl()) { | 
            ||
| 433 | $reasons[] = 'Dev tools';  | 
            ||
| 434 | }  | 
            ||
| 435 |         if (self::isAdminUrl() && !self::config()->get('enabled_in_admin')) { | 
            ||
| 436 | $reasons[] = 'In admin';  | 
            ||
| 437 | }  | 
            ||
| 438 |         if (isset($_GET['CMSPreview'])) { | 
            ||
| 439 | $reasons[] = 'CMS Preview';  | 
            ||
| 440 | }  | 
            ||
| 441 | return $reasons;  | 
            ||
| 442 | }  | 
            ||
| 443 | |||
| 444 | /**  | 
            ||
| 445 | * Determine why DebugBar is disabled  | 
            ||
| 446 | *  | 
            ||
| 447 | * Deprecated in favor of disabledCriteria  | 
            ||
| 448 | *  | 
            ||
| 449 | * @return string  | 
            ||
| 450 | */  | 
            ||
| 451 | public static function whyDisabled()  | 
            ||
| 452 |     { | 
            ||
| 453 | $reasons = self::disabledCriteria();  | 
            ||
| 454 |         if (!empty($reasons)) { | 
            ||
| 455 | return $reasons[0];  | 
            ||
| 456 | }  | 
            ||
| 457 | return "I don't know why";  | 
            ||
| 458 | }  | 
            ||
| 459 | |||
| 460 | public static function vendorNotInstalled()  | 
            ||
| 461 |     { | 
            ||
| 462 |         return !class_exists('DebugBar\\StandardDebugBar'); | 
            ||
| 463 | }  | 
            ||
| 464 | |||
| 465 | public static function notLocalIp()  | 
            ||
| 474 | }  | 
            ||
| 475 | |||
| 476 | public static function onlyInDevMode()  | 
            ||
| 477 |     { | 
            ||
| 478 | // You will also need to add a debugbar-live config  | 
            ||
| 479 |         if (Environment::getEnv('DEBUGBAR_DISABLE_ONLY_DEV')) { | 
            ||
| 480 | return false;  | 
            ||
| 481 | }  | 
            ||
| 482 | return true;  | 
            ||
| 483 | }  | 
            ||
| 484 | |||
| 485 | public static function isDisabled()  | 
            ||
| 486 |     { | 
            ||
| 487 |         if (Environment::getEnv('DEBUGBAR_DISABLE') || static::config()->get('disabled')) { | 
            ||
| 488 | return true;  | 
            ||
| 489 | }  | 
            ||
| 490 | return false;  | 
            ||
| 491 | }  | 
            ||
| 492 | |||
| 493 | public static function isDevUrl()  | 
            ||
| 494 |     { | 
            ||
| 495 | return strpos(self::getRequestUrl(), '/dev/') === 0;  | 
            ||
| 496 | }  | 
            ||
| 497 | |||
| 498 | public static function isAdminUrl()  | 
            ||
| 499 |     { | 
            ||
| 500 | $baseUrl = rtrim(BASE_URL, '/');  | 
            ||
| 501 |         if (class_exists(AdminRootController::class)) { | 
            ||
| 502 |             $adminUrl = AdminRootController::config()->get('url_base'); | 
            ||
| 503 |         } else { | 
            ||
| 504 | $adminUrl = 'admin';  | 
            ||
| 505 | }  | 
            ||
| 506 | |||
| 507 | return strpos(self::getRequestUrl(), $baseUrl . '/' . $adminUrl . '/') === 0;  | 
            ||
| 508 | }  | 
            ||
| 509 | |||
| 510 | public static function isAdminController()  | 
            ||
| 516 | }  | 
            ||
| 517 | |||
| 518 | /**  | 
            ||
| 519 | * Avoid triggering data collection for open handler  | 
            ||
| 520 | *  | 
            ||
| 521 | * @return boolean  | 
            ||
| 522 | */  | 
            ||
| 523 | public static function isDebugBarRequest()  | 
            ||
| 524 |     { | 
            ||
| 525 |         if ($url = self::getRequestUrl()) { | 
            ||
| 526 | return strpos($url, '/__debugbar') === 0;  | 
            ||
| 527 | }  | 
            ||
| 528 | return true;  | 
            ||
| 529 | }  | 
            ||
| 530 | |||
| 531 | /**  | 
            ||
| 532 | * Get request url  | 
            ||
| 533 | *  | 
            ||
| 534 | * @return string  | 
            ||
| 535 | */  | 
            ||
| 536 | public static function getRequestUrl()  | 
            ||
| 537 |     { | 
            ||
| 538 |         if (isset($_REQUEST['url'])) { | 
            ||
| 539 | return $_REQUEST['url'];  | 
            ||
| 540 | }  | 
            ||
| 541 |         if (isset($_SERVER['REQUEST_URI'])) { | 
            ||
| 542 | return $_SERVER['REQUEST_URI'];  | 
            ||
| 543 | }  | 
            ||
| 544 | return '';  | 
            ||
| 545 | }  | 
            ||
| 546 | |||
| 547 | /**  | 
            ||
| 548 | * Helper to make code cleaner  | 
            ||
| 549 | *  | 
            ||
| 550 | * @param callable $callback  | 
            ||
| 551 | */  | 
            ||
| 552 | public static function withDebugBar($callback)  | 
            ||
| 553 |     { | 
            ||
| 554 |         if (self::getDebugBar() && !self::isDebugBarRequest()) { | 
            ||
| 555 | $callback(self::getDebugBar());  | 
            ||
| 556 | }  | 
            ||
| 557 | }  | 
            ||
| 558 | |||
| 559 | /**  | 
            ||
| 560 | * Set the current request. Is provided by the DebugBarMiddleware.  | 
            ||
| 561 | *  | 
            ||
| 562 | * @param HTTPRequest $request  | 
            ||
| 563 | */  | 
            ||
| 564 | public static function setRequest(HTTPRequest $request)  | 
            ||
| 565 |     { | 
            ||
| 566 | self::$request = $request;  | 
            ||
| 567 | }  | 
            ||
| 568 | |||
| 569 | /**  | 
            ||
| 570 | * Get the current request  | 
            ||
| 571 | *  | 
            ||
| 572 | * @return HTTPRequest  | 
            ||
| 573 | */  | 
            ||
| 574 | public static function getRequest()  | 
            ||
| 575 |     { | 
            ||
| 576 |         if (self::$request) { | 
            ||
| 577 | return self::$request;  | 
            ||
| 578 | }  | 
            ||
| 579 | // Fall back to trying from the global state  | 
            ||
| 580 |         if (Controller::has_curr()) { | 
            ||
| 581 | return Controller::curr()->getRequest();  | 
            ||
| 582 | }  | 
            ||
| 583 | }  | 
            ||
| 584 | |||
| 585 | /**  | 
            ||
| 586 | * @return TimeDataCollector|false  | 
            ||
| 587 | */  | 
            ||
| 588 | public static function getTimeCollector()  | 
            ||
| 589 |     { | 
            ||
| 590 | $debugbar = self::getDebugBar();  | 
            ||
| 591 |         if (!$debugbar) { | 
            ||
| 592 | return false;  | 
            ||
| 593 | }  | 
            ||
| 594 |         return $debugbar->getCollector('time'); | 
            ||
| 595 | }  | 
            ||
| 596 | |||
| 597 | /**  | 
            ||
| 598 | * @return MessagesCollector|false  | 
            ||
| 599 | */  | 
            ||
| 600 | public static function getMessageCollector()  | 
            ||
| 601 |     { | 
            ||
| 602 | $debugbar = self::getDebugBar();  | 
            ||
| 603 |         if (!$debugbar) { | 
            ||
| 604 | return false;  | 
            ||
| 605 | }  | 
            ||
| 606 |         return  $debugbar->getCollector('messages'); | 
            ||
| 607 | }  | 
            ||
| 608 | |||
| 609 | /**  | 
            ||
| 610 | * Start/stop time tracking (also before init)  | 
            ||
| 611 | *  | 
            ||
| 612 | * @param string $label  | 
            ||
| 613 | * @return void  | 
            ||
| 614 | */  | 
            ||
| 615 | public static function trackTime($label)  | 
            ||
| 616 |     { | 
            ||
| 617 |         if (!isset(self::$extraTimes[$label])) { | 
            ||
| 618 | self::$extraTimes[$label] = [microtime(true)];  | 
            ||
| 619 |         } else { | 
            ||
| 620 | self::$extraTimes[$label][] = microtime(true);  | 
            ||
| 621 | |||
| 622 | // If we have the debugbar instance, add the measure  | 
            ||
| 623 |             if (self::$debugbar) { | 
            ||
| 624 | $timeData = self::getTimeCollector();  | 
            ||
| 625 |                 if (!$timeData) { | 
            ||
| 626 | return;  | 
            ||
| 627 | }  | 
            ||
| 628 | $values = self::$extraTimes[$label];  | 
            ||
| 629 | $timeData->addMeasure(  | 
            ||
| 630 | $label,  | 
            ||
| 631 | $values[0],  | 
            ||
| 632 | $values[1]  | 
            ||
| 633 | );  | 
            ||
| 634 | unset(self::$extraTimes[$label]);  | 
            ||
| 635 | }  | 
            ||
| 636 | }  | 
            ||
| 637 | }  | 
            ||
| 638 | |||
| 639 | /**  | 
            ||
| 640 | * Close any open extra time record  | 
            ||
| 641 | *  | 
            ||
| 642 | * @return void  | 
            ||
| 643 | */  | 
            ||
| 644 | public static function closeExtraTime()  | 
            ||
| 645 |     { | 
            ||
| 646 |         foreach (self::$extraTimes as $label => $values) { | 
            ||
| 647 |             if (!isset($values[1])) { | 
            ||
| 648 | self::$extraTimes[$label][] = microtime(true);  | 
            ||
| 649 | }  | 
            ||
| 650 | }  | 
            ||
| 651 | }  | 
            ||
| 652 | |||
| 653 | /**  | 
            ||
| 654 | * Add extra time to time collector  | 
            ||
| 655 | */  | 
            ||
| 656 | public static function measureExtraTime()  | 
            ||
| 672 | }  | 
            ||
| 673 | }  | 
            ||
| 674 | }  | 
            ||
| 675 | 
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..