Commit 7fd3f90d by 朱继来

加入调试工具

parent 28f8c396
Showing with 4766 additions and 1 deletions
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
"maatwebsite/excel": "~2.0.0", "maatwebsite/excel": "~2.0.0",
"guzzlehttp/guzzle": "^6.3", "guzzlehttp/guzzle": "^6.3",
"predis/predis": "^1.1", "predis/predis": "^1.1",
"redgo/monitor-ding": "0.2" "redgo/monitor-ding": "0.2",
"barryvdh/laravel-debugbar": "^2.0"
}, },
"require-dev": { "require-dev": {
"fzaninotto/faker": "~1.4", "fzaninotto/faker": "~1.4",
......
...@@ -156,6 +156,7 @@ return [ ...@@ -156,6 +156,7 @@ return [
App\Providers\EventServiceProvider::class, App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class, App\Providers\RouteServiceProvider::class,
Redgo\MonitorDing\MonitorDingServiceProvider::class, Redgo\MonitorDing\MonitorDingServiceProvider::class,
Barryvdh\Debugbar\ServiceProvider::class,
], ],
/* /*
...@@ -203,6 +204,7 @@ return [ ...@@ -203,6 +204,7 @@ return [
'View' => Illuminate\Support\Facades\View::class, 'View' => Illuminate\Support\Facades\View::class,
'Excel' => Maatwebsite\Excel\Facades\Excel::class, 'Excel' => Maatwebsite\Excel\Facades\Excel::class,
'MonitorDing' => Redgo\MonitorDing\Facades\MonitorDing::class, 'MonitorDing' => Redgo\MonitorDing\Facades\MonitorDing::class,
'Debugbar' => Barryvdh\Debugbar\Facade::class,
], ],
......
<?php
return [
/*
|--------------------------------------------------------------------------
| Debugbar Settings
|--------------------------------------------------------------------------
|
| Debugbar is enabled by default, when debug is set to true in app.php.
| You can override the value by setting enable to true or false instead of null.
|
*/
'enabled' => env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Storage settings
|--------------------------------------------------------------------------
|
| DebugBar stores data for session/ajax requests.
| You can disable this, so the debugbar stores data in headers/session,
| but this can cause problems with large data collectors.
| By default, file storage (in the storage folder) is used. Redis and PDO
| can also be used. For PDO, run the package migrations first.
|
*/
'storage' => [
'enabled' => true,
'driver' => 'file', // redis, file, pdo, custom
'path' => storage_path('debugbar'), // For file driver
'connection' => null, // Leave null for default connection (Redis/PDO)
'provider' => '' // Instance of StorageInterface for custom driver
],
/*
|--------------------------------------------------------------------------
| Vendors
|--------------------------------------------------------------------------
|
| Vendor files are included by default, but can be set to false.
| This can also be set to 'js' or 'css', to only include javascript or css vendor files.
| Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
| and for js: jquery and and highlight.js
| So if you want syntax highlighting, set it to true.
| jQuery is set to not conflict with existing jQuery scripts.
|
*/
'include_vendors' => true,
/*
|--------------------------------------------------------------------------
| Capture Ajax Requests
|--------------------------------------------------------------------------
|
| The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors),
| you can use this option to disable sending the data through the headers.
|
| Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
*/
'capture_ajax' => true,
'add_ajax_timing' => false,
/*
|--------------------------------------------------------------------------
| Custom Error Handler for Deprecated warnings
|--------------------------------------------------------------------------
|
| When enabled, the Debugbar shows deprecated warnings for Symfony components
| in the Messages tab.
|
*/
'error_handler' => false,
/*
|--------------------------------------------------------------------------
| Clockwork integration
|--------------------------------------------------------------------------
|
| The Debugbar can emulate the Clockwork headers, so you can use the Chrome
| Extension, without the server-side code. It uses Debugbar collectors instead.
|
*/
'clockwork' => false,
/*
|--------------------------------------------------------------------------
| DataCollectors
|--------------------------------------------------------------------------
|
| Enable/disable DataCollectors
|
*/
'collectors' => [
'phpinfo' => true, // Php version
'messages' => true, // Messages
'time' => true, // Time Datalogger
'memory' => true, // Memory usage
'exceptions' => true, // Exception displayer
'log' => true, // Logs from Monolog (merged in messages if enabled)
'db' => true, // Show database (PDO) queries and bindings
'views' => true, // Views with their data
'route' => true, // Current route information
'auth' => true, // Display Laravel authentication status
'gate' => true, // Display Laravel Gate checks
'session' => true, // Display session data
'symfony_request' => true, // Only one can be enabled..
'mail' => true, // Catch mail messages
'laravel' => false, // Laravel version and environment
'events' => false, // All events fired
'default_request' => false, // Regular or special Symfony request logger
'logs' => false, // Add the latest log messages
'files' => false, // Show the included files
'config' => false, // Display config settings
],
/*
|--------------------------------------------------------------------------
| Extra options
|--------------------------------------------------------------------------
|
| Configure some DataCollectors
|
*/
'options' => [
'auth' => [
'show_name' => true, // Also show the users name/email in the debugbar
],
'db' => [
'with_params' => true, // Render SQL with the parameters substituted
'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
'timeline' => false, // Add the queries to the timeline
'explain' => [ // Show EXPLAIN output on queries
'enabled' => false,
'types' => ['SELECT'], // ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+
],
'hints' => true, // Show hints for common mistakes
],
'mail' => [
'full_log' => false
],
'views' => [
'data' => false, //Note: Can slow down the application, because the data can be quite large..
],
'route' => [
'label' => true // show complete route on bar
],
'logs' => [
'file' => null
],
],
/*
|--------------------------------------------------------------------------
| Inject Debugbar in Response
|--------------------------------------------------------------------------
|
| Usually, the debugbar is added just before </body>, by listening to the
| Response after the App is done. If you disable this, you have to add them
| in your template yourself. See http://phpdebugbar.com/docs/rendering.html
|
*/
'inject' => true,
/*
|--------------------------------------------------------------------------
| DebugBar route prefix
|--------------------------------------------------------------------------
|
| Sometimes you want to set route prefix to be used by DebugBar to load
| its resources from. Usually the need comes from misconfigured web server or
| from trying to overcome bugs like this: http://trac.nginx.org/nginx/ticket/97
|
*/
'route_prefix' => '_debugbar',
/*
|--------------------------------------------------------------------------
| DebugBar route domain
|--------------------------------------------------------------------------
|
| By default DebugBar route served from the same domain that request served.
| To override default domain, specify it as a non-empty value.
*/
'route_domain' => null,
];
*
!.gitignore
\ No newline at end of file
/vendor
composer.phar
composer.lock
.DS_Store
\ No newline at end of file
Copyright (C) 2013-2014 Barry vd. Heuvel
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
# Changelog for Laravel Debugbar
## 1.8.4 (2014-10-31)
- Add Redis/PDO storage options
## 1.8.3 (2014-11-23)
- Base EventCollector on TimeData Collector
## 1.8.2 (2014-11-18)
- Use XHR handler instead of jQuery handler
## 1.8.1 (2014-11-14)
- Fix compatability with Symfony 2.3 (Laravel 4.)
## 1.8.0 (2014-10-31)
- Fix L5 compatability
- add hints + explain options to QueryLogger
- update to Debugbar 1.10.x
- new ViewCollector layout with more information
## 1.7.7 (2014-09-15)
- Make it compatible with Laravel 5.0-dev
- Allow anonymous function as `enabled` setting (for IP checks etc)
- Escape query bindings, to prevent executing of scripts/html
## 1.7.6 (2014-09-12)
- Fix reflash bug
- Fix caching of debugbar assets
## 1.7.5 (2014-09-12)
- Reflash data for all debugbar requests
## 1.7.4 (2014-09-08)
- Rename assets routes to prevent Nginx conflicts
## 1.7.3 (2014-09-05)
- Add helper functions (debug(), add/start/stop_measure() and measure()
- Collect data on responses that are not redirect/ajax/html also.
## 1.7.2 (2014-09-04)
- Fix 4.0 compatibility (problem with Controller namespace)
- Give deprecation notice instead of publishing assets.
## 1.7.1 (2014-09-03)
- Deprecated `debugbar:publish` command in favor of AssetController
- Fixed issue with detecting absolute paths in Windows
## 1.7.0 (2014-09-03)
- Use AssetController instead of publishing assets to the public folder.
- Inline fonts + images to base64 Data-URI
- Use PSR-4 file structure
## 1.6.8 (2014-08-27)
- Change OpenHandler layout
- Add backtrace option for query origin
## 1.6.7 (2014-08-09)
- Add Twig extensions for better integration with rcrowe/TwigBridge
## 1.6.6 (2014-07-08)
- Check if Requests wantsJSON instead of only isXmlHttpRequest
- Make sure closure for timing is run, even when disabled
## 1.6.5 (2014-06-24)
- Add Laravel style
## 1.6.4 (2014-06-15)
- Work on non-UTF-8 handling
\ No newline at end of file
{
"name": "barryvdh/laravel-debugbar",
"description": "PHP Debugbar integration for Laravel",
"keywords": ["laravel", "debugbar", "profiler", "debug", "webprofiler"],
"license": "MIT",
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"require": {
"php": ">=5.5.9",
"illuminate/support": "5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
"symfony/finder": "~2.7|~3.0",
"maximebf/debugbar": "~1.13.0"
},
"autoload": {
"psr-4": {
"Barryvdh\\Debugbar\\": "src/"
},
"files": [
"src/helpers.php"
]
}
}
<?php
return [
/*
|--------------------------------------------------------------------------
| Debugbar Settings
|--------------------------------------------------------------------------
|
| Debugbar is enabled by default, when debug is set to true in app.php.
| You can override the value by setting enable to true or false instead of null.
|
*/
'enabled' => env('DEBUGBAR_ENABLED', null),
/*
|--------------------------------------------------------------------------
| Storage settings
|--------------------------------------------------------------------------
|
| DebugBar stores data for session/ajax requests.
| You can disable this, so the debugbar stores data in headers/session,
| but this can cause problems with large data collectors.
| By default, file storage (in the storage folder) is used. Redis and PDO
| can also be used. For PDO, run the package migrations first.
|
*/
'storage' => [
'enabled' => true,
'driver' => 'file', // redis, file, pdo, custom
'path' => storage_path('debugbar'), // For file driver
'connection' => null, // Leave null for default connection (Redis/PDO)
'provider' => '' // Instance of StorageInterface for custom driver
],
/*
|--------------------------------------------------------------------------
| Vendors
|--------------------------------------------------------------------------
|
| Vendor files are included by default, but can be set to false.
| This can also be set to 'js' or 'css', to only include javascript or css vendor files.
| Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
| and for js: jquery and and highlight.js
| So if you want syntax highlighting, set it to true.
| jQuery is set to not conflict with existing jQuery scripts.
|
*/
'include_vendors' => true,
/*
|--------------------------------------------------------------------------
| Capture Ajax Requests
|--------------------------------------------------------------------------
|
| The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors),
| you can use this option to disable sending the data through the headers.
|
| Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
*/
'capture_ajax' => true,
'add_ajax_timing' => false,
/*
|--------------------------------------------------------------------------
| Custom Error Handler for Deprecated warnings
|--------------------------------------------------------------------------
|
| When enabled, the Debugbar shows deprecated warnings for Symfony components
| in the Messages tab.
|
*/
'error_handler' => false,
/*
|--------------------------------------------------------------------------
| Clockwork integration
|--------------------------------------------------------------------------
|
| The Debugbar can emulate the Clockwork headers, so you can use the Chrome
| Extension, without the server-side code. It uses Debugbar collectors instead.
|
*/
'clockwork' => false,
/*
|--------------------------------------------------------------------------
| DataCollectors
|--------------------------------------------------------------------------
|
| Enable/disable DataCollectors
|
*/
'collectors' => [
'phpinfo' => true, // Php version
'messages' => true, // Messages
'time' => true, // Time Datalogger
'memory' => true, // Memory usage
'exceptions' => true, // Exception displayer
'log' => true, // Logs from Monolog (merged in messages if enabled)
'db' => true, // Show database (PDO) queries and bindings
'views' => true, // Views with their data
'route' => true, // Current route information
'auth' => true, // Display Laravel authentication status
'gate' => true, // Display Laravel Gate checks
'session' => true, // Display session data
'symfony_request' => true, // Only one can be enabled..
'mail' => true, // Catch mail messages
'laravel' => false, // Laravel version and environment
'events' => false, // All events fired
'default_request' => false, // Regular or special Symfony request logger
'logs' => false, // Add the latest log messages
'files' => false, // Show the included files
'config' => false, // Display config settings
],
/*
|--------------------------------------------------------------------------
| Extra options
|--------------------------------------------------------------------------
|
| Configure some DataCollectors
|
*/
'options' => [
'auth' => [
'show_name' => true, // Also show the users name/email in the debugbar
],
'db' => [
'with_params' => true, // Render SQL with the parameters substituted
'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
'timeline' => false, // Add the queries to the timeline
'explain' => [ // Show EXPLAIN output on queries
'enabled' => false,
'types' => ['SELECT'], // ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+
],
'hints' => true, // Show hints for common mistakes
],
'mail' => [
'full_log' => false
],
'views' => [
'data' => false, //Note: Can slow down the application, because the data can be quite large..
],
'route' => [
'label' => true // show complete route on bar
],
'logs' => [
'file' => null
],
],
/*
|--------------------------------------------------------------------------
| Inject Debugbar in Response
|--------------------------------------------------------------------------
|
| Usually, the debugbar is added just before </body>, by listening to the
| Response after the App is done. If you disable this, you have to add them
| in your template yourself. See http://phpdebugbar.com/docs/rendering.html
|
*/
'inject' => true,
/*
|--------------------------------------------------------------------------
| DebugBar route prefix
|--------------------------------------------------------------------------
|
| Sometimes you want to set route prefix to be used by DebugBar to load
| its resources from. Usually the need comes from misconfigured web server or
| from trying to overcome bugs like this: http://trac.nginx.org/nginx/ticket/97
|
*/
'route_prefix' => '_debugbar',
/*
|--------------------------------------------------------------------------
| DebugBar route domain
|--------------------------------------------------------------------------
|
| By default DebugBar route served from the same domain that request served.
| To override default domain, specify it as a non-empty value.
*/
'route_domain' => null,
];
## Laravel Debugbar
[![Packagist License](https://poser.pugx.org/barryvdh/laravel-debugbar/license.png)](http://choosealicense.com/licenses/mit/)
[![Latest Stable Version](https://poser.pugx.org/barryvdh/laravel-debugbar/version.png)](https://packagist.org/packages/barryvdh/laravel-debugbar)
[![Total Downloads](https://poser.pugx.org/barryvdh/laravel-debugbar/d/total.png)](https://packagist.org/packages/barryvdh/laravel-debugbar)
### For Laravel 4, please use the [1.8 branch](https://github.com/barryvdh/laravel-debugbar/tree/1.8)!
This is a package to integrate [PHP Debug Bar](http://phpdebugbar.com/) with Laravel 5.
It includes a ServiceProvider to register the debugbar and attach it to the output. You can publish assets and configure it through Laravel.
It bootstraps some Collectors to work with Laravel and implements a couple custom DataCollectors, specific for Laravel.
It is configured to display Redirects and (jQuery) Ajax Requests. (Shown in a dropdown)
Read [the documentation](http://phpdebugbar.com/docs/) for more configuration options.
![Screenshot](https://cloud.githubusercontent.com/assets/973269/4270452/740c8c8c-3ccb-11e4-8d9a-5a9e64f19351.png)
Note: Use the DebugBar only in development. It can slow the application down (because it has to gather data). So when experiencing slowness, try disabling some of the collectors.
This package includes some custom collectors:
- QueryCollector: Show all queries, including binding + timing
- RouteCollector: Show information about the current Route.
- ViewCollector: Show the currently loaded views. (Optionally: display the shared data)
- EventsCollector: Show all events
- LaravelCollector: Show the Laravel version and Environment. (disabled by default)
- SymfonyRequestCollector: replaces the RequestCollector with more information about the request/response
- LogsCollector: Show the latest log entries from the storage logs. (disabled by default)
- FilesCollector: Show the files that are included/required by PHP. (disabled by default)
- ConfigCollector: Display the values from the config files. (disabled by default)
Bootstraps the following collectors for Laravel:
- LogCollector: Show all Log messages
- SwiftMailCollector and SwiftLogCollector for Mail
And the default collectors:
- PhpInfoCollector
- MessagesCollector
- TimeDataCollector (With Booting and Application timing)
- MemoryCollector
- ExceptionsCollector
It also provides a Facade interface for easy logging Messages, Exceptions and Time
## Installation
Require this package with composer:
```shell
composer require barryvdh/laravel-debugbar
```
After updating composer, add the ServiceProvider to the providers array in config/app.php
> If you use a catch-all/fallback route, make sure you load the Debugbar ServiceProvider before your own App ServiceProviders.
### Laravel 5.x:
```php
Barryvdh\Debugbar\ServiceProvider::class,
```
If you want to use the facade to log messages, add this to your facades in app.php:
```php
'Debugbar' => Barryvdh\Debugbar\Facade::class,
```
The profiler is enabled by default, if you have app.debug=true. You can override that in the config (`debugbar.enabled`). See more options in `config/debugbar.php`
You can also set in your config if you want to include/exclude the vendor files also (FontAwesome, Highlight.js and jQuery). If you already use them in your site, set it to false.
You can also only display the js or css vendors, by setting it to 'js' or 'css'. (Highlight.js requires both css + js, so set to `true` for syntax highlighting)
Copy the package config to your local config with the publish command:
```shell
php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"
```
### Lumen:
For Lumen, register a different Provider in `bootstrap/app.php`:
```php
if (env('APP_DEBUG')) {
$app->register(Barryvdh\Debugbar\LumenServiceProvider::class);
}
```
To change the configuration, copy the file to your config folder and enable it:
```php
$app->configure('debugbar');
```
## Usage
You can now add messages using the Facade (when added), using the PSR-3 levels (debug, info, notice, warning, error, critical, alert, emergency):
```php
Debugbar::info($object);
Debugbar::error('Error!');
Debugbar::warning('Watch out…');
Debugbar::addMessage('Another message', 'mylabel');
```
And start/stop timing:
```php
Debugbar::startMeasure('render','Time for rendering');
Debugbar::stopMeasure('render');
Debugbar::addMeasure('now', LARAVEL_START, microtime(true));
Debugbar::measure('My long operation', function() {
// Do something…
});
```
Or log exceptions:
```php
try {
throw new Exception('foobar');
} catch (Exception $e) {
Debugbar::addThrowable($e);
}
```
There are also helper functions available for the most common calls:
```php
// All arguments will be dumped as a debug message
debug($var1, $someString, $intValue, $object);
start_measure('render','Time for rendering');
stop_measure('render');
add_measure('now', LARAVEL_START, microtime(true));
measure('My long operation', function() {
// Do something…
});
```
If you want you can add your own DataCollectors, through the Container or the Facade:
```php
Debugbar::addCollector(new DebugBar\DataCollector\MessagesCollector('my_messages'));
//Or via the App container:
$debugbar = App::make('debugbar');
$debugbar->addCollector(new DebugBar\DataCollector\MessagesCollector('my_messages'));
```
By default, the Debugbar is injected just before `</body>`. If you want to inject the Debugbar yourself,
set the config option 'inject' to false and use the renderer yourself and follow http://phpdebugbar.com/docs/rendering.html
```php
$renderer = Debugbar::getJavascriptRenderer();
```
Note: Not using the auto-inject, will disable the Request information, because that is added After the response.
You can add the default_request datacollector in the config as alternative.
## Enabling/Disabling on run time
You can enable or disable the debugbar during run time.
```php
\Debugbar::enable();
\Debugbar::disable();
```
NB. Once enabled, the collectors are added (and could produce extra overhead), so if you want to use the debugbar in production, disable in the config and only enable when needed.
## Twig Integration
Laravel Debugbar comes with two Twig Extensions. These are tested with [rcrowe/TwigBridge](https://github.com/rcrowe/TwigBridge) 0.6.x
Add the following extensions to your TwigBridge config/extensions.php (or register the extensions manually)
```php
'Barryvdh\Debugbar\Twig\Extension\Debug',
'Barryvdh\Debugbar\Twig\Extension\Dump',
'Barryvdh\Debugbar\Twig\Extension\Stopwatch',
```
The Dump extension will replace the [dump function](http://twig.sensiolabs.org/doc/functions/dump.html) to output variables using the DataFormatter. The Debug extension adds a `debug()` function which passes variables to the Message Collector,
instead of showing it directly in the template. It dumps the arguments, or when empty; all context variables.
```twig
{{ debug() }}
{{ debug(user, categories) }}
```
The Stopwatch extension adds a [stopwatch tag](http://symfony.com/blog/new-in-symfony-2-4-a-stopwatch-tag-for-twig) similar to the one in Symfony/Silex Twigbridge.
```twig
{% stopwatch "foo" %}
…some things that gets timed
{% endstopwatch %}
```
<?php namespace Barryvdh\Debugbar\Console;
use DebugBar\DebugBar;
use Illuminate\Console\Command;
class ClearCommand extends Command
{
protected $name = 'debugbar:clear';
protected $description = 'Clear the Debugbar Storage';
protected $debugbar;
public function __construct(DebugBar $debugbar)
{
$this->debugbar = $debugbar;
parent::__construct();
}
public function fire()
{
$this->debugbar->boot();
if ($storage = $this->debugbar->getStorage()) {
try
{
$storage->clear();
} catch(\InvalidArgumentException $e) {
// hide InvalidArgumentException if storage location does not exist
if(strpos($e->getMessage(), 'does not exist') === false) {
throw $e;
}
}
$this->info('Debugbar Storage cleared!');
} else {
$this->error('No Debugbar Storage found..');
}
}
}
<?php
namespace Barryvdh\Debugbar\Console;
use Illuminate\Console\Command;
/**
* Publish the Debugbar assets to the public directory
*
* @author Barry vd. Heuvel <barryvdh@gmail.com>
* @deprecated No longer needed because of the AssetController
*/
class PublishCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'debugbar:publish';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Publish the Debugbar assets';
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$this->info(
'NOTICE: Since laravel-debugbar 1.7.x, publishing assets is no longer necessary. The assets in public/packages/barryvdh/laravel-debugbar and maximebf/php-debugbar can be safely removed.'
);
}
}
<?php namespace Barryvdh\Debugbar\Controllers;
use Illuminate\Http\Response;
class AssetController extends BaseController
{
/**
* Return the javascript for the Debugbar
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function js()
{
$renderer = $this->debugbar->getJavascriptRenderer();
$content = $renderer->dumpAssetsToString('js');
$response = new Response(
$content, 200, [
'Content-Type' => 'text/javascript',
]
);
return $this->cacheResponse($response);
}
/**
* Return the stylesheets for the Debugbar
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function css()
{
$renderer = $this->debugbar->getJavascriptRenderer();
$content = $renderer->dumpAssetsToString('css');
$response = new Response(
$content, 200, [
'Content-Type' => 'text/css',
]
);
return $this->cacheResponse($response);
}
/**
* Cache the response 1 year (31536000 sec)
*/
protected function cacheResponse(Response $response)
{
$response->setSharedMaxAge(31536000);
$response->setMaxAge(31536000);
$response->setExpires(new \DateTime('+1 year'));
return $response;
}
}
<?php namespace Barryvdh\Debugbar\Controllers;
use Barryvdh\Debugbar\LaravelDebugbar;
use Illuminate\Routing\Controller;
use Illuminate\Http\Request;
if (class_exists('Illuminate\Routing\Controller')) {
class BaseController extends Controller
{
protected $debugbar;
public function __construct(Request $request, LaravelDebugbar $debugbar)
{
$this->debugbar = $debugbar;
if ($request->hasSession()){
$request->session()->reflash();
}
}
}
} else {
class BaseController
{
protected $debugbar;
public function __construct(Request $request, LaravelDebugbar $debugbar)
{
$this->debugbar = $debugbar;
if ($request->hasSession()){
$request->session()->reflash();
}
}
}
}
\ No newline at end of file
<?php namespace Barryvdh\Debugbar\Controllers;
use Barryvdh\Debugbar\Support\Clockwork\Converter;
use DebugBar\OpenHandler;
use Illuminate\Http\Response;
class OpenHandlerController extends BaseController
{
public function handle()
{
$debugbar = $this->debugbar;
if (!$debugbar->isEnabled()) {
$this->app->abort('500', 'Debugbar is not enabled');
}
$openHandler = new OpenHandler($debugbar);
$data = $openHandler->handle(null, false, false);
return new Response(
$data, 200, [
'Content-Type' => 'application/json'
]
);
}
/**
* Return Clockwork output
*
* @param $id
* @return mixed
* @throws \DebugBar\DebugBarException
*/
public function clockwork($id)
{
$request = [
'op' => 'get',
'id' => $id,
];
$debugbar = $this->debugbar;
if (!$debugbar->isEnabled()) {
$this->app->abort('500', 'Debugbar is not enabled');
}
$openHandler = new OpenHandler($debugbar);
$data = $openHandler->handle($request, false, false);
// Convert to Clockwork
$converter = new Converter();
$output = $converter->convert(json_decode($data, true));
return response()->json($output);
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Illuminate\Contracts\Support\Arrayable;
/**
* Collector for Laravel's Auth provider
*/
class AuthCollector extends DataCollector implements Renderable
{
/** @var \Illuminate\Auth\AuthManager */
protected $auth;
/** @var bool */
protected $showName = false;
/**
* @param \Illuminate\Auth\AuthManager $auth
*/
public function __construct($auth)
{
$this->auth = $auth;
}
/**
* Set to show the users name/email
* @param bool $showName
*/
public function setShowName($showName)
{
$this->showName = (bool) $showName;
}
/**
* @{inheritDoc}
*/
public function collect()
{
try {
$user = $this->auth->user();
} catch (\Exception $e) {
$user = null;
}
return $this->getUserInformation($user);
}
/**
* Get displayed user information
* @param \Illuminate\Auth\UserInterface $user
* @return array
*/
protected function getUserInformation($user = null)
{
// Defaults
if (is_null($user)) {
return [
'name' => 'Guest',
'user' => ['guest' => true],
];
}
// The default auth identifer is the ID number, which isn't all that
// useful. Try username and email.
$identifier = $user->getAuthIdentifier();
if (is_numeric($identifier)) {
try {
if ($user->username) {
$identifier = $user->username;
} elseif ($user->email) {
$identifier = $user->email;
}
} catch (\Exception $e) {
}
}
return [
'name' => $identifier,
'user' => $user instanceof Arrayable ? $user->toArray() : $user,
];
}
/**
* @{inheritDoc}
*/
public function getName()
{
return 'auth';
}
/**
* @{inheritDoc}
*/
public function getWidgets()
{
$widgets = [
'auth' => [
'icon' => 'lock',
'widget' => 'PhpDebugBar.Widgets.VariableListWidget',
'map' => 'auth.user',
'default' => '{}'
]
];
if ($this->showName) {
$widgets['auth.name'] = [
'icon' => 'user',
'tooltip' => 'Auth status',
'map' => 'auth.name',
'default' => '',
];
}
return $widgets;
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\TimeDataCollector;
use Illuminate\Events\Dispatcher;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter;
class EventCollector extends TimeDataCollector
{
/** @var Dispatcher */
protected $events;
/** @var ValueExporter */
protected $exporter;
public function __construct($requestStartTime = null)
{
parent::__construct($requestStartTime);
$this->exporter = new ValueExporter();
}
public function onWildcardEvent($name = null, $data = [])
{
// Pre-Laravel 5.4, using 'firing' to get the current event name.
if (method_exists($this->events, 'firing')) {
$name = $this->events->firing();
// Get the arguments passed to the event
$data = func_get_args();
}
$params = $this->prepareParams($data);
$time = microtime(true);
// Find all listeners for the current event
foreach ($this->events->getListeners($name) as $i => $listener) {
// Check if it's an object + method name
if (is_array($listener) && count($listener) > 1 && is_object($listener[0])) {
list($class, $method) = $listener;
// Skip this class itself
if ($class instanceof static) {
continue;
}
// Format the listener to readable format
$listener = get_class($class) . '@' . $method;
// Handle closures
} elseif ($listener instanceof \Closure) {
$reflector = new \ReflectionFunction($listener);
// Skip our own listeners
if ($reflector->getNamespaceName() == 'Barryvdh\Debugbar') {
continue;
}
// Format the closure to a readable format
$filename = ltrim(str_replace(base_path(), '', $reflector->getFileName()), '/');
$listener = $reflector->getName() . ' (' . $filename . ':' . $reflector->getStartLine() . '-' . $reflector->getEndLine() . ')';
} else {
// Not sure if this is possible, but to prevent edge cases
$listener = $this->formatVar($listener);
}
$params['listeners.' . $i] = $listener;
}
$this->addMeasure($name, $time, $time, $params);
}
public function subscribe(Dispatcher $events)
{
$this->events = $events;
$events->listen('*', [$this, 'onWildcardEvent']);
}
protected function prepareParams($params)
{
$data = [];
foreach ($params as $key => $value) {
if (is_object($value) && Str::is('Illuminate\*\Events\*', get_class($value))) {
$value = $this->prepareParams(get_object_vars($value));
}
$data[$key] = htmlentities($this->exporter->exportValue($value), ENT_QUOTES, 'UTF-8', false);
}
return $data;
}
public function collect()
{
$data = parent::collect();
$data['nb_measures'] = count($data['measures']);
return $data;
}
public function getName()
{
return 'event';
}
public function getWidgets()
{
return [
"events" => [
"icon" => "tasks",
"widget" => "PhpDebugBar.Widgets.TimelineWidget",
"map" => "event",
"default" => "{}",
],
'events:badge' => [
'map' => 'event.nb_measures',
'default' => 0,
],
];
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Illuminate\Contracts\Foundation\Application;
class FilesCollector extends DataCollector implements Renderable
{
/** @var \Illuminate\Contracts\Foundation\Application */
protected $app;
protected $basePath;
/**
* @param \Illuminate\Contracts\Foundation\Application $app
*/
public function __construct(Application $app = null)
{
$this->app = $app;
$this->basePath = base_path();
}
/**
* {@inheritDoc}
*/
public function collect()
{
$files = $this->getIncludedFiles();
$compiled = $this->getCompiledFiles();
$included = [];
$alreadyCompiled = [];
foreach ($files as $file) {
// Skip the files from Debugbar, they are only loaded for Debugging and confuse the output.
// Of course some files are stil always loaded (ServiceProvider, Facade etc)
if (strpos($file, 'vendor/maximebf/debugbar/src') !== false || strpos(
$file,
'vendor/barryvdh/laravel-debugbar/src'
) !== false
) {
continue;
} elseif (!in_array($file, $compiled)) {
$included[] = [
'message' => "'" . $this->stripBasePath($file) . "',",
// Use PHP syntax so we can copy-paste to compile config file.
'is_string' => true,
];
} else {
$alreadyCompiled[] = [
'message' => "* '" . $this->stripBasePath($file) . "',",
// Mark with *, so know they are compiled anyways.
'is_string' => true,
];
}
}
// First the included files, then those that are going to be compiled.
$messages = array_merge($included, $alreadyCompiled);
return [
'messages' => $messages,
'count' => count($included),
];
}
/**
* Get the files included on load.
*
* @return array
*/
protected function getIncludedFiles()
{
return get_included_files();
}
/**
* Get the files that are going to be compiled, so they aren't as important.
*
* @return array
*/
protected function getCompiledFiles()
{
if ($this->app && class_exists('Illuminate\Foundation\Console\OptimizeCommand')) {
$reflector = new \ReflectionClass('Illuminate\Foundation\Console\OptimizeCommand');
$path = dirname($reflector->getFileName()) . '/Optimize/config.php';
if (file_exists($path)) {
$app = $this->app;
$core = require $path;
return array_merge($core, $app['config']['compile']);
}
}
return [];
}
/**
* Remove the basePath from the paths, so they are relative to the base
*
* @param $path
* @return string
*/
protected function stripBasePath($path)
{
return ltrim(str_replace($this->basePath, '', $path), '/');
}
/**
* {@inheritDoc}
*/
public function getWidgets()
{
$name = $this->getName();
return [
"$name" => [
"icon" => "files-o",
"widget" => "PhpDebugBar.Widgets.MessagesWidget",
"map" => "$name.messages",
"default" => "{}"
],
"$name:badge" => [
"map" => "$name.count",
"default" => "null"
]
];
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'files';
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\MessagesCollector;
use Illuminate\Contracts\Auth\Access\Gate;
use Illuminate\Contracts\Auth\Authenticatable;
use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter;
/**
* Collector for Laravel's Auth provider
*/
class GateCollector extends MessagesCollector
{
/** @var ValueExporter */
protected $exporter;
/**
* @param Gate $gate
*/
public function __construct(Gate $gate)
{
parent::__construct('gate');
$this->exporter = new ValueExporter();
if (method_exists($gate, 'after')) {
$gate->after([$this, 'addCheck']);
}
}
public function addCheck(Authenticatable $user, $ability, $result, $arguments = [])
{
$label = $result ? 'success' : 'error';
$this->addMessage([
'ability' => $ability,
'result' => $result,
'user' => $user->getAuthIdentifier(),
'arguments' => $this->exporter->exportValue($arguments),
], $label, false);
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Config;
/**
* Based on Illuminate\Foundation\Console\RoutesCommand for Taylor Otwell
* https://github.com/laravel/framework/blob/master/src/Illuminate/Foundation/Console/RoutesCommand.php
*
*/
class IlluminateRouteCollector extends DataCollector implements Renderable
{
/**
* The router instance.
*
* @var \Illuminate\Routing\Router
*/
protected $router;
public function __construct(Router $router)
{
$this->router = $router;
}
/**
* {@inheritDoc}
*/
public function collect()
{
$route = $this->router->current();
return $this->getRouteInformation($route);
}
/**
* Get the route information for a given route.
*
* @param \Illuminate\Routing\Route $route
* @return array
*/
protected function getRouteInformation($route)
{
if (!is_a($route, 'Illuminate\Routing\Route')) {
return [];
}
$uri = head($route->methods()) . ' ' . $route->uri();
$action = $route->getAction();
$result = [
'uri' => $uri ?: '-',
];
$result = array_merge($result, $action);
if (isset($action['controller']) && strpos($action['controller'], '@') !== false) {
list($controller, $method) = explode('@', $action['controller']);
if(class_exists($controller) && method_exists($controller, $method)) {
$reflector = new \ReflectionMethod($controller, $method);
}
unset($result['uses']);
} elseif (isset($action['uses']) && $action['uses'] instanceof \Closure) {
$reflector = new \ReflectionFunction($action['uses']);
$result['uses'] = $this->formatVar($result['uses']);
}
if (isset($reflector)) {
$filename = ltrim(str_replace(base_path(), '', $reflector->getFileName()), '/');
$result['file'] = $filename . ':' . $reflector->getStartLine() . '-' . $reflector->getEndLine();
}
if ($middleware = $this->getMiddleware($route)) {
$result['middleware'] = $middleware;
}
return $result;
}
/**
* Get middleware
*
* @param \Illuminate\Routing\Route $route
* @return string
*/
protected function getMiddleware($route)
{
return implode(', ', $route->middleware());
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'route';
}
/**
* {@inheritDoc}
*/
public function getWidgets()
{
$widgets = [
"route" => [
"icon" => "share",
"widget" => "PhpDebugBar.Widgets.VariableListWidget",
"map" => "route",
"default" => "{}"
]
];
if (Config::get('debugbar.options.route.label', true)) {
$widgets['currentroute'] = [
"icon" => "share",
"tooltip" => "Route",
"map" => "route.uri",
"default" => ""
];
}
return $widgets;
}
/**
* Display the route information on the console.
*
* @param array $routes
* @return void
*/
protected function displayRoutes(array $routes)
{
$this->table->setHeaders($this->headers)->setRows($routes);
$this->table->render($this->getOutput());
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Illuminate\Foundation\Application;
class LaravelCollector extends DataCollector implements Renderable
{
/** @var \Illuminate\Foundation\Application $app */
protected $app;
/**
* @param Application $app
*/
public function __construct(Application $app = null)
{
$this->app = $app;
}
/**
* {@inheritDoc}
*/
public function collect()
{
// Fallback if not injected
$app = $this->app ?: app();
return [
"version" => $app::VERSION,
"environment" => $app->environment(),
"locale" => $app->getLocale(),
];
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'laravel';
}
/**
* {@inheritDoc}
*/
public function getWidgets()
{
return [
"version" => [
"icon" => "github",
"tooltip" => "Version",
"map" => "laravel.version",
"default" => ""
],
"environment" => [
"icon" => "desktop",
"tooltip" => "Environment",
"map" => "laravel.environment",
"default" => ""
],
"locale" => [
"icon" => "flag",
"tooltip" => "Current locale",
"map" => "laravel.locale",
"default" => "",
],
];
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\MessagesCollector;
use Psr\Log\LogLevel;
use ReflectionClass;
class LogsCollector extends MessagesCollector
{
protected $lines = 124;
public function __construct($path = null, $name = 'logs')
{
parent::__construct($name);
$path = $path ?: $this->getLogsFile();
$this->getStorageLogs($path);
}
/**
* Get the path to the logs file
*
* @return string
*/
public function getLogsFile()
{
// default daily rotating logs (Laravel 5.0)
$path = storage_path() . '/logs/laravel-' . date('Y-m-d') . '.log';
// single file logs
if (!file_exists($path)) {
$path = storage_path() . '/logs/laravel.log';
}
return $path;
}
/**
* get logs apache in app/storage/logs
* only 24 last of current day
*
* @param string $path
*
* @return array
*/
public function getStorageLogs($path)
{
if (!file_exists($path)) {
return;
}
//Load the latest lines, guessing about 15x the number of log entries (for stack traces etc)
$file = implode("", $this->tailFile($path, $this->lines));
foreach ($this->getLogs($file) as $log) {
$this->addMessage($log['header'] . $log['stack'], $log['level'], false);
}
}
/**
* By Ain Tohvri (ain)
* http://tekkie.flashbit.net/php/tail-functionality-in-php
* @param string $file
* @param int $lines
* @return array
*/
protected function tailFile($file, $lines)
{
$handle = fopen($file, "r");
$linecounter = $lines;
$pos = -2;
$beginning = false;
$text = [];
while ($linecounter > 0) {
$t = " ";
while ($t != "\n") {
if (fseek($handle, $pos, SEEK_END) == -1) {
$beginning = true;
break;
}
$t = fgetc($handle);
$pos--;
}
$linecounter--;
if ($beginning) {
rewind($handle);
}
$text[$lines - $linecounter - 1] = fgets($handle);
if ($beginning) {
break;
}
}
fclose($handle);
return array_reverse($text);
}
/**
* Search a string for log entries
* Based on https://github.com/mikemand/logviewer/blob/master/src/Kmd/Logviewer/Logviewer.php by mikemand
*
* @param $file
* @return array
*/
public function getLogs($file)
{
$pattern = "/\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\].*/";
$log_levels = $this->getLevels();
// There has GOT to be a better way of doing this...
preg_match_all($pattern, $file, $headings);
$log_data = preg_split($pattern, $file);
$log = [];
foreach ($headings as $h) {
for ($i = 0, $j = count($h); $i < $j; $i++) {
foreach ($log_levels as $ll) {
if (strpos(strtolower($h[$i]), strtolower('.' . $ll))) {
$log[] = ['level' => $ll, 'header' => $h[$i], 'stack' => $log_data[$i]];
}
}
}
}
$log = array_reverse($log);
return $log;
}
/**
* Get the log levels from psr/log.
* Based on https://github.com/mikemand/logviewer/blob/master/src/Kmd/Logviewer/Logviewer.php by mikemand
*
* @access public
* @return array
*/
public function getLevels()
{
$class = new ReflectionClass(new LogLevel());
return $class->getConstants();
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use Illuminate\Auth\SessionGuard;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\Str;
/**
* Collector for Laravel's Auth provider
*/
class MultiAuthCollector extends AuthCollector
{
/** @var array $guards */
protected $guards;
/**
* @param \Illuminate\Auth\AuthManager $auth
* @param array $guards
*/
public function __construct($auth, $guards)
{
parent::__construct($auth);
$this->guards = $guards;
}
/**
* @{inheritDoc}
*/
public function collect()
{
$data = [];
$names = '';
foreach($this->guards as $guardName) {
try {
$user = $this->resolveUser($this->auth->guard($guardName));
} catch (\Exception $e) {
continue;
}
$data['guards'][$guardName] = $this->getUserInformation($user);
if(!is_null($user)) {
$names .= $guardName . ": " . $data['guards'][$guardName]['name'] . ', ';
}
}
foreach ($data['guards'] as $key => $var) {
if (!is_string($data['guards'][$key])) {
$data['guards'][$key] = $this->formatVar($var);
}
}
$data['names'] = rtrim($names, ', ');
return $data;
}
private function resolveUser(Guard $guard)
{
// if we're logging in using remember token
// then we must resolve user „manually”
// to prevent csrf token regeneration
$recaller = $guard instanceof SessionGuard
? $guard->getRequest()->cookies->get($guard->getRecallerName())
: null;
if (is_string($recaller) && Str::contains($recaller, '|')) {
$segments = explode('|', $recaller);
if (count($segments) == 2 && trim($segments[0]) !== '' && trim($segments[1]) !== '') {
return $guard->getProvider()->retrieveByToken($segments[0], $segments[1]);
}
}
return $guard->user();
}
/**
* @{inheritDoc}
*/
public function getWidgets()
{
$widgets = [
"auth" => [
"icon" => "lock",
"widget" => "PhpDebugBar.Widgets.VariableListWidget",
"map" => "auth.guards",
"default" => "{}"
]
];
if ($this->showName) {
$widgets['auth.name'] = [
'icon' => 'user',
'tooltip' => 'Auth status',
'map' => 'auth.names',
'default' => '',
];
}
return $widgets;
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\DataCollectorInterface;
use DebugBar\DataCollector\Renderable;
class SessionCollector extends DataCollector implements DataCollectorInterface, Renderable
{
/** @var \Symfony\Component\HttpFoundation\Session\SessionInterface|\Illuminate\Contracts\Session\Session $session */
protected $session;
/**
* Create a new SessionCollector
*
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface|\Illuminate\Contracts\Session\Session $session
*/
public function __construct($session)
{
$this->session = $session;
}
/**
* {@inheritdoc}
*/
public function collect()
{
$data = [];
foreach ($this->session->all() as $key => $value) {
$data[$key] = is_string($value) ? $value : $this->formatVar($value);
}
return $data;
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'session';
}
/**
* {@inheritDoc}
*/
public function getWidgets()
{
return [
"session" => [
"icon" => "archive",
"widget" => "PhpDebugBar.Widgets.VariableListWidget",
"map" => "session",
"default" => "{}"
]
];
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\DataCollectorInterface;
use DebugBar\DataCollector\Renderable;
use Symfony\Component\HttpFoundation\Response;
/**
*
* Based on \Symfony\Component\HttpKernel\DataCollector\RequestDataCollector by Fabien Potencier <fabien@symfony.com>
*
*/
class SymfonyRequestCollector extends DataCollector implements DataCollectorInterface, Renderable
{
/** @var \Symfony\Component\HttpFoundation\Request $request */
protected $request;
/** @var \Symfony\Component\HttpFoundation\Request $response */
protected $response;
/** @var \Symfony\Component\HttpFoundation\Session\SessionInterface $session */
protected $session;
/**
* Create a new SymfonyRequestCollector
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\HttpFoundation\Request $response
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
*/
public function __construct($request, $response, $session = null)
{
$this->request = $request;
$this->response = $response;
$this->session = $session;
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'request';
}
/**
* {@inheritDoc}
*/
public function getWidgets()
{
return [
"request" => [
"icon" => "tags",
"widget" => "PhpDebugBar.Widgets.VariableListWidget",
"map" => "request",
"default" => "{}"
]
];
}
/**
* {@inheritdoc}
*/
public function collect()
{
$request = $this->request;
$response = $this->response;
$responseHeaders = $response->headers->all();
$cookies = [];
foreach ($response->headers->getCookies() as $cookie) {
$cookies[] = $this->getCookieHeader(
$cookie->getName(),
$cookie->getValue(),
$cookie->getExpiresTime(),
$cookie->getPath(),
$cookie->getDomain(),
$cookie->isSecure(),
$cookie->isHttpOnly()
);
}
if (count($cookies) > 0) {
$responseHeaders['Set-Cookie'] = $cookies;
}
$statusCode = $response->getStatusCode();
$data = [
'format' => $request->getRequestFormat(),
'content_type' => $response->headers->get('Content-Type') ? $response->headers->get(
'Content-Type'
) : 'text/html',
'status_text' => isset(Response::$statusTexts[$statusCode]) ? Response::$statusTexts[$statusCode] : '',
'status_code' => $statusCode,
'request_query' => $request->query->all(),
'request_request' => $request->request->all(),
'request_headers' => $request->headers->all(),
'request_server' => $request->server->all(),
'request_cookies' => $request->cookies->all(),
'response_headers' => $responseHeaders,
'path_info' => $request->getPathInfo(),
];
if ($this->session) {
$sessionAttributes = [];
foreach ($this->session->all() as $key => $value) {
$sessionAttributes[$key] = $value;
}
$data['session_attributes'] = $sessionAttributes;
}
foreach ($data['request_server'] as $key => $value) {
if (str_is('*_KEY', $key) || str_is('*_PASSWORD', $key)
|| str_is('*_SECRET', $key) || str_is('*_PW', $key)) {
$data['request_server'][$key] = '******';
}
}
if (isset($data['request_headers']['php-auth-pw'])) {
$data['request_headers']['php-auth-pw'] = '******';
}
if (isset($data['request_server']['PHP_AUTH_PW'])) {
$data['request_server']['PHP_AUTH_PW'] = '******';
}
foreach ($data as $key => $var) {
if (!is_string($data[$key])) {
$data[$key] = $this->formatVar($var);
}
}
return $data;
}
private function getCookieHeader($name, $value, $expires, $path, $domain, $secure, $httponly)
{
$cookie = sprintf('%s=%s', $name, urlencode($value));
if (0 !== $expires) {
if (is_numeric($expires)) {
$expires = (int) $expires;
} elseif ($expires instanceof \DateTime) {
$expires = $expires->getTimestamp();
} else {
$expires = strtotime($expires);
if (false === $expires || -1 == $expires) {
throw new \InvalidArgumentException(
sprintf('The "expires" cookie parameter is not valid.', $expires)
);
}
}
$cookie .= '; expires=' . substr(
\DateTime::createFromFormat('U', $expires, new \DateTimeZone('UTC'))->format('D, d-M-Y H:i:s T'),
0,
-5
);
}
if ($domain) {
$cookie .= '; domain=' . $domain;
}
$cookie .= '; path=' . $path;
if ($secure) {
$cookie .= '; secure';
}
if ($httponly) {
$cookie .= '; httponly';
}
return $cookie;
}
}
<?php
namespace Barryvdh\Debugbar\DataCollector;
use DebugBar\Bridge\Twig\TwigCollector;
use Illuminate\View\View;
use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter;
class ViewCollector extends TwigCollector
{
protected $templates = [];
protected $collect_data;
/**
* Create a ViewCollector
*
* @param bool $collectData Collects view data when tru
*/
public function __construct($collectData = true)
{
$this->collect_data = $collectData;
$this->name = 'views';
$this->templates = [];
$this->exporter = new ValueExporter();
}
public function getName()
{
return 'views';
}
public function getWidgets()
{
return [
'views' => [
'icon' => 'leaf',
'widget' => 'PhpDebugBar.Widgets.TemplatesWidget',
'map' => 'views',
'default' => '[]'
],
'views:badge' => [
'map' => 'views.nb_templates',
'default' => 0
]
];
}
/**
* Add a View instance to the Collector
*
* @param \Illuminate\View\View $view
*/
public function addView(View $view)
{
$name = $view->getName();
$path = $view->getPath();
if (!is_object($path)) {
if ($path) {
$path = ltrim(str_replace(base_path(), '', realpath($path)), '/');
}
if (substr($path, -10) == '.blade.php') {
$type = 'blade';
} else {
$type = pathinfo($path, PATHINFO_EXTENSION);
}
} else {
$type = get_class($view);
$path = '';
}
if (!$this->collect_data) {
$params = array_keys($view->getData());
} else {
$data = [];
foreach ($view->getData() as $key => $value) {
$data[$key] = $this->exporter->exportValue($value);
}
$params = $data;
}
$this->templates[] = [
'name' => $path ? sprintf('%s (%s)', $name, $path) : $name,
'param_count' => count($params),
'params' => $params,
'type' => $type,
];
}
public function collect()
{
$templates = $this->templates;
return [
'nb_templates' => count($templates),
'templates' => $templates,
];
}
}
<?php
namespace Barryvdh\Debugbar\DataFormatter;
use DebugBar\DataFormatter\DataFormatter;
class QueryFormatter extends DataFormatter
{
/**
* Removes extra spaces at the beginning and end of the SQL query and its lines.
*
* @param string $sql
* @return string
*/
public function formatSql($sql)
{
return trim(preg_replace("/\s*\n\s*/", "\n", $sql));
}
/**
* Check bindings for illegal (non UTF-8) strings, like Binary data.
*
* @param $bindings
* @return mixed
*/
public function checkBindings($bindings)
{
foreach ($bindings as &$binding) {
if (is_string($binding) && !mb_check_encoding($binding, 'UTF-8')) {
$binding = '[BINARY DATA]';
}
}
return $bindings;
}
/**
* Make the bindings safe for outputting.
*
* @param array $bindings
* @return array
*/
public function escapeBindings($bindings)
{
foreach ($bindings as &$binding) {
$binding = htmlentities($binding, ENT_QUOTES, 'UTF-8', false);
}
return $bindings;
}
/**
* Format a source object.
*
* @param object|null $source If the backtrace is disabled, the $source will be null.
* @return string
*/
public function formatSource($source)
{
if (! is_object($source)) {
return '';
}
$parts = [];
if ($source->namespace) {
$parts['namespace'] = $source->namespace . '::';
}
$parts['name'] = $source->name;
$parts['line'] = ':' . $source->line;
return implode($parts);
}
}
<?php namespace Barryvdh\Debugbar;
class Facade extends \Illuminate\Support\Facades\Facade
{
/**
* {@inheritDoc}
*/
protected static function getFacadeAccessor()
{
return 'debugbar';
}
}
<?php namespace Barryvdh\Debugbar;
use DebugBar\DebugBar;
use DebugBar\JavascriptRenderer as BaseJavascriptRenderer;
use Illuminate\Routing\UrlGenerator;
/**
* {@inheritdoc}
*/
class JavascriptRenderer extends BaseJavascriptRenderer
{
// Use XHR handler by default, instead of jQuery
protected $ajaxHandlerBindToJquery = false;
protected $ajaxHandlerBindToXHR = true;
public function __construct(DebugBar $debugBar, $baseUrl = null, $basePath = null)
{
parent::__construct($debugBar, $baseUrl, $basePath);
$this->cssFiles['laravel'] = __DIR__ . '/Resources/laravel-debugbar.css';
$this->cssVendors['fontawesome'] = __DIR__ . '/Resources/vendor/font-awesome/style.css';
$this->jsFiles['laravel-sql'] = __DIR__ . '/Resources/sqlqueries/widget.js';
}
/**
* Set the URL Generator
*
* @param \Illuminate\Routing\UrlGenerator $url
* @deprecated
*/
public function setUrlGenerator($url)
{
}
/**
* {@inheritdoc}
*/
public function renderHead()
{
$cssRoute = route('debugbar.assets.css', [
'v' => $this->getModifiedTime('css')
]);
$jsRoute = route('debugbar.assets.js', [
'v' => $this->getModifiedTime('js')
]);
$cssRoute = preg_replace('/\Ahttps?:/', '', $cssRoute);
$jsRoute = preg_replace('/\Ahttps?:/', '', $jsRoute);
$html = "<link rel='stylesheet' type='text/css' property='stylesheet' href='{$cssRoute}'>";
$html .= "<script type='text/javascript' src='{$jsRoute}'></script>";
if ($this->isJqueryNoConflictEnabled()) {
$html .= '<script type="text/javascript">jQuery.noConflict(true);</script>' . "\n";
}
return $html;
}
/**
* Get the last modified time of any assets.
*
* @param string $type 'js' or 'css'
* @return int
*/
protected function getModifiedTime($type)
{
$files = $this->getAssets($type);
$latest = 0;
foreach ($files as $file) {
$mtime = filemtime($file);
if ($mtime > $latest) {
$latest = $mtime;
}
}
return $latest;
}
/**
* Return assets as a string
*
* @param string $type 'js' or 'css'
* @return string
*/
public function dumpAssetsToString($type)
{
$files = $this->getAssets($type);
$content = '';
foreach ($files as $file) {
$content .= file_get_contents($file) . "\n";
}
return $content;
}
/**
* Makes a URI relative to another
*
* @param string|array $uri
* @param string $root
* @return string
*/
protected function makeUriRelativeTo($uri, $root)
{
if (!$root) {
return $uri;
}
if (is_array($uri)) {
$uris = [];
foreach ($uri as $u) {
$uris[] = $this->makeUriRelativeTo($u, $root);
}
return $uris;
}
if (substr($uri, 0, 1) === '/' || preg_match('/^([a-zA-Z]+:\/\/|[a-zA-Z]:\/|[a-zA-Z]:\\\)/', $uri)) {
return $uri;
}
return rtrim($root, '/') . "/$uri";
}
}
<?php namespace Barryvdh\Debugbar;
use Laravel\Lumen\Application;
class LumenServiceProvider extends ServiceProvider
{
/** @var Application */
protected $app;
/**
* Get the active router.
*
* @return Application
*/
protected function getRouter()
{
return $this->app;
}
/**
* Get the config path
*
* @return string
*/
protected function getConfigPath()
{
return base_path('config/debugbar.php');
}
/**
* Register the Debugbar Middleware
*
* @param string $middleware
*/
protected function registerMiddleware($middleware)
{
$this->app->middleware([$middleware]);
}
/**
* Check the App Debug status
*/
protected function checkAppDebug()
{
return env('APP_DEBUG');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['debugbar', 'command.debugbar.clear'];
}
}
<?php namespace Barryvdh\Debugbar\Middleware;
use Error;
use Closure;
use Exception;
use Illuminate\Http\Request;
use Barryvdh\Debugbar\LaravelDebugbar;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Symfony\Component\Debug\Exception\FatalThrowableError;
class Debugbar
{
/**
* The App container
*
* @var Container
*/
protected $container;
/**
* The DebugBar instance
*
* @var LaravelDebugbar
*/
protected $debugbar;
/**
* Create a new middleware instance.
*
* @param Container $container
* @param LaravelDebugbar $debugbar
*/
public function __construct(Container $container, LaravelDebugbar $debugbar)
{
$this->container = $container;
$this->debugbar = $debugbar;
}
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
try {
/** @var \Illuminate\Http\Response $response */
$response = $next($request);
} catch (Exception $e) {
$response = $this->handleException($request, $e);
} catch (Error $error) {
$e = new FatalThrowableError($error);
$response = $this->handleException($request, $e);
}
// Modify the response to add the Debugbar
$this->debugbar->modifyResponse($request, $response);
return $response;
}
/**
* Handle the given exception.
*
* (Copy from Illuminate\Routing\Pipeline by Taylor Otwell)
*
* @param $passable
* @param Exception $e
* @return mixed
* @throws Exception
*/
protected function handleException($passable, Exception $e)
{
if (! $this->container->bound(ExceptionHandler::class) || ! $passable instanceof Request) {
throw $e;
}
$handler = $this->container->make(ExceptionHandler::class);
$handler->report($e);
return $handler->render($passable, $e);
}
}
# Font Squirrel Font-face Generator Configuration File
# Upload this file to the generator to recreate the settings
# you used to create these fonts.
{"mode":"expert","formats":["woff"],"tt_instructor":"keep","fallback":"none","fallback_custom":"100","options_subset":"none","subset_custom":"","subset_custom_range":"","subset_ot_features":"all","subset_ot_features_list":"","base64":"Y","css_stylesheet":"style.css","filename_suffix":"","emsquare":"2048","spacing_adjustment":"0","rememberme":"Y"}
\ No newline at end of file
This diff could not be displayed because it is too large.
<?php namespace Barryvdh\Debugbar;
use Illuminate\Routing\Router;
use Illuminate\Session\SessionManager;
class ServiceProvider extends \Illuminate\Support\ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$configPath = __DIR__ . '/../config/debugbar.php';
$this->mergeConfigFrom($configPath, 'debugbar');
$this->app->alias(
'DebugBar\DataFormatter\DataFormatter',
'DebugBar\DataFormatter\DataFormatterInterface'
);
$this->app->singleton('debugbar', function ($app) {
$debugbar = new LaravelDebugbar($app);
if ($app->bound(SessionManager::class)) {
$sessionManager = $app->make(SessionManager::class);
$httpDriver = new SymfonyHttpDriver($sessionManager);
$debugbar->setHttpDriver($httpDriver);
}
return $debugbar;
}
);
$this->app->alias('debugbar', 'Barryvdh\Debugbar\LaravelDebugbar');
$this->app->singleton('command.debugbar.clear',
function ($app) {
return new Console\ClearCommand($app['debugbar']);
}
);
$this->commands(['command.debugbar.clear']);
}
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$app = $this->app;
$configPath = __DIR__ . '/../config/debugbar.php';
$this->publishes([$configPath => $this->getConfigPath()], 'config');
// If enabled is null, set from the app.debug value
$enabled = $this->app['config']->get('debugbar.enabled');
if (is_null($enabled)) {
$enabled = $this->checkAppDebug();
}
if (! $enabled) {
return;
}
$routeConfig = [
'namespace' => 'Barryvdh\Debugbar\Controllers',
'prefix' => $this->app['config']->get('debugbar.route_prefix'),
'domain' => $this->app['config']->get('debugbar.route_domain'),
];
$this->getRouter()->group($routeConfig, function($router) {
$router->get('open', [
'uses' => 'OpenHandlerController@handle',
'as' => 'debugbar.openhandler',
]);
$router->get('clockwork/{id}', [
'uses' => 'OpenHandlerController@clockwork',
'as' => 'debugbar.clockwork',
]);
$router->get('assets/stylesheets', [
'uses' => 'AssetController@css',
'as' => 'debugbar.assets.css',
]);
$router->get('assets/javascript', [
'uses' => 'AssetController@js',
'as' => 'debugbar.assets.js',
]);
});
if ($app->runningInConsole() || $app->environment('testing')) {
return;
}
/** @var LaravelDebugbar $debugbar */
$debugbar = $this->app['debugbar'];
$debugbar->enable();
$debugbar->boot();
$this->registerMiddleware('Barryvdh\Debugbar\Middleware\Debugbar');
}
/**
* Get the active router.
*
* @return Router
*/
protected function getRouter()
{
return $this->app['router'];
}
/**
* Get the config path
*
* @return string
*/
protected function getConfigPath()
{
return config_path('debugbar.php');
}
/**
* Publish the config file
*
* @param string $configPath
*/
protected function publishConfig($configPath)
{
$this->publishes([$configPath => config_path('debugbar.php')], 'config');
}
/**
* Register the Debugbar Middleware
*
* @param string $middleware
*/
protected function registerMiddleware($middleware)
{
$kernel = $this->app['Illuminate\Contracts\Http\Kernel'];
$kernel->pushMiddleware($middleware);
}
/**
* Check the App Debug status
*/
protected function checkAppDebug()
{
return $this->app['config']->get('app.debug');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['debugbar', 'command.debugbar.clear'];
}
}
<?php
namespace Barryvdh\Debugbar\Storage;
use DebugBar\Storage\StorageInterface;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
/**
* Stores collected data into files
*/
class FilesystemStorage implements StorageInterface
{
protected $dirname;
protected $files;
protected $gc_lifetime = 24; // Hours to keep collected data;
protected $gc_probability = 5; // Probability of GC being run on a save request. (5/100)
/**
* @param \Illuminate\Filesystem\Filesystem $files The filesystem
* @param string $dirname Directories where to store files
*/
public function __construct($files, $dirname)
{
$this->files = $files;
$this->dirname = rtrim($dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
}
/**
* {@inheritDoc}
*/
public function save($id, $data)
{
if (!$this->files->isDirectory($this->dirname)) {
if ($this->files->makeDirectory($this->dirname, 0777, true)) {
$this->files->put($this->dirname . '.gitignore', "*\n!.gitignore");
} else {
throw new \Exception("Cannot create directory '$this->dirname'..");
}
}
try {
$this->files->put($this->makeFilename($id), json_encode($data));
} catch (\Exception $e) {
//TODO; error handling
}
// Randomly check if we should collect old files
if (rand(1, 100) <= $this->gc_probability) {
$this->garbageCollect();
}
}
/**
* Create the filename for the data, based on the id.
*
* @param $id
* @return string
*/
public function makeFilename($id)
{
return $this->dirname . basename($id) . ".json";
}
/**
* Delete files older then a certain age (gc_lifetime)
*/
protected function garbageCollect()
{
foreach (Finder::create()->files()->name('*.json')->date('< ' . $this->gc_lifetime . ' hour ago')->in(
$this->dirname
) as $file) {
$this->files->delete($file->getRealPath());
}
}
/**
* {@inheritDoc}
*/
public function get($id)
{
return json_decode($this->files->get($this->makeFilename($id)), true);
}
/**
* {@inheritDoc}
*/
public function find(array $filters = [], $max = 20, $offset = 0)
{
// Sort by modified time, newest first
$sort = function (\SplFileInfo $a, \SplFileInfo $b) {
return strcmp($b->getMTime(), $a->getMTime());
};
// Loop through .json files, filter the metadata and stop when max is found.
$i = 0;
$results = [];
foreach (Finder::create()->files()->name('*.json')->in($this->dirname)->sort($sort) as $file) {
if ($i++ < $offset && empty($filters)) {
$results[] = null;
continue;
}
$data = json_decode($file->getContents(), true);
$meta = $data['__meta'];
unset($data);
if ($this->filter($meta, $filters)) {
$results[] = $meta;
}
if (count($results) >= ($max + $offset)) {
break;
}
}
return array_slice($results, $offset, $max);
}
/**
* Filter the metadata for matches.
*
* @param $meta
* @param $filters
* @return bool
*/
protected function filter($meta, $filters)
{
foreach ($filters as $key => $value) {
if (!isset($meta[$key]) || fnmatch($value, $meta[$key]) === false) {
return false;
}
}
return true;
}
/**
* {@inheritDoc}
*/
public function clear()
{
foreach (Finder::create()->files()->name('*.json')->in($this->dirname) as $file) {
$this->files->delete($file->getRealPath());
}
}
}
<?php
namespace Barryvdh\Debugbar\Support\Clockwork;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\DataCollectorInterface;
use DebugBar\DataCollector\Renderable;
use Symfony\Component\HttpFoundation\Response;
/**
*
* Based on \Symfony\Component\HttpKernel\DataCollector\RequestDataCollector by Fabien Potencier <fabien@symfony.com>
*
*/
class ClockworkCollector extends DataCollector implements DataCollectorInterface, Renderable
{
/** @var \Symfony\Component\HttpFoundation\Request $request */
protected $request;
/** @var \Symfony\Component\HttpFoundation\Request $response */
protected $response;
/** @var \Symfony\Component\HttpFoundation\Session\SessionInterface $session */
protected $session;
/**
* Create a new SymfonyRequestCollector
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\HttpFoundation\Request $response
* @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
*/
public function __construct($request, $response, $session = null)
{
$this->request = $request;
$this->response = $response;
$this->session = $session;
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'clockwork';
}
/**
* {@inheritDoc}
*/
public function getWidgets()
{
return null;
}
/**
* {@inheritdoc}
*/
public function collect()
{
$request = $this->request;
$response = $this->response;
$data = [
'getData' => $request->query->all(),
'postData' => $request->request->all(),
'headers' => $request->headers->all(),
'cookies' => $request->cookies->all(),
'uri' => $request->getRequestUri(),
'method' => $request->getMethod(),
'responseStatus' => $response->getStatusCode(),
];
if ($this->session) {
$sessionAttributes = [];
foreach ($this->session->all() as $key => $value) {
$sessionAttributes[$key] = $value;
}
$data['sessionData'] = $sessionAttributes;
}
if (isset($data['postData']['php-auth-pw'])) {
$data['postData']['php-auth-pw'] = '******';
}
if (isset($data['postData']['PHP_AUTH_PW'])) {
$data['postData']['PHP_AUTH_PW'] = '******';
}
return $data;
}
}
<?php namespace Barryvdh\Debugbar\Support\Clockwork;
class Converter {
/**
* Convert the phpdebugbar data to Clockwork format.
*
* @param array $data
* @return array
*/
public function convert($data)
{
$meta = $data['__meta'];
// Default output
$output = [
'id' => $meta['id'],
'method' => $meta['method'],
'uri' => $meta['uri'],
'time' => $meta['utime'],
'headers' => [],
'cookies' => [],
'emailsData' => [],
'getData' => [],
'log' => [],
'postData' => [],
'sessionData' => [],
'timelineData' => [],
'viewsData' => [],
'controller' => null,
'responseTime' => null,
'responseStatus' => null,
'responseDuration' => 0,
];
if (isset($data['clockwork'])) {
$output = array_merge($output, $data['clockwork']);
}
if (isset($data['time'])) {
$time = $data['time'];
$output['time'] = $time['start'];
$output['responseTime'] = $time['end'];
$output['responseDuration'] = $time['duration'] * 1000;
foreach($time['measures'] as $measure) {
$output['timelineData'][] = [
'data' => [],
'description' => $measure['label'],
'duration' => $measure['duration'] * 1000,
'end' => $measure['end'],
'start' => $measure['start'],
'relative_start' => $measure['start'] - $time['start'],
];
}
}
if (isset($data['route'])) {
$route = $data['route'];
$controller = null;
if (isset($route['controller'])) {
$controller = $route['controller'];
} elseif (isset($route['uses'])) {
$controller = $route['uses'];
}
$output['controller'] = $controller;
list($method, $uri) = explode(' ', $route['uri'], 2);
$output['routes'][] = [
'action' => $controller,
'after' => isset($route['after']) ? $route['after'] : null,
'before' => isset($route['before']) ? $route['before'] : null,
'method' => $method,
'name' => isset($route['as']) ? $route['as'] : null,
'uri' => $uri,
];
}
if (isset($data['messages'])) {
foreach($data['messages']['messages'] as $message) {
$output['log'][] = [
'message' => $message['message'],
'time' => $message['time'],
'level' => $message['label'],
];
}
}
if (isset($data['queries'])) {
$queries = $data['queries'];
foreach($queries['statements'] as $statement){
$output['databaseQueries'][] = [
'query' => $statement['sql'],
'bindings' => $statement['params'],
'duration' => $statement['duration'] * 1000,
'connection' => $statement['connection']
];
}
$output['databaseDuration'] = $queries['accumulated_duration'] * 1000;
}
if (isset($data['views'])) {
foreach ($data['views']['templates'] as $view) {
$output['viewsData'][] = [
'description' => 'Rendering a view',
'duration' => 0,
'end' => 0,
'start' => 0,
'data' => [
'name' => $view['name'],
'data' => $view['params'],
],
];
}
}
if (isset($data['swiftmailer_mails'])) {
foreach($data['swiftmailer_mails']['mails'] as $mail) {
$output['emailsData'][] = [
'data' => [
'to' => $mail['to'],
'subject' => $mail['subject'],
'headers' => isset($mail['headers']) ? explode("\n", $mail['headers']) : null,
],
];
}
}
return $output;
}
}
<?php
namespace Barryvdh\Debugbar;
use DebugBar\HttpDriverInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
/**
* HTTP driver for Symfony Request/Session
*/
class SymfonyHttpDriver implements HttpDriverInterface
{
/** @var \Symfony\Component\HttpFoundation\Session\Session|\Illuminate\Contracts\Session\Session|\Illuminate\Session\SessionManager */
protected $session;
/** @var \Symfony\Component\HttpFoundation\Response */
protected $response;
public function __construct($session, $response = null)
{
$this->session = $session;
$this->response = $response;
}
/**
* {@inheritDoc}
*/
public function setHeaders(array $headers)
{
if (!is_null($this->response)) {
$this->response->headers->add($headers);
}
}
/**
* {@inheritDoc}
*/
public function isSessionStarted()
{
if (!$this->session->isStarted()) {
$this->session->start();
}
return $this->session->isStarted();
}
/**
* {@inheritDoc}
*/
public function setSessionValue($name, $value)
{
// In Laravel 5.4 the session changed to use their own custom implementation
// instead of the one from Symfony. One of the changes was the set method
// that was changed to put. Here we check if we are using the new one.
if (method_exists($this->session, 'driver') && $this->session->driver() instanceof \Illuminate\Contracts\Session\Session) {
$this->session->put($name, $value);
return;
}
$this->session->set($name, $value);
}
/**
* {@inheritDoc}
*/
public function hasSessionValue($name)
{
return $this->session->has($name);
}
/**
* {@inheritDoc}
*/
public function getSessionValue($name)
{
return $this->session->get($name);
}
/**
* {@inheritDoc}
*/
public function deleteSessionValue($name)
{
$this->session->remove($name);
}
}
<?php namespace Barryvdh\Debugbar\Twig\Extension;
use Illuminate\Foundation\Application;
use Twig_Environment;
use Twig_Extension;
use Twig_SimpleFunction;
/**
* Access Laravels auth class in your Twig templates.
*/
class Debug extends Twig_Extension
{
/**
* @var \Barryvdh\Debugbar\LaravelDebugbar
*/
protected $debugbar;
/**
* Create a new auth extension.
*
* @param \Illuminate\Foundation\Application $app
*/
public function __construct(Application $app)
{
if ($app->bound('debugbar')) {
$this->debugbar = $app['debugbar'];
} else {
$this->debugbar = null;
}
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'Laravel_Debugbar_Debug';
}
/**
* {@inheritDoc}
*/
public function getFunctions()
{
return [
new Twig_SimpleFunction(
'debug', [$this, 'debug'], ['needs_context' => true, 'needs_environment' => true]
),
];
}
/**
* Based on Twig_Extension_Debug / twig_var_dump
* (c) 2011 Fabien Potencier
*
* @param Twig_Environment $env
* @param $context
*/
public function debug(Twig_Environment $env, $context)
{
if (!$env->isDebug() || !$this->debugbar) {
return;
}
$count = func_num_args();
if (2 === $count) {
$data = [];
foreach ($context as $key => $value) {
if (is_object($value)) {
if (method_exists($value, 'toArray')) {
$data[$key] = $value->toArray();
} else {
$data[$key] = "Object (" . get_class($value) . ")";
}
} else {
$data[$key] = $value;
}
}
$this->debugbar->addMessage($data);
} else {
for ($i = 2; $i < $count; $i++) {
$this->debugbar->addMessage(func_get_arg($i));
}
}
return;
}
}
<?php namespace Barryvdh\Debugbar\Twig\Extension;
use DebugBar\DataFormatter\DataFormatterInterface;
use Twig_Environment;
use Twig_Extension;
use Twig_SimpleFunction;
/**
* Dump variables using the DataFormatter
*/
class Dump extends Twig_Extension
{
/**
* @var \DebugBar\DataFormatter\DataFormatter
*/
protected $formatter;
/**
* Create a new auth extension.
*
* @param \DebugBar\DataFormatter\DataFormatterInterface $formatter
*/
public function __construct(DataFormatterInterface $formatter)
{
$this->formatter = $formatter;
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'Laravel_Debugbar_Dump';
}
/**
* {@inheritDoc}
*/
public function getFunctions()
{
return [
new Twig_SimpleFunction(
'dump', [$this, 'dump'], ['is_safe' => ['html'], 'needs_context' => true, 'needs_environment' => true]
),
];
}
/**
* Based on Twig_Extension_Debug / twig_var_dump
* (c) 2011 Fabien Potencier
*
* @param Twig_Environment $env
* @param $context
*
* @return string
*/
public function dump(Twig_Environment $env, $context)
{
$output = '';
$count = func_num_args();
if (2 === $count) {
$data = [];
foreach ($context as $key => $value) {
if (is_object($value)) {
if (method_exists($value, 'toArray')) {
$data[$key] = $value->toArray();
} else {
$data[$key] = "Object (" . get_class($value) . ")";
}
} else {
$data[$key] = $value;
}
}
$output .= $this->formatter->formatVar($data);
} else {
for ($i = 2; $i < $count; $i++) {
$output .= $this->formatter->formatVar(func_get_arg($i));
}
}
return '<pre>'.$output.'</pre>';
}
}
<?php namespace Barryvdh\Debugbar\Twig\Extension;
use Barryvdh\Debugbar\Twig\TokenParser\StopwatchTokenParser;
use Illuminate\Foundation\Application;
use Twig_Extension;
/**
* Access Laravels auth class in your Twig templates.
* Based on Symfony\Bridge\Twig\Extension\StopwatchExtension
*/
class Stopwatch extends Twig_Extension
{
/**
* @var \Barryvdh\Debugbar\LaravelDebugbar
*/
protected $debugbar;
/**
* Create a new auth extension.
*
* @param \Illuminate\Foundation\Application $app
*/
public function __construct(Application $app)
{
if ($app->bound('debugbar')) {
$this->debugbar = $app['debugbar'];
} else {
$this->debugbar = null;
}
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'stopwatch';
}
public function getTokenParsers()
{
return [
/*
* {% stopwatch foo %}
* Some stuff which will be recorded on the timeline
* {% endstopwatch %}
*/
new StopwatchTokenParser($this->debugbar !== null),
];
}
public function getDebugbar()
{
return $this->debugbar;
}
}
<?php namespace Barryvdh\Debugbar\Twig\Node;
/**
* Represents a stopwatch node. Based on Symfony\Bridge\Twig\Node\StopwatchNode
*
* @author Wouter J <wouter@wouterj.nl>
*/
class StopwatchNode extends \Twig_Node
{
public function __construct(
\Twig_NodeInterface $name,
$body,
\Twig_Node_Expression_AssignName $var,
$lineno = 0,
$tag = null
) {
parent::__construct(['body' => $body, 'name' => $name, 'var' => $var], [], $lineno, $tag);
}
public function compile(\Twig_Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write('')
->subcompile($this->getNode('var'))
->raw(' = ')
->subcompile($this->getNode('name'))
->write(";\n")
->write("\$this->env->getExtension('stopwatch')->getDebugbar()->startMeasure(")
->subcompile($this->getNode('var'))
->raw(");\n")
->subcompile($this->getNode('body'))
->write("\$this->env->getExtension('stopwatch')->getDebugbar()->stopMeasure(")
->subcompile($this->getNode('var'))
->raw(");\n");
}
}
<?php namespace Barryvdh\Debugbar\Twig\TokenParser;
use Barryvdh\Debugbar\Twig\Node\StopwatchNode;
/**
* Token Parser for the stopwatch tag. Based on Symfony\Bridge\Twig\TokenParser\StopwatchTokenParser;
*
* @author Wouter J <wouter@wouterj.nl>
*/
class StopwatchTokenParser extends \Twig_TokenParser
{
protected $debugbarAvailable;
public function __construct($debugbarAvailable)
{
$this->debugbarAvailable = $debugbarAvailable;
}
public function parse(\Twig_Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
// {% stopwatch 'bar' %}
$name = $this->parser->getExpressionParser()->parseExpression();
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
// {% endstopwatch %}
$body = $this->parser->subparse([$this, 'decideStopwatchEnd'], true);
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
if ($this->debugbarAvailable) {
return new StopwatchNode(
$name,
$body,
new \Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()),
$lineno,
$this->getTag()
);
}
return $body;
}
public function getTag()
{
return 'stopwatch';
}
public function decideStopwatchEnd(\Twig_Token $token)
{
return $token->test('endstopwatch');
}
}
<?php
if (!function_exists('debugbar')) {
/**
* Get the Debugbar instance
*
* @return \Barryvdh\Debugbar\LaravelDebugbar
*/
function debugbar()
{
return app('debugbar');
}
}
if (!function_exists('debug')) {
/**
* Adds one or more messages to the MessagesCollector
*
* @param mixed ...$value
* @return string
*/
function debug($value)
{
$debugbar = app('debugbar');
foreach (func_get_args() as $value) {
$debugbar->addMessage($value, 'debug');
}
}
}
if (!function_exists('start_measure')) {
/**
* Starts a measure
*
* @param string $name Internal name, used to stop the measure
* @param string $label Public name
*/
function start_measure($name, $label = null)
{
app('debugbar')->startMeasure($name, $label);
}
}
if (!function_exists('stop_measure')) {
/**
* Stop a measure
*
* @param string $name Internal name, used to stop the measure
*/
function stop_measure($name)
{
app('debugbar')->stopMeasure($name);
}
}
if (!function_exists('add_measure')) {
/**
* Adds a measure
*
* @param string $label
* @param float $start
* @param float $end
*/
function add_measure($label, $start, $end)
{
app('debugbar')->addMeasure($label, $start, $end);
}
}
if (!function_exists('measure')) {
/**
* Utility function to measure the execution of a Closure
*
* @param string $label
* @param \Closure $closure
*/
function measure($label, \Closure $closure)
{
app('debugbar')->measure($label, $closure);
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePhpdebugbarStorageTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('phpdebugbar', function (Blueprint $table) {
$table->string('id');
$table->longText('data');
$table->string('meta_utime');
$table->dateTime('meta_datetime');
$table->string('meta_uri');
$table->string('meta_ip');
$table->string('meta_method');
$table->primary('id');
$table->index('meta_utime');
$table->index('meta_datetime');
$table->index('meta_uri');
$table->index('meta_ip');
$table->index('meta_method');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('phpdebugbar');
}
}
...@@ -18,4 +18,5 @@ return array( ...@@ -18,4 +18,5 @@ return array(
'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php', 'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php', '58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'4a1f389d6ce373bda9e57857d3b61c84' => $vendorDir . '/barryvdh/laravel-debugbar/src/helpers.php',
); );
...@@ -44,8 +44,10 @@ return array( ...@@ -44,8 +44,10 @@ return array(
'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'), 'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),
'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'), 'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'),
'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
'DebugBar\\' => array($vendorDir . '/maximebf/debugbar/src/DebugBar'),
'Cron\\' => array($vendorDir . '/mtdowling/cron-expression/src/Cron'), 'Cron\\' => array($vendorDir . '/mtdowling/cron-expression/src/Cron'),
'ClassPreloader\\' => array($vendorDir . '/classpreloader/classpreloader/src'), 'ClassPreloader\\' => array($vendorDir . '/classpreloader/classpreloader/src'),
'Barryvdh\\Debugbar\\' => array($vendorDir . '/barryvdh/laravel-debugbar/src'),
'App\\' => array($baseDir . '/app'), 'App\\' => array($baseDir . '/app'),
'' => array($vendorDir . '/nesbot/carbon/src'), '' => array($vendorDir . '/nesbot/carbon/src'),
); );
...@@ -19,6 +19,7 @@ class ComposerStaticInit207e6e0c20b937d4ce6e1ee236483f64 ...@@ -19,6 +19,7 @@ class ComposerStaticInit207e6e0c20b937d4ce6e1ee236483f64
'f0906e6318348a765ffb6eb24e0d0938' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Foundation/helpers.php', 'f0906e6318348a765ffb6eb24e0d0938' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Support/helpers.php', '58571171fd5812e6e447dce228f52f4d' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Support/helpers.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'4a1f389d6ce373bda9e57857d3b61c84' => __DIR__ . '/..' . '/barryvdh/laravel-debugbar/src/helpers.php',
); );
public static $prefixLengthsPsr4 = array ( public static $prefixLengthsPsr4 = array (
...@@ -101,12 +102,17 @@ class ComposerStaticInit207e6e0c20b937d4ce6e1ee236483f64 ...@@ -101,12 +102,17 @@ class ComposerStaticInit207e6e0c20b937d4ce6e1ee236483f64
array ( array (
'Dotenv\\' => 7, 'Dotenv\\' => 7,
'Doctrine\\Instantiator\\' => 22, 'Doctrine\\Instantiator\\' => 22,
'DebugBar\\' => 9,
), ),
'C' => 'C' =>
array ( array (
'Cron\\' => 5, 'Cron\\' => 5,
'ClassPreloader\\' => 15, 'ClassPreloader\\' => 15,
), ),
'B' =>
array (
'Barryvdh\\Debugbar\\' => 18,
),
'A' => 'A' =>
array ( array (
'App\\' => 4, 'App\\' => 4,
...@@ -269,6 +275,10 @@ class ComposerStaticInit207e6e0c20b937d4ce6e1ee236483f64 ...@@ -269,6 +275,10 @@ class ComposerStaticInit207e6e0c20b937d4ce6e1ee236483f64
array ( array (
0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator',
), ),
'DebugBar\\' =>
array (
0 => __DIR__ . '/..' . '/maximebf/debugbar/src/DebugBar',
),
'Cron\\' => 'Cron\\' =>
array ( array (
0 => __DIR__ . '/..' . '/mtdowling/cron-expression/src/Cron', 0 => __DIR__ . '/..' . '/mtdowling/cron-expression/src/Cron',
...@@ -277,6 +287,10 @@ class ComposerStaticInit207e6e0c20b937d4ce6e1ee236483f64 ...@@ -277,6 +287,10 @@ class ComposerStaticInit207e6e0c20b937d4ce6e1ee236483f64
array ( array (
0 => __DIR__ . '/..' . '/classpreloader/classpreloader/src', 0 => __DIR__ . '/..' . '/classpreloader/classpreloader/src',
), ),
'Barryvdh\\Debugbar\\' =>
array (
0 => __DIR__ . '/..' . '/barryvdh/laravel-debugbar/src',
),
'App\\' => 'App\\' =>
array ( array (
0 => __DIR__ . '/../..' . '/app', 0 => __DIR__ . '/../..' . '/app',
......
...@@ -3866,5 +3866,119 @@ ...@@ -3866,5 +3866,119 @@
} }
], ],
"description": "用于给钉钉自定义机器人发送消息" "description": "用于给钉钉自定义机器人发送消息"
},
{
"name": "maximebf/debugbar",
"version": "1.13.1",
"version_normalized": "1.13.1.0",
"source": {
"type": "git",
"url": "https://github.com/maximebf/php-debugbar.git",
"reference": "afee79a236348e39a44cb837106b7c5b4897ac2a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/afee79a236348e39a44cb837106b7c5b4897ac2a",
"reference": "afee79a236348e39a44cb837106b7c5b4897ac2a",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "^1.0",
"symfony/var-dumper": "^2.6|^3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0|^5.0"
},
"suggest": {
"kriswallsmith/assetic": "The best way to manage assets",
"monolog/monolog": "Log using Monolog",
"predis/predis": "Redis storage"
},
"time": "2017-01-05T08:46:19+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.13-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"DebugBar\\": "src/DebugBar/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maxime Bouroumeau-Fuseau",
"email": "maxime.bouroumeau@gmail.com",
"homepage": "http://maximebf.com"
},
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "Debug bar in the browser for php application",
"homepage": "https://github.com/maximebf/php-debugbar",
"keywords": [
"debug",
"debugbar"
]
},
{
"name": "barryvdh/laravel-debugbar",
"version": "v2.4.3",
"version_normalized": "2.4.3.0",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "d7c88f08131f6404cb714f3f6cf0642f6afa3903"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/d7c88f08131f6404cb714f3f6cf0642f6afa3903",
"reference": "d7c88f08131f6404cb714f3f6cf0642f6afa3903",
"shasum": ""
},
"require": {
"illuminate/support": "5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
"maximebf/debugbar": "~1.13.0",
"php": ">=5.5.9",
"symfony/finder": "~2.7|~3.0"
},
"time": "2017-07-21T11:56:48+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Barryvdh\\Debugbar\\": "src/"
},
"files": [
"src/helpers.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "PHP Debugbar integration for Laravel",
"keywords": [
"debug",
"debugbar",
"laravel",
"profiler",
"webprofiler"
]
} }
] ]
Copyright (C) 2013 Maxime Bouroumeau-Fuseau
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
{
"name": "maximebf/debugbar",
"description": "Debug bar in the browser for php application",
"keywords": ["debug", "debugbar"],
"homepage": "https://github.com/maximebf/php-debugbar",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Maxime Bouroumeau-Fuseau",
"email": "maxime.bouroumeau@gmail.com",
"homepage": "http://maximebf.com"
},
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"require": {
"php": ">=5.3.0",
"psr/log": "^1.0",
"symfony/var-dumper": "^2.6|^3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0|^5.0"
},
"autoload": {
"psr-4": {
"DebugBar\\": "src/DebugBar/"
}
},
"suggest": {
"kriswallsmith/assetic": "The best way to manage assets",
"monolog/monolog": "Log using Monolog",
"predis/predis": "Redis storage"
},
"extra": {
"branch-alias": {
"dev-master": "1.13-dev"
}
}
}
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use CacheCache\Cache;
use CacheCache\LoggingBackend;
use Monolog\Logger;
/**
* Collects CacheCache operations
*
* http://maximebf.github.io/CacheCache/
*
* Example:
* <code>
* $debugbar->addCollector(new CacheCacheCollector(CacheManager::get('default')));
* // or
* $debugbar->addCollector(new CacheCacheCollector());
* $debugbar['cache']->addCache(CacheManager::get('default'));
* </code>
*/
class CacheCacheCollector extends MonologCollector
{
protected $logger;
/**
* CacheCacheCollector constructor.
* @param Cache|null $cache
* @param Logger|null $logger
* @param bool $level
* @param bool $bubble
*/
public function __construct(Cache $cache = null, Logger $logger = null, $level = Logger::DEBUG, $bubble = true)
{
parent::__construct(null, $level, $bubble);
if ($logger === null) {
$logger = new Logger('Cache');
}
$this->logger = $logger;
if ($cache !== null) {
$this->addCache($cache);
}
}
/**
* @param Cache $cache
*/
public function addCache(Cache $cache)
{
$backend = $cache->getBackend();
if (!($backend instanceof LoggingBackend)) {
$backend = new LoggingBackend($backend, $this->logger);
}
$cache->setBackend($backend);
$this->addLogger($backend->getLogger());
}
/**
* @return string
*/
public function getName()
{
return 'cache';
}
}
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use DebugBar\DebugBarException;
use Doctrine\DBAL\Logging\DebugStack;
use Doctrine\ORM\EntityManager;
/**
* Collects Doctrine queries
*
* http://doctrine-project.org
*
* Uses the DebugStack logger to collects data about queries
*
* <code>
* $debugStack = new Doctrine\DBAL\Logging\DebugStack();
* $entityManager->getConnection()->getConfiguration()->setSQLLogger($debugStack);
* $debugbar->addCollector(new DoctrineCollector($debugStack));
* </code>
*/
class DoctrineCollector extends DataCollector implements Renderable, AssetProvider
{
protected $debugStack;
/**
* DoctrineCollector constructor.
* @param $debugStackOrEntityManager
* @throws DebugBarException
*/
public function __construct($debugStackOrEntityManager)
{
if ($debugStackOrEntityManager instanceof EntityManager) {
$debugStackOrEntityManager = $debugStackOrEntityManager->getConnection()->getConfiguration()->getSQLLogger();
}
if (!($debugStackOrEntityManager instanceof DebugStack)) {
throw new DebugBarException("'DoctrineCollector' requires an 'EntityManager' or 'DebugStack' object");
}
$this->debugStack = $debugStackOrEntityManager;
}
/**
* @return array
*/
public function collect()
{
$queries = array();
$totalExecTime = 0;
foreach ($this->debugStack->queries as $q) {
$queries[] = array(
'sql' => $q['sql'],
'params' => (object) $q['params'],
'duration' => $q['executionMS'],
'duration_str' => $this->formatDuration($q['executionMS'])
);
$totalExecTime += $q['executionMS'];
}
return array(
'nb_statements' => count($queries),
'accumulated_duration' => $totalExecTime,
'accumulated_duration_str' => $this->formatDuration($totalExecTime),
'statements' => $queries
);
}
/**
* @return string
*/
public function getName()
{
return 'doctrine';
}
/**
* @return array
*/
public function getWidgets()
{
return array(
"database" => array(
"icon" => "arrow-right",
"widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
"map" => "doctrine",
"default" => "[]"
),
"database:badge" => array(
"map" => "doctrine.nb_statements",
"default" => 0
)
);
}
/**
* @return array
*/
public function getAssets()
{
return array(
'css' => 'widgets/sqlqueries/widget.css',
'js' => 'widgets/sqlqueries/widget.js'
);
}
}
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use DebugBar\DataCollector\DataCollectorInterface;
use DebugBar\DataCollector\MessagesAggregateInterface;
use DebugBar\DataCollector\Renderable;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
/**
* A monolog handler as well as a data collector
*
* https://github.com/Seldaek/monolog
*
* <code>
* $debugbar->addCollector(new MonologCollector($logger));
* </code>
*/
class MonologCollector extends AbstractProcessingHandler implements DataCollectorInterface, Renderable, MessagesAggregateInterface
{
protected $name;
protected $records = array();
/**
* @param Logger $logger
* @param int $level
* @param boolean $bubble
* @param string $name
*/
public function __construct(Logger $logger = null, $level = Logger::DEBUG, $bubble = true, $name = 'monolog')
{
parent::__construct($level, $bubble);
$this->name = $name;
if ($logger !== null) {
$this->addLogger($logger);
}
}
/**
* Adds logger which messages you want to log
*
* @param Logger $logger
*/
public function addLogger(Logger $logger)
{
$logger->pushHandler($this);
}
/**
* @param array $record
*/
protected function write(array $record)
{
$this->records[] = array(
'message' => $record['formatted'],
'is_string' => true,
'label' => strtolower($record['level_name']),
'time' => $record['datetime']->format('U')
);
}
/**
* @return array
*/
public function getMessages()
{
return $this->records;
}
/**
* @return array
*/
public function collect()
{
return array(
'count' => count($this->records),
'records' => $this->records
);
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return array
*/
public function getWidgets()
{
$name = $this->getName();
return array(
$name => array(
"icon" => "suitcase",
"widget" => "PhpDebugBar.Widgets.MessagesWidget",
"map" => "$name.records",
"default" => "[]"
),
"$name:badge" => array(
"map" => "$name.count",
"default" => "null"
)
);
}
}
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Connection\ProfilerConnectionWrapper;
use Propel\Runtime\Propel;
use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
/**
* A Propel logger which acts as a data collector
*
* http://propelorm.org/
*
* Will log queries and display them using the SQLQueries widget.
*
* Example:
* <code>
* $debugbar->addCollector(new \DebugBar\Bridge\Propel2Collector(\Propel\Runtime\Propel::getServiceContainer()->getReadConnection()));
* </code>
*/
class Propel2Collector extends DataCollector implements Renderable, AssetProvider
{
/**
* @var null|TestHandler
*/
protected $handler = null;
/**
* @var null|Logger
*/
protected $logger = null;
/**
* @var array
*/
protected $config = array();
/**
* @var array
*/
protected $errors = array();
/**
* @var int
*/
protected $queryCount = 0;
/**
* @param ConnectionInterface $connection Propel connection
*/
public function __construct(
ConnectionInterface $connection,
array $logMethods = array(
'beginTransaction',
'commit',
'rollBack',
'forceRollBack',
'exec',
'query',
'execute'
)
) {
if ($connection instanceof ProfilerConnectionWrapper) {
$connection->setLogMethods($logMethods);
$this->config = $connection->getProfiler()->getConfiguration();
$this->handler = new TestHandler();
if ($connection->getLogger() instanceof Logger) {
$this->logger = $connection->getLogger();
$this->logger->pushHandler($this->handler);
} else {
$this->errors[] = 'Supported only monolog logger';
}
} else {
$this->errors[] = 'You need set ProfilerConnectionWrapper';
}
}
/**
* @return TestHandler|null
*/
public function getHandler()
{
return $this->handler;
}
/**
* @return array
*/
public function getConfig()
{
return $this->config;
}
/**
* @return Logger|null
*/
public function getLogger()
{
return $this->logger;
}
/**
* @return LoggerInterface
*/
protected function getDefaultLogger()
{
return Propel::getServiceContainer()->getLogger();
}
/**
* @return int
*/
protected function getQueryCount()
{
return $this->queryCount;
}
/**
* @param array $records
* @param array $config
* @return array
*/
protected function getStatements($records, $config)
{
$statements = array();
foreach ($records as $record) {
$duration = null;
$memory = null;
$isSuccess = ( LogLevel::INFO === strtolower($record['level_name']) );
$detailsCount = count($config['details']);
$parameters = explode($config['outerGlue'], $record['message'], $detailsCount + 1);
if (count($parameters) === ($detailsCount + 1)) {
$parameters = array_map('trim', $parameters);
$_details = array();
foreach (array_splice($parameters, 0, $detailsCount) as $string) {
list($key, $value) = array_map('trim', explode($config['innerGlue'], $string, 2));
$_details[$key] = $value;
}
$details = array();
foreach ($config['details'] as $key => $detail) {
if (isset($_details[$detail['name']])) {
$value = $_details[$detail['name']];
if ('time' === $key) {
if (substr_count($value, 'ms')) {
$value = (float)$value / 1000;
} else {
$value = (float)$value;
}
} else {
$suffixes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
$suffix = substr($value, -2);
$i = array_search($suffix, $suffixes, true);
$i = (false === $i) ? 0 : $i;
$value = ((float)$value) * pow(1024, $i);
}
$details[$key] = $value;
}
}
if (isset($details['time'])) {
$duration = $details['time'];
}
if (isset($details['memDelta'])) {
$memory = $details['memDelta'];
}
$message = end($parameters);
if ($isSuccess) {
$this->queryCount++;
}
} else {
$message = $record['message'];
}
$statement = array(
'sql' => $message,
'is_success' => $isSuccess,
'duration' => $duration,
'duration_str' => $this->getDataFormatter()->formatDuration($duration),
'memory' => $memory,
'memory_str' => $this->getDataFormatter()->formatBytes($memory),
);
if (false === $isSuccess) {
$statement['sql'] = '';
$statement['error_code'] = $record['level'];
$statement['error_message'] = $message;
}
$statements[] = $statement;
}
return $statements;
}
/**
* @return array
*/
public function collect()
{
if (count($this->errors)) {
return array(
'statements' => array_map(function ($message) {
return array('sql' => '', 'is_success' => false, 'error_code' => 500, 'error_message' => $message);
}, $this->errors),
'nb_statements' => 0,
'nb_failed_statements' => count($this->errors),
);
}
if ($this->getHandler() === null) {
return array();
}
$statements = $this->getStatements($this->getHandler()->getRecords(), $this->getConfig());
$failedStatement = count(array_filter($statements, function ($statement) {
return false === $statement['is_success'];
}));
$accumulatedDuration = array_reduce($statements, function ($accumulatedDuration, $statement) {
$time = isset($statement['duration']) ? $statement['duration'] : 0;
return $accumulatedDuration += $time;
});
$memoryUsage = array_reduce($statements, function ($memoryUsage, $statement) {
$time = isset($statement['memory']) ? $statement['memory'] : 0;
return $memoryUsage += $time;
});
return array(
'nb_statements' => $this->getQueryCount(),
'nb_failed_statements' => $failedStatement,
'accumulated_duration' => $accumulatedDuration,
'accumulated_duration_str' => $this->getDataFormatter()->formatDuration($accumulatedDuration),
'memory_usage' => $memoryUsage,
'memory_usage_str' => $this->getDataFormatter()->formatBytes($memoryUsage),
'statements' => $statements
);
}
/**
* @return string
*/
public function getName()
{
$additionalName = '';
if ($this->getLogger() !== $this->getDefaultLogger()) {
$additionalName = ' ('.$this->getLogger()->getName().')';
}
return 'propel2'.$additionalName;
}
/**
* @return array
*/
public function getWidgets()
{
return array(
$this->getName() => array(
'icon' => 'bolt',
'widget' => 'PhpDebugBar.Widgets.SQLQueriesWidget',
'map' => $this->getName(),
'default' => '[]'
),
$this->getName().':badge' => array(
'map' => $this->getName().'.nb_statements',
'default' => 0
),
);
}
/**
* @return array
*/
public function getAssets()
{
return array(
'css' => 'widgets/sqlqueries/widget.css',
'js' => 'widgets/sqlqueries/widget.js'
);
}
}
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use BasicLogger;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Propel;
use PropelConfiguration;
use PropelPDO;
use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
/**
* A Propel logger which acts as a data collector
*
* http://propelorm.org/
*
* Will log queries and display them using the SQLQueries widget.
* You can provide a LoggerInterface object to forward non-query related message to.
*
* Example:
* <code>
* $debugbar->addCollector(new PropelCollector($debugbar['messages']));
* PropelCollector::enablePropelProfiling();
* </code>
*/
class PropelCollector extends DataCollector implements BasicLogger, Renderable, AssetProvider
{
protected $logger;
protected $statements = array();
protected $accumulatedTime = 0;
protected $peakMemory = 0;
/**
* Sets the needed configuration option in propel to enable query logging
*
* @param PropelConfiguration $config Apply profiling on a specific config
*/
public static function enablePropelProfiling(PropelConfiguration $config = null)
{
if ($config === null) {
$config = Propel::getConfiguration(PropelConfiguration::TYPE_OBJECT);
}
$config->setParameter('debugpdo.logging.details.method.enabled', true);
$config->setParameter('debugpdo.logging.details.time.enabled', true);
$config->setParameter('debugpdo.logging.details.mem.enabled', true);
$allMethods = array(
'PropelPDO::__construct', // logs connection opening
'PropelPDO::__destruct', // logs connection close
'PropelPDO::exec', // logs a query
'PropelPDO::query', // logs a query
'PropelPDO::beginTransaction', // logs a transaction begin
'PropelPDO::commit', // logs a transaction commit
'PropelPDO::rollBack', // logs a transaction rollBack (watch out for the capital 'B')
'DebugPDOStatement::execute', // logs a query from a prepared statement
);
$config->setParameter('debugpdo.logging.methods', $allMethods, false);
}
/**
* @param LoggerInterface $logger A logger to forward non-query log lines to
* @param PropelPDO $conn Bound this collector to a connection only
*/
public function __construct(LoggerInterface $logger = null, PropelPDO $conn = null)
{
if ($conn) {
$conn->setLogger($this);
} else {
Propel::setLogger($this);
}
$this->logger = $logger;
$this->logQueriesToLogger = false;
}
public function setLogQueriesToLogger($enable = true)
{
$this->logQueriesToLogger = $enable;
return $this;
}
public function isLogQueriesToLogger()
{
return $this->logQueriesToLogger;
}
public function emergency($m)
{
$this->log($m, Propel::LOG_EMERG);
}
public function alert($m)
{
$this->log($m, Propel::LOG_ALERT);
}
public function crit($m)
{
$this->log($m, Propel::LOG_CRIT);
}
public function err($m)
{
$this->log($m, Propel::LOG_ERR);
}
public function warning($m)
{
$this->log($m, Propel::LOG_WARNING);
}
public function notice($m)
{
$this->log($m, Propel::LOG_NOTICE);
}
public function info($m)
{
$this->log($m, Propel::LOG_INFO);
}
public function debug($m)
{
$this->log($m, Propel::LOG_DEBUG);
}
public function log($message, $severity = null)
{
if (strpos($message, 'DebugPDOStatement::execute') !== false) {
list($sql, $duration_str) = $this->parseAndLogSqlQuery($message);
if (!$this->logQueriesToLogger) {
return;
}
$message = "$sql ($duration_str)";
}
if ($this->logger !== null) {
$this->logger->log($this->convertLogLevel($severity), $message);
}
}
/**
* Converts Propel log levels to PSR log levels
*
* @param int $level
* @return string
*/
protected function convertLogLevel($level)
{
$map = array(
Propel::LOG_EMERG => LogLevel::EMERGENCY,
Propel::LOG_ALERT => LogLevel::ALERT,
Propel::LOG_CRIT => LogLevel::CRITICAL,
Propel::LOG_ERR => LogLevel::ERROR,
Propel::LOG_WARNING => LogLevel::WARNING,
Propel::LOG_NOTICE => LogLevel::NOTICE,
Propel::LOG_DEBUG => LogLevel::DEBUG
);
return $map[$level];
}
/**
* Parse a log line to extract query information
*
* @param string $message
*/
protected function parseAndLogSqlQuery($message)
{
$parts = explode('|', $message, 4);
$sql = trim($parts[3]);
$duration = 0;
if (preg_match('/([0-9]+\.[0-9]+)/', $parts[1], $matches)) {
$duration = (float) $matches[1];
}
$memory = 0;
if (preg_match('/([0-9]+\.[0-9]+) ([A-Z]{1,2})/', $parts[2], $matches)) {
$memory = (float) $matches[1];
if ($matches[2] == 'KB') {
$memory *= 1024;
} elseif ($matches[2] == 'MB') {
$memory *= 1024 * 1024;
}
}
$this->statements[] = array(
'sql' => $sql,
'is_success' => true,
'duration' => $duration,
'duration_str' => $this->formatDuration($duration),
'memory' => $memory,
'memory_str' => $this->formatBytes($memory)
);
$this->accumulatedTime += $duration;
$this->peakMemory = max($this->peakMemory, $memory);
return array($sql, $this->formatDuration($duration));
}
public function collect()
{
return array(
'nb_statements' => count($this->statements),
'nb_failed_statements' => 0,
'accumulated_duration' => $this->accumulatedTime,
'accumulated_duration_str' => $this->formatDuration($this->accumulatedTime),
'peak_memory_usage' => $this->peakMemory,
'peak_memory_usage_str' => $this->formatBytes($this->peakMemory),
'statements' => $this->statements
);
}
public function getName()
{
return 'propel';
}
public function getWidgets()
{
return array(
"propel" => array(
"icon" => "bolt",
"widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
"map" => "propel",
"default" => "[]"
),
"propel:badge" => array(
"map" => "propel.nb_statements",
"default" => 0
)
);
}
public function getAssets()
{
return array(
'css' => 'widgets/sqlqueries/widget.css',
'js' => 'widgets/sqlqueries/widget.js'
);
}
}
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use DebugBar\DataCollector\MessagesCollector;
use Psr\Log\LogLevel;
use Slim\Log;
use Slim\Slim;
/**
* Collects messages from a Slim logger
*
* http://slimframework.com
*/
class SlimCollector extends MessagesCollector
{
protected $slim;
protected $originalLogWriter;
public function __construct(Slim $slim)
{
$this->slim = $slim;
if ($log = $slim->getLog()) {
$this->originalLogWriter = $log->getWriter();
$log->setWriter($this);
$log->setEnabled(true);
}
}
public function write($message, $level)
{
if ($this->originalLogWriter) {
$this->originalLogWriter->write($message, $level);
}
$this->addMessage($message, $this->getLevelName($level));
}
protected function getLevelName($level)
{
$map = array(
Log::EMERGENCY => LogLevel::EMERGENCY,
Log::ALERT => LogLevel::ALERT,
Log::CRITICAL => LogLevel::CRITICAL,
Log::ERROR => LogLevel::ERROR,
Log::WARN => LogLevel::WARNING,
Log::NOTICE => LogLevel::NOTICE,
Log::INFO => LogLevel::INFO,
Log::DEBUG => LogLevel::DEBUG
);
return $map[$level];
}
public function getName()
{
return 'slim';
}
}
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge\SwiftMailer;
use DebugBar\DataCollector\MessagesCollector;
use Swift_Mailer;
use Swift_Plugins_Logger;
use Swift_Plugins_LoggerPlugin;
/**
* Collects log messages
*
* http://swiftmailer.org/
*/
class SwiftLogCollector extends MessagesCollector implements Swift_Plugins_Logger
{
public function __construct(Swift_Mailer $mailer)
{
$mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($this));
}
public function add($entry)
{
$this->addMessage($entry);
}
public function dump()
{
return implode(PHP_EOL, $this->_log);
}
public function getName()
{
return 'swiftmailer_logs';
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment