Server IP : 103.191.208.50 / Your IP : 216.73.216.53 Web Server : LiteSpeed System : Linux orion.herosite.pro 4.18.0-553.53.1.lve.el8.x86_64 #1 SMP Wed May 28 17:01:02 UTC 2025 x86_64 User : celkcksm ( 1031) PHP Version : 7.4.33 Disable Function : show_source, system, shell_exec, passthru, popen, exec MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON Directory (0755) : /home/celkcksm/hrms.ncriptech.com/vendor/barryvdh/laravel-debugbar/src/ |
[ Home ] | [ C0mmand ] | [ Upload File ] |
---|
<?php namespace Barryvdh\Debugbar; use Barryvdh\Debugbar\DataCollector\CacheCollector; use Barryvdh\Debugbar\DataCollector\EventCollector; use Barryvdh\Debugbar\DataCollector\FilesCollector; use Barryvdh\Debugbar\DataCollector\GateCollector; use Barryvdh\Debugbar\DataCollector\LaravelCollector; use Barryvdh\Debugbar\DataCollector\LivewireCollector; use Barryvdh\Debugbar\DataCollector\LogsCollector; use Barryvdh\Debugbar\DataCollector\MultiAuthCollector; use Barryvdh\Debugbar\DataCollector\PennantCollector; use Barryvdh\Debugbar\DataCollector\QueryCollector; use Barryvdh\Debugbar\DataCollector\SessionCollector; use Barryvdh\Debugbar\DataCollector\RequestCollector; use Barryvdh\Debugbar\DataCollector\RouteCollector; use Barryvdh\Debugbar\DataCollector\ViewCollector; use Barryvdh\Debugbar\DataFormatter\QueryFormatter; use Barryvdh\Debugbar\Storage\SocketStorage; use Barryvdh\Debugbar\Storage\FilesystemStorage; use Barryvdh\Debugbar\Support\Clockwork\ClockworkCollector; use DebugBar\Bridge\MonologCollector; use DebugBar\Bridge\Symfony\SymfonyMailCollector; use DebugBar\DataCollector\ConfigCollector; use DebugBar\DataCollector\DataCollectorInterface; use DebugBar\DataCollector\ExceptionsCollector; use DebugBar\DataCollector\MemoryCollector; use DebugBar\DataCollector\MessagesCollector; use DebugBar\DataCollector\ObjectCountCollector; use DebugBar\DataCollector\PhpInfoCollector; use DebugBar\DataCollector\RequestDataCollector; use DebugBar\DataCollector\TimeDataCollector; use DebugBar\DebugBar; use DebugBar\HttpDriverInterface; use DebugBar\PhpHttpDriver; use DebugBar\Storage\PdoStorage; use DebugBar\Storage\RedisStorage; use Exception; use Illuminate\Contracts\Foundation\Application; use Illuminate\Mail\Events\MessageSent; use Illuminate\Session\SessionManager; use Illuminate\Support\Str; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Mailer\Envelope; use Symfony\Component\Mailer\SentMessage; use Symfony\Component\Mailer\Transport\AbstractTransport; use Symfony\Component\Mime\RawMessage; use Throwable; /** * Debug bar subclass which adds all without Request and with LaravelCollector. * Rest is added in Service Provider * * @method void emergency(...$message) * @method void alert(...$message) * @method void critical(...$message) * @method void error(...$message) * @method void warning(...$message) * @method void notice(...$message) * @method void info(...$message) * @method void debug(...$message) * @method void log(...$message) */ class LaravelDebugbar extends DebugBar { /** * The Laravel application instance. * * @var \Illuminate\Foundation\Application */ protected $app; /** * Normalized Laravel Version * * @var string */ protected $version; /** * True when booted. * * @var bool */ protected $booted = false; /** * True when enabled, false disabled on null for still unknown * * @var bool */ protected $enabled = null; /** * True when this is a Lumen application * * @var bool */ protected $is_lumen = false; protected ?string $editorTemplateLink = null; protected array $remoteServerReplacements = []; protected bool $responseIsModified = false; protected array $stackedData = []; /** * @param Application $app */ public function __construct($app = null) { if (!$app) { $app = app(); //Fallback when $app is not given } $this->app = $app; $this->version = $app->version(); $this->is_lumen = Str::contains($this->version, 'Lumen'); if ($this->is_lumen) { $this->version = Str::betweenFirst($app->version(), '(', ')'); } } /** * Returns the HTTP driver * * If no http driver where defined, a PhpHttpDriver is automatically created * * @return HttpDriverInterface */ public function getHttpDriver() { if ($this->httpDriver === null) { $this->httpDriver = $this->app->make(SymfonyHttpDriver::class); } return $this->httpDriver; } /** * Enable the Debugbar and boot, if not already booted. */ public function enable() { $this->enabled = true; if (!$this->booted) { $this->boot(); } } /** * Boot the debugbar (add collectors, renderer and listener) */ public function boot() { if ($this->booted) { return; } /** @var Application $app */ $app = $this->app; /** @var \Illuminate\Config\Repository $config */ $config = $app['config']; /** @var \Illuminate\Events\Dispatcher|null $events */ $events = isset($app['events']) ? $app['events'] : null; $this->editorTemplateLink = $config->get('debugbar.editor') ?: null; $this->remoteServerReplacements = $this->getRemoteServerReplacements(); // Set custom error handler if ($config->get('debugbar.error_handler', false)) { set_error_handler([$this, 'handleError']); } $this->selectStorage($this); if ($this->shouldCollect('phpinfo', true)) { $this->addCollector(new PhpInfoCollector()); } if ($this->shouldCollect('messages', true)) { $this->addCollector(new MessagesCollector()); if ($config->get('debugbar.options.messages.trace', true)) { $this['messages']->collectFileTrace(true); } } if ($this->shouldCollect('time', true)) { $startTime = $app['request']->server('REQUEST_TIME_FLOAT'); $this->addCollector(new TimeDataCollector($startTime)); if ($config->get('debugbar.options.time.memory_usage')) { $this['time']->showMemoryUsage(); } if (! $this->isLumen() && $startTime) { $app->booted( function () use ($startTime) { $this->addMeasure('Booting', $startTime, microtime(true), [], 'time'); } ); } $this->startMeasure('application', 'Application', 'time'); } if ($this->shouldCollect('memory', true)) { $this->addCollector(new MemoryCollector()); $this['memory']->setPrecision($config->get('debugbar.options.memory.precision', 0)); if (function_exists('memory_reset_peak_usage') && $config->get('debugbar.options.memory.reset_peak')) { memory_reset_peak_usage(); } if ($config->get('debugbar.options.memory.with_baseline')) { $this['memory']->resetMemoryBaseline(); } } if ($this->shouldCollect('exceptions', true)) { try { $this->addCollector(new ExceptionsCollector()); $this['exceptions']->setChainExceptions( $config->get('debugbar.options.exceptions.chain', true) ); } catch (Exception $e) { } } if ($this->shouldCollect('laravel', false)) { $this->addCollector(new LaravelCollector($app)); } if ($this->shouldCollect('default_request', false)) { $this->addCollector(new RequestDataCollector()); } if ($this->shouldCollect('events', false) && $events) { try { $startTime = $app['request']->server('REQUEST_TIME_FLOAT'); $collectData = $config->get('debugbar.options.events.data', false); $this->addCollector(new EventCollector($startTime, $collectData)); $events->subscribe($this['event']); } catch (Exception $e) { $this->addCollectorException('Cannot add EventCollector', $e); } } if ($this->shouldCollect('views', true) && $events) { try { $collectData = $config->get('debugbar.options.views.data', true); $excludePaths = $config->get('debugbar.options.views.exclude_paths', []); $group = $config->get('debugbar.options.views.group', true); $this->addCollector(new ViewCollector($collectData, $excludePaths, $group)); $events->listen( 'composing:*', function ($event, $params) { $this['views']->addView($params[0]); } ); } catch (Exception $e) { $this->addCollectorException('Cannot add ViewCollector', $e); } } if (!$this->isLumen() && $this->shouldCollect('route')) { try { $this->addCollector($app->make(RouteCollector::class)); } catch (Exception $e) { $this->addCollectorException('Cannot add RouteCollector', $e); } } if (!$this->isLumen() && $this->shouldCollect('log', true)) { try { if ($this->hasCollector('messages')) { $logger = new MessagesCollector('log'); $this['messages']->aggregate($logger); $app['log']->listen( function (\Illuminate\Log\Events\MessageLogged $log) use ($logger) { try { $logMessage = (string) $log->message; if (mb_check_encoding($logMessage, 'UTF-8')) { $context = $log->context; $logMessage .= (!empty($context) ? ' ' . json_encode($context, JSON_PRETTY_PRINT) : ''); } else { $logMessage = "[INVALID UTF-8 DATA]"; } } catch (Exception $e) { $logMessage = "[Exception: " . $e->getMessage() . "]"; } $logger->addMessage( '[' . date('H:i:s') . '] ' . "LOG.{$log->level}: " . $logMessage, $log->level, false ); } ); } else { $this->addCollector(new MonologCollector($this->getMonologLogger())); } } catch (Exception $e) { $this->addCollectorException('Cannot add LogsCollector', $e); } } if ($this->shouldCollect('db', true) && isset($app['db']) && $events) { if ($this->hasCollector('time') && $config->get('debugbar.options.db.timeline', false)) { $timeCollector = $this['time']; } else { $timeCollector = null; } $queryCollector = new QueryCollector($timeCollector); $queryCollector->setDataFormatter(new QueryFormatter()); $queryCollector->setLimits($config->get('debugbar.options.db.soft_limit'), $config->get('debugbar.options.db.hard_limit')); $queryCollector->setDurationBackground($config->get('debugbar.options.db.duration_background')); if ($config->get('debugbar.options.db.with_params')) { $queryCollector->setRenderSqlWithParams(true); } if ($dbBacktrace = $config->get('debugbar.options.db.backtrace')) { $middleware = ! $this->is_lumen ? $app['router']->getMiddleware() : []; $queryCollector->setFindSource($dbBacktrace, $middleware); } if ($excludePaths = $config->get('debugbar.options.db.exclude_paths')) { $queryCollector->mergeExcludePaths($excludePaths); } if ($excludeBacktracePaths = $config->get('debugbar.options.db.backtrace_exclude_paths')) { $queryCollector->mergeBacktraceExcludePaths($excludeBacktracePaths); } if ($config->get('debugbar.options.db.explain.enabled')) { $types = $config->get('debugbar.options.db.explain.types'); $queryCollector->setExplainSource(true, $types); } if ($config->get('debugbar.options.db.hints', true)) { $queryCollector->setShowHints(true); } if ($config->get('debugbar.options.db.show_copy', false)) { $queryCollector->setShowCopyButton(true); } $this->addCollector($queryCollector); try { $events->listen( function (\Illuminate\Database\Events\QueryExecuted $query) { if (!app(static::class)->shouldCollect('db', true)) { return; // Issue 776 : We've turned off collecting after the listener was attached } //allow collecting only queries slower than a specified amount of milliseconds $threshold = app('config')->get('debugbar.options.db.slow_threshold', false); if (!$threshold || $query->time > $threshold) { $this['queries']->addQuery($query); } } ); } catch (Exception $e) { $this->addCollectorException('Cannot listen to Queries', $e); } try { $events->listen( \Illuminate\Database\Events\TransactionBeginning::class, function ($transaction) { $this['queries']->collectTransactionEvent('Begin Transaction', $transaction->connection); } ); $events->listen( \Illuminate\Database\Events\TransactionCommitted::class, function ($transaction) { $this['queries']->collectTransactionEvent('Commit Transaction', $transaction->connection); } ); $events->listen( \Illuminate\Database\Events\TransactionRolledBack::class, function ($transaction) { $this['queries']->collectTransactionEvent('Rollback Transaction', $transaction->connection); } ); $events->listen( 'connection.*.beganTransaction', function ($event, $params) { $this['queries']->collectTransactionEvent('Begin Transaction', $params[0]); } ); $events->listen( 'connection.*.committed', function ($event, $params) { $this['queries']->collectTransactionEvent('Commit Transaction', $params[0]); } ); $events->listen( 'connection.*.rollingBack', function ($event, $params) { $this['queries']->collectTransactionEvent('Rollback Transaction', $params[0]); } ); $events->listen( function (\Illuminate\Database\Events\ConnectionEstablished $event) { $this['queries']->collectTransactionEvent('Connection Established', $event->connection); if (app('config')->get('debugbar.options.db.memory_usage')) { $event->connection->beforeExecuting(function () { $this['queries']->startMemoryUsage(); }); } } ); } catch (Exception $e) { $this->addCollectorException('Cannot listen transactions to Queries', $e); } } if ($this->shouldCollect('models', true) && $events) { try { $this->addCollector(new ObjectCountCollector('models')); $events->listen('eloquent.retrieved:*', function ($event, $models) { foreach (array_filter($models) as $model) { $this['models']->countClass($model); } }); } catch (Exception $e) { $this->addCollectorException('Cannot add Models Collector', $e); } } if ($this->shouldCollect('livewire', true) && $app->bound('livewire')) { try { $this->addCollector($app->make(LivewireCollector::class)); } catch (Exception $e) { $this->addCollectorException('Cannot add Livewire Collector', $e); } } if ($this->shouldCollect('mail', true) && class_exists('Illuminate\Mail\MailServiceProvider') && $events) { try { $mailCollector = new SymfonyMailCollector(); $this->addCollector($mailCollector); $events->listen(function (MessageSent $event) use ($mailCollector) { $mailCollector->addSymfonyMessage($event->sent->getSymfonySentMessage()); }); if ($config->get('debugbar.options.mail.show_body') || $config->get('debugbar.options.mail.full_log')) { $mailCollector->showMessageBody(); } if ($this->hasCollector('time') && $config->get('debugbar.options.mail.timeline')) { $transport = $app['mailer']->getSymfonyTransport(); $app['mailer']->setSymfonyTransport(new class ($transport, $this) extends AbstractTransport{ private $originalTransport; private $laravelDebugbar; public function __construct($transport, $laravelDebugbar) { $this->originalTransport = $transport; $this->laravelDebugbar = $laravelDebugbar; } public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage { return $this->laravelDebugbar['time']->measure( 'mail: ' . Str::limit($message->getSubject(), 100), function () use ($message, $envelope) { return $this->originalTransport->send($message, $envelope); }, 'mail' ); } protected function doSend(SentMessage $message): void { } public function __toString(): string { return $this->originalTransport->__toString(); } }); } } catch (Exception $e) { $this->addCollectorException('Cannot add SymfonyMailCollector', $e); } } if ($this->shouldCollect('logs', false)) { try { $file = $config->get('debugbar.options.logs.file'); $this->addCollector(new LogsCollector($file)); } catch (Exception $e) { $this->addCollectorException('Cannot add LogsCollector', $e); } } if ($this->shouldCollect('files', false)) { $this->addCollector(new FilesCollector($app)); } if ($this->shouldCollect('auth', false)) { try { $guards = $config->get('auth.guards', []); $this->addCollector(new MultiAuthCollector($app['auth'], $guards)); $this['auth']->setShowName( $config->get('debugbar.options.auth.show_name') ); $this['auth']->setShowGuardsData( $config->get('debugbar.options.auth.show_guards', true) ); } catch (Exception $e) { $this->addCollectorException('Cannot add AuthCollector', $e); } } if ($this->shouldCollect('gate', false)) { try { $this->addCollector($app->make(GateCollector::class)); } catch (Exception $e) { $this->addCollectorException('Cannot add GateCollector', $e); } } if ($this->shouldCollect('cache', false) && $events) { try { $collectValues = $config->get('debugbar.options.cache.values', true); $startTime = $app['request']->server('REQUEST_TIME_FLOAT'); $this->addCollector(new CacheCollector($startTime, $collectValues)); $events->subscribe($this['cache']); } catch (Exception $e) { $this->addCollectorException('Cannot add CacheCollector', $e); } } if ($this->shouldCollect('jobs', false) && $events) { try { $this->addCollector(new ObjectCountCollector('jobs', 'briefcase')); $events->listen(\Illuminate\Queue\Events\JobQueued::class, function ($event) { $this['jobs']->countClass($event->job); }); } catch (Exception $e) { $this->addCollectorException('Cannot add Jobs Collector', $e); } } if ($this->shouldCollect('pennant', false)) { if (class_exists('Laravel\Pennant\FeatureManager') && $app->bound(\Laravel\Pennant\FeatureManager::class)) { $featureManager = $app->make(\Laravel\Pennant\FeatureManager::class); try { $this->addCollector(new PennantCollector($featureManager)); } catch (Exception $e) { $this->addCollectorException('Cannot add PennantCollector', $e); } } } $renderer = $this->getJavascriptRenderer(); $renderer->setHideEmptyTabs($config->get('debugbar.hide_empty_tabs', false)); $renderer->setIncludeVendors($config->get('debugbar.include_vendors', true)); $renderer->setBindAjaxHandlerToFetch($config->get('debugbar.capture_ajax', true)); $renderer->setBindAjaxHandlerToXHR($config->get('debugbar.capture_ajax', true)); $this->booted = true; } public function shouldCollect($name, $default = false) { return $this->app['config']->get('debugbar.collectors.' . $name, $default); } /** * Adds a data collector * * @param DataCollectorInterface $collector * * @throws DebugBarException * @return $this */ public function addCollector(DataCollectorInterface $collector) { parent::addCollector($collector); if (method_exists($collector, 'useHtmlVarDumper')) { $collector->useHtmlVarDumper(); } if (method_exists($collector, 'setEditorLinkTemplate') && $this->editorTemplateLink) { $collector->setEditorLinkTemplate($this->editorTemplateLink); } if (method_exists($collector, 'addXdebugReplacements') && $this->remoteServerReplacements) { $collector->addXdebugReplacements($this->remoteServerReplacements); } return $this; } /** * Handle silenced errors * * @param $level * @param $message * @param string $file * @param int $line * @param array $context * @throws \ErrorException */ public function handleError($level, $message, $file = '', $line = 0, $context = []) { $exception = new \ErrorException($message, 0, $level, $file, $line); if (error_reporting() & $level) { throw $exception; } $this->addThrowable($exception); if ($this->hasCollector('messages')) { $file = $file ? ' on ' . $this['messages']->normalizeFilePath($file) . ":{$line}" : ''; $this['messages']->addMessage($message . $file, 'deprecation'); } } /** * Starts a measure * * @param string $name Internal name, used to stop the measure * @param string $label Public name * @param string|null $collector */ public function startMeasure($name, $label = null, $collector = null) { if ($this->hasCollector('time')) { /** @var \DebugBar\DataCollector\TimeDataCollector */ $time = $this->getCollector('time'); $time->startMeasure($name, $label, $collector); } } /** * Stops a measure * * @param string $name */ public function stopMeasure($name) { if ($this->hasCollector('time')) { /** @var \DebugBar\DataCollector\TimeDataCollector $collector */ $collector = $this->getCollector('time'); try { $collector->stopMeasure($name); } catch (Exception $e) { // $this->addThrowable($e); } } } /** * Adds an exception to be profiled in the debug bar * * @param Exception $e * @deprecated in favor of addThrowable */ public function addException(Exception $e) { return $this->addThrowable($e); } /** * Adds an exception to be profiled in the debug bar * * @param Throwable $e */ public function addThrowable($e) { if ($this->hasCollector('exceptions')) { /** @var \DebugBar\DataCollector\ExceptionsCollector $collector */ $collector = $this->getCollector('exceptions'); $collector->addThrowable($e); } } /** * Register collector exceptions * * @param string $message * @param Exception $exception */ protected function addCollectorException(string $message, Exception $exception) { $this->addThrowable( new Exception( $message . ' on Laravel Debugbar: ' . $exception->getMessage(), $exception->getCode(), $exception ) ); } /** * Returns a JavascriptRenderer for this instance * * @param string $baseUrl * @param string $basePath * @return JavascriptRenderer */ public function getJavascriptRenderer($baseUrl = null, $basePath = null) { if ($this->jsRenderer === null) { $this->jsRenderer = new JavascriptRenderer($this, $baseUrl, $basePath); } return $this->jsRenderer; } /** * Modify the response and inject the debugbar (or data in headers) * * @param \Symfony\Component\HttpFoundation\Request $request * @param \Symfony\Component\HttpFoundation\Response $response * @return \Symfony\Component\HttpFoundation\Response */ public function modifyResponse(Request $request, Response $response) { /** @var Application $app */ $app = $this->app; if (!$this->isEnabled() || !$this->booted || $this->isDebugbarRequest() || $this->responseIsModified) { return $response; } // Prevent duplicate modification $this->responseIsModified = true; // Set the Response if required $httpDriver = $this->getHttpDriver(); if ($httpDriver instanceof SymfonyHttpDriver) { $httpDriver->setResponse($response); } // Show the Http Response Exception in the Debugbar, when available if (isset($response->exception)) { $this->addThrowable($response->exception); } if ($this->shouldCollect('config', false)) { try { $configCollector = new ConfigCollector(); $configCollector->setData($app['config']->all()); $this->addCollector($configCollector); } catch (Exception $e) { $this->addCollectorException('Cannot add ConfigCollector', $e); } } $sessionHiddens = $app['config']->get('debugbar.options.session.hiddens', []); if ($app->bound(SessionManager::class)) { /** @var \Illuminate\Session\SessionManager $sessionManager */ $sessionManager = $app->make(SessionManager::class); if ($this->shouldCollect('session') && ! $this->hasCollector('session')) { try { $this->addCollector(new SessionCollector($sessionManager, $sessionHiddens)); } catch (Exception $e) { $this->addCollectorException('Cannot add SessionCollector', $e); } } } else { $sessionManager = null; } $requestHiddens = array_merge( $app['config']->get('debugbar.options.symfony_request.hiddens', []), array_map(fn ($key) => 'session_attributes.' . $key, $sessionHiddens) ); if ($this->shouldCollect('symfony_request', true) && !$this->hasCollector('request')) { try { $reqId = $this->getCurrentRequestId(); $this->addCollector(new RequestCollector($request, $response, $sessionManager, $reqId, $requestHiddens)); } catch (Exception $e) { $this->addCollectorException('Cannot add SymfonyRequestCollector', $e); } } if ($app['config']->get('debugbar.clockwork') && ! $this->hasCollector('clockwork')) { try { $this->addCollector(new ClockworkCollector($request, $response, $sessionManager, $requestHiddens)); } catch (Exception $e) { $this->addCollectorException('Cannot add ClockworkCollector', $e); } $this->addClockworkHeaders($response); } try { if ($this->hasCollector('views') && $response->headers->has('X-Inertia')) { $content = $response->getContent(); if (is_string($content)) { $content = json_decode($content, true); } if (is_array($content)) { $this['views']->addInertiaAjaxView($content); } } } catch (Exception $e) { } if ($app['config']->get('debugbar.add_ajax_timing', false)) { $this->addServerTimingHeaders($response); } if ($response->isRedirection()) { try { $this->stackData(); } catch (Exception $e) { $app['log']->error('Debugbar exception: ' . $e->getMessage()); } return $response; } try { // Collect + store data, only inject the ID in theheaders $this->sendDataInHeaders(true); } catch (Exception $e) { $app['log']->error('Debugbar exception: ' . $e->getMessage()); } // Check if it's safe to inject the Debugbar if ( $app['config']->get('debugbar.inject', true) && str_contains($response->headers->get('Content-Type', 'text/html'), 'html') && !$this->isJsonRequest($request, $response) && $response->getContent() !== false && in_array($request->getRequestFormat(), [null, 'html'], true) ) { try { $this->injectDebugbar($response); } catch (Exception $e) { $app['log']->error('Debugbar exception: ' . $e->getMessage()); } } return $response; } /** * Check if the Debugbar is enabled * @return boolean */ public function isEnabled() { if ($this->enabled === null) { /** @var \Illuminate\Config\Repository $config */ $config = $this->app['config']; $configEnabled = value($config->get('debugbar.enabled')); if ($configEnabled === null) { $configEnabled = $config->get('app.debug'); } $this->enabled = $configEnabled && !$this->app->runningInConsole() && !$this->app->environment('testing'); } return $this->enabled; } /** * Check if this is a request to the Debugbar OpenHandler * * @return bool */ protected function isDebugbarRequest() { return $this->app['request']->is($this->app['config']->get('debugbar.route_prefix') . '*'); } /** * @param \Symfony\Component\HttpFoundation\Request $request * @param \Symfony\Component\HttpFoundation\Response $response * @return bool */ protected function isJsonRequest(Request $request, Response $response) { // If XmlHttpRequest, Live or HTMX, return true if ( $request->isXmlHttpRequest() || $request->headers->has('X-Livewire') || ($request->headers->has('Hx-Request') && $request->headers->has('Hx-Target')) ) { return true; } // Check if the request wants Json $acceptable = $request->getAcceptableContentTypes(); if (isset($acceptable[0]) && in_array($acceptable[0], ['application/json', 'application/javascript'], true)) { return true; } // Check if content looks like JSON without actually validating $content = $response->getContent(); if (is_string($content) && strlen($content) > 0 && in_array($content[0], ['{', '['], true)) { return true; } return false; } /** * Collects the data from the collectors * * @return array */ public function collect() { /** @var Request $request */ $request = $this->app['request']; $this->data = [ '__meta' => [ 'id' => $this->getCurrentRequestId(), 'datetime' => date('Y-m-d H:i:s'), 'utime' => microtime(true), 'method' => $request->getMethod(), 'uri' => $request->getRequestUri(), 'ip' => $request->getClientIp() ] ]; foreach ($this->collectors as $name => $collector) { $this->data[$name] = $collector->collect(); } // Remove all invalid (non UTF-8) characters array_walk_recursive( $this->data, function (&$item) { if (is_string($item) && !mb_check_encoding($item, 'UTF-8')) { $item = mb_convert_encoding($item, 'UTF-8', 'UTF-8'); } } ); if ($this->storage !== null) { $this->storage->save($this->getCurrentRequestId(), $this->data); } return $this->data; } /** * Injects the web debug toolbar into the given Response. * * @param \Symfony\Component\HttpFoundation\Response $response A Response instance * Based on https://github.com/symfony/WebProfilerBundle/blob/master/EventListener/WebDebugToolbarListener.php */ public function injectDebugbar(Response $response) { /** @var \Illuminate\Config\Repository $config */ $config = $this->app['config']; $content = $response->getContent(); $renderer = $this->getJavascriptRenderer(); $autoShow = $config->get('debugbar.ajax_handler_auto_show', true); $renderer->setAjaxHandlerAutoShow($autoShow); $enableTab = $config->get('debugbar.ajax_handler_enable_tab', true); $renderer->setAjaxHandlerEnableTab($enableTab); if ($this->getStorage()) { $openHandlerUrl = route('debugbar.openhandler'); $renderer->setOpenHandlerUrl($openHandlerUrl); } $head = $renderer->renderHead(); $widget = $renderer->render(); // Try to put the js/css directly before the </head> $pos = stripos($content, '</head>'); if (false !== $pos) { $content = substr($content, 0, $pos) . $head . substr($content, $pos); } else { // Append the head before the widget $widget = $head . $widget; } // Try to put the widget at the end, directly before the </body> $pos = strripos($content, '</body>'); if (false !== $pos) { $content = substr($content, 0, $pos) . $widget . substr($content, $pos); } else { $content = $content . $widget; } $original = null; if ($response instanceof \Illuminate\Http\Response && $response->getOriginalContent()) { $original = $response->getOriginalContent(); } // Update the new content and reset the content length $response->setContent($content); $response->headers->remove('Content-Length'); // Restore original response (e.g. the View or Ajax data) if ($original) { $response->original = $original; } } /** * Checks if there is stacked data in the session * * @return boolean */ public function hasStackedData() { return count($this->getStackedData(false)) > 0; } /** * Returns the data stacked in the session * * @param boolean $delete Whether to delete the data in the session * @return array */ public function getStackedData($delete = true): array { $this->stackedData = array_merge($this->stackedData, parent::getStackedData($delete)); return $this->stackedData; } /** * Disable the Debugbar */ public function disable() { $this->enabled = false; } /** * Adds a measure * * @param string $label * @param float $start * @param float $end * @param array|null $params * @param string|null $collector */ public function addMeasure($label, $start, $end, $params = [], $collector = null) { if ($this->hasCollector('time')) { /** @var \DebugBar\DataCollector\TimeDataCollector */ $time = $this->getCollector('time'); $time->addMeasure($label, $start, $end, $params, $collector); } } /** * Utility function to measure the execution of a Closure * * @param string $label * @param \Closure $closure * @param string|null $collector * @return mixed */ public function measure($label, \Closure $closure, $collector = null) { if ($this->hasCollector('time')) { /** @var \DebugBar\DataCollector\TimeDataCollector */ $time = $this->getCollector('time'); $result = $time->measure($label, $closure, $collector); } else { $result = $closure(); } return $result; } /** * Collect data in a CLI request * * @return array */ public function collectConsole() { if (!$this->isEnabled()) { return; } $this->data = [ '__meta' => [ 'id' => $this->getCurrentRequestId(), 'datetime' => date('Y-m-d H:i:s'), 'utime' => microtime(true), 'method' => 'CLI', 'uri' => isset($_SERVER['argv']) ? implode(' ', $_SERVER['argv']) : null, 'ip' => isset($_SERVER['SSH_CLIENT']) ? $_SERVER['SSH_CLIENT'] : null ] ]; foreach ($this->collectors as $name => $collector) { $this->data[$name] = $collector->collect(); } // Remove all invalid (non UTF-8) characters array_walk_recursive( $this->data, function (&$item) { if (is_string($item) && !mb_check_encoding($item, 'UTF-8')) { $item = mb_convert_encoding($item, 'UTF-8', 'UTF-8'); } } ); if ($this->storage !== null) { $this->storage->save($this->getCurrentRequestId(), $this->data); } return $this->data; } /** * Magic calls for adding messages * * @param string $method * @param array $args * @return mixed|void */ public function __call($method, $args) { $messageLevels = ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug', 'log']; if (in_array($method, $messageLevels)) { foreach ($args as $arg) { $this->addMessage($arg, $method); } } } /** * Adds a message to the MessagesCollector * * A message can be anything from an object to a string * * @param mixed $message * @param string $label */ public function addMessage($message, $label = 'info') { if ($this->hasCollector('messages')) { /** @var \DebugBar\DataCollector\MessagesCollector $collector */ $collector = $this->getCollector('messages'); $collector->addMessage($message, $label); } } /** * Check the version of Laravel * * @param string $version * @param string $operator (default: '>=') * @return boolean */ protected function checkVersion($version, $operator = ">=") { return version_compare($this->version, $version, $operator); } protected function isLumen() { return $this->is_lumen; } /** * @param DebugBar $debugbar */ protected function selectStorage(DebugBar $debugbar) { /** @var \Illuminate\Config\Repository $config */ $config = $this->app['config']; if ($config->get('debugbar.storage.enabled')) { $driver = $config->get('debugbar.storage.driver', 'file'); switch ($driver) { case 'pdo': $connection = $config->get('debugbar.storage.connection'); $table = $this->app['db']->getTablePrefix() . 'phpdebugbar'; $pdo = $this->app['db']->connection($connection)->getPdo(); $storage = new PdoStorage($pdo, $table); break; case 'redis': $connection = $config->get('debugbar.storage.connection'); $client = $this->app['redis']->connection($connection); if (is_a($client, 'Illuminate\Redis\Connections\Connection', false)) { $client = $client->client(); } $storage = new RedisStorage($client); break; case 'custom': $class = $config->get('debugbar.storage.provider'); $storage = $this->app->make($class); break; case 'socket': $hostname = $config->get('debugbar.storage.hostname', '127.0.0.1'); $port = $config->get('debugbar.storage.port', 2304); $storage = new SocketStorage($hostname, $port); break; case 'file': default: $path = $config->get('debugbar.storage.path'); $storage = new FilesystemStorage($this->app['files'], $path); break; } $debugbar->setStorage($storage); } } protected function addClockworkHeaders(Response $response) { $prefix = $this->app['config']->get('debugbar.route_prefix'); $response->headers->set('X-Clockwork-Id', $this->getCurrentRequestId(), true); $response->headers->set('X-Clockwork-Version', 9, true); $response->headers->set('X-Clockwork-Path', $prefix . '/clockwork/', true); } /** * Add Server-Timing headers for the TimeData collector * * @see https://www.w3.org/TR/server-timing/ * @param Response $response */ protected function addServerTimingHeaders(Response $response) { if ($this->hasCollector('time')) { $collector = $this->getCollector('time'); $headers = []; foreach ($collector->collect()['measures'] as $m) { $headers[] = sprintf('app;desc="%s";dur=%F', str_replace(array("\n", "\r"), ' ', str_replace('"', "'", $m['label'])), $m['duration'] * 1000); } $response->headers->set('Server-Timing', $headers, false); } } /** * @return array */ private function getRemoteServerReplacements() { $localPath = $this->app['config']->get('debugbar.local_sites_path') ?: base_path(); $remotePaths = array_filter(explode(',', $this->app['config']->get('debugbar.remote_sites_path') ?: '')) ?: [base_path()]; return array_fill_keys($remotePaths, $localPath); } /** * @return \Monolog\Logger * @throws Exception */ private function getMonologLogger() { $logger = $this->app['log']->getLogger(); if (get_class($logger) !== 'Monolog\Logger') { throw new Exception('Logger is not a Monolog\Logger instance'); } return $logger; } }