├── .codecov.yml ├── .editorconfig ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .scrutinizer.yml ├── .travis.yml ├── .upgrade.yml ├── LICENSE ├── README.md ├── _config.php ├── _config ├── debugbar.yml └── debugbar_cache.yml ├── assets ├── debugbar.css ├── debugbar.js ├── openhandler.css ├── openhandler.js ├── vendor │ ├── font-awesome │ │ ├── css │ │ │ └── font-awesome.min.css │ │ └── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ ├── highlightjs │ │ ├── highlight.pack.js │ │ └── styles │ │ │ └── github.css │ └── jquery │ │ └── dist │ │ └── jquery.min.js ├── widgets.css ├── widgets.js └── widgets │ ├── mails │ ├── widget.css │ └── widget.js │ ├── sqlqueries │ ├── widget.css │ └── widget.js │ └── templates │ ├── widget.css │ └── widget.js ├── code ├── Aspects │ └── CacheAfterCallAspect.php ├── Bridge │ ├── MonologCollector.php │ └── SymfonyMailer │ │ └── SymfonyMailerCollector.php ├── Collector │ ├── CacheCollector.php │ ├── ConfigCollector.php │ ├── DatabaseCollector.php │ ├── HeaderCollector.php │ ├── PartialCacheCollector.php │ ├── PhpInfoCollector.php │ ├── SilverStripeCollector.php │ └── TimeDataCollector.php ├── DebugBar.php ├── DebugBarController.php ├── DebugBarUtils.php ├── Extension │ ├── ControllerExtension.php │ ├── DebugMailerExtension.php │ ├── LeftAndMainExtension.php │ └── ProxyDBExtension.php ├── Messages │ └── LogFormatter.php ├── Middleware │ └── DebugBarMiddleware.php └── Proxy │ ├── CacheProxy.php │ ├── ConfigManifestProxy.php │ ├── DeltaConfigManifestProxy.php │ ├── ProxyConfigCollectionInterface.php │ └── SSViewerProxy.php ├── composer.json ├── css └── custom.css ├── docs └── _images │ ├── database-duplicates.png │ ├── database-long-running.png │ ├── database-query-threshold.png │ ├── database.png │ ├── messages.png │ ├── other.png │ ├── screenshot.png │ ├── templateCache.png │ ├── templates.png │ └── timeline.png ├── javascript ├── config │ ├── widget.css │ └── widget.js ├── sqlqueries │ ├── widget.css │ └── widget.js └── widgets.js ├── phpcs.xml.dist ├── phpunit.xml.dist └── tests ├── Aspects └── CacheAfterCallAspectTest.php ├── Collector ├── ConfigCollectorTest.php ├── DatabaseCollectorTest.php ├── PartialCacheCollectorTest.php ├── PhpInfoCollectorTest.php ├── SilverStripeCollectorTest.php └── TimeDataCollectorTest.php ├── ControllerTest.php ├── DebugBarTest.php ├── Extension ├── ControllerExtensionTest.php ├── LeftAndMainExtensionTest.php └── ProxyDBExtensionTest.php ├── Messages └── LogFormatterTest.php └── Proxy └── SSViewerProxyTest.php /.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: off 2 | coverage: 3 | status: 4 | project: off 5 | patch: off 6 | 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # For more information about the properties used in this file, 2 | # please see the EditorConfig documentation: 3 | # http://editorconfig.org 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 4 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [{*.yml,package.json}] 14 | indent_size = 2 15 | 16 | # The indent size used in the package.json file cannot be changed: 17 | # https://github.com/npm/npm/pull/3180#issuecomment-16336516 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | # Every Friday at 10:20am UTC 8 | schedule: 9 | - cron: '20 10 * * 5' 10 | 11 | jobs: 12 | ci: 13 | name: CI 14 | # Only run cron on the silverstripe account 15 | if: (github.event_name == 'schedule' && github.repository_owner == 'lekoala') || (github.event_name != 'schedule') 16 | uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .php_cs.cache 2 | .idea 3 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | inherit: true 2 | 3 | build: 4 | image: default-bionic 5 | environment: 6 | php: 8.1.2 7 | nodes: 8 | analysis: 9 | tests: 10 | override: [php-scrutinizer-run] 11 | 12 | checks: 13 | php: 14 | code_rating: true 15 | duplication: true 16 | 17 | filter: 18 | paths: [code/*, tests/*] 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | version: ~> 1.0 2 | 3 | import: 4 | - silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range.yml 5 | -------------------------------------------------------------------------------- /.upgrade.yml: -------------------------------------------------------------------------------- 1 | mappings: 2 | DebugBarDatabaseCollector: LeKoala\DebugBar\Collector\DatabaseCollector 3 | DebugBarSilverStripeCollector: LeKoala\DebugBar\Collector\SilverStripeCollector 4 | DebugBarTimeDataCollector: LeKoala\DebugBar\Collector\TimeDataCollector 5 | DebugBarControllerExtension: LeKoala\DebugBar\Extension\ControllerExtension 6 | DebugBarLeftAndMainExtension: LeKoala\DebugBar\Extension\LeftAndMainExtension 7 | DebugBarTemplateParserProxy: LeKoala\DebugBar\Proxy\TemplateParserProxy 8 | DebugBarController: LeKoala\DebugBar\DebugBarController 9 | DebugBar: LeKoala\DebugBar\DebugBar 10 | DebugBarRequestFilter: LeKoala\DebugBar\RequestFilter 11 | DebugBarControllerTest: LeKoala\DebugBar\Test\ControllerTest 12 | DebugBarDebugBarTest: LeKoala\DebugBar\Test\DebugBarTest 13 | DebugBarDatabaseCollectorTest: LeKoala\DebugBar\Test\Collector\DatabaseCollectorTest 14 | DebugBarSilverStripeCollectorTest: LeKoala\DebugBar\Test\Collector\SilverStripeCollectorTest 15 | DebugBarTimeDataCollectorTest: LeKoala\DebugBar\Test\Collector\TimeDataCollectorTest 16 | DebugBarControllerExtensionTest: LeKoala\DebugBar\Test\Extension\ControllerExtensionTest 17 | DebugBarLeftAndMainExtensionTest: LeKoala\DebugBar\Test\Extension\LeftAndMainExtensionTest 18 | DebugBarTemplateParserProxyTest: LeKoala\DebugBar\Test\Proxy\TemplateParserProxyTest 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Thomas Portelange 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /_config.php: -------------------------------------------------------------------------------- 1 | get(LoggerInterface::class)->info("Please remove call to d() in $file:$line"); 53 | return; 54 | } 55 | 56 | // Arguments passed to the function are stored in matches 57 | $src = file($file); 58 | if (!$src) { 59 | return; 60 | } 61 | $src_line = $src[$line - 1]; 62 | preg_match("/d\((.+)\)/", $src_line, $matches); 63 | 64 | // Find all arguments, ignore variables within parenthesis 65 | $arguments_name = array(); 66 | if (!empty($matches[1])) { 67 | $split = preg_split("/(?![^(]*\)),/", $matches[1]); 68 | if ($split) { 69 | $arguments_name = array_map('trim', $split); 70 | } 71 | } 72 | 73 | // Display data nicely according to context 74 | $print = function (...$args) use ($isPlain) { 75 | if (!$isPlain) { 76 | echo '
';
 77 |             }
 78 |             foreach ($args as $arg) {
 79 |                 if ($isPlain && $arg === "") {
 80 |                     $arg = "(empty)";
 81 |                 } elseif ($isPlain && $arg === null) {
 82 |                     $arg = "(null)";
 83 |                 } elseif (!is_string($arg)) {
 84 |                     // Avoid print_r on object as it can cause massive recursion
 85 |                     if (is_object($arg)) {
 86 |                         $arg = get_class($arg);
 87 |                     } else {
 88 |                         $arg = json_encode($arg, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR, 5);
 89 |                     }
 90 |                 }
 91 |                 $arg = trim($arg);
 92 |                 if (strlen($arg) > 255) {
 93 |                     $arg = substr($arg, 0, 252) . "...";
 94 |                 }
 95 |                 echo $arg . "\n";
 96 |             }
 97 |             if (!$isPlain) {
 98 |                 echo '
'; 99 | } 100 | }; 101 | 102 | // Display caller info 103 | $fileline = "$file:$line"; 104 | if (!$isPlain) { 105 | // Allow opening in ide 106 | $idePrefix = Environment::getEnv('IDE_PROTOCOL'); 107 | if (!$idePrefix) { 108 | $idePrefix = 'vscode'; 109 | } 110 | $idePlaceholder = $idePrefix . '://file/{file}:{line}'; 111 | $ideLink = str_replace(['{file}', '{line}'], [$file, $line], $idePlaceholder); 112 | $fileline = "$fileline"; 113 | } 114 | $print("$fileline ($caller)"); 115 | 116 | // Display data in a friendly manner 117 | if (empty($args)) { 118 | $arguments_name = array(); 119 | foreach ($bt as $trace) { 120 | if (!empty($trace['object'])) { 121 | $line = isset($trace['line']) ? $trace['line'] : 0; 122 | $function = isset($trace['function']) ? $trace['function'] : 'unknown function'; 123 | $arguments_name[] = $function . ':' . $line; 124 | $args[] = $trace['object']; 125 | } 126 | } 127 | } 128 | 129 | $i = 0; 130 | foreach ($args as $arg) { 131 | // Echo name of the variable 132 | $len = 20; 133 | $varname = isset($arguments_name[$i]) ? $arguments_name[$i] : null; 134 | if ($varname) { 135 | $print('Value for: ' . $varname); 136 | $len = strlen($varname); 137 | } 138 | // For ajax and cli requests, a good old print_r is much better 139 | if ($isPlain || !function_exists('dump')) { 140 | $print($arg); 141 | // Make a nice line between variables for readability 142 | if (count($args) > 1) { 143 | $print(str_repeat('-', $len)); 144 | } 145 | } else { 146 | if ($varname && is_string($arg) && strpos($varname, 'sql') !== false) { 147 | echo \LeKoala\DebugBar\DebugBarUtils::formatSql($arg); 148 | } else { 149 | dump($arg); 150 | } 151 | } 152 | $i++; 153 | } 154 | if ($doExit) { 155 | exit(); 156 | } 157 | } 158 | } 159 | 160 | // Add a simple log helper that provides a default priority 161 | if (!function_exists('l')) { 162 | /** 163 | * @param string|array $message 164 | * @param mixed $priority This can be skipped array can be used instead for extras 165 | * @param array $extras 166 | * @return void 167 | */ 168 | function l($message, $priority = \Monolog\Level::Debug, $extras = []) 169 | { 170 | if (!is_string($message)) { 171 | $message = json_encode((array) $message, JSON_THROW_ON_ERROR); 172 | } 173 | if (is_array($priority)) { 174 | $extras = $priority; 175 | $priority = \Monolog\Level::Debug; 176 | } 177 | $inst = Injector::inst()->get(LoggerInterface::class); 178 | $inst->log($priority, $message, $extras); 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /_config/debugbar.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Name: debugbar 3 | Before: 4 | - 'mysite' 5 | - 'app' 6 | After: 7 | - '#corecache' 8 | Only: 9 | environment: 'dev' 10 | --- 11 | LeKoala\DebugBar\DebugBar: 12 | enable_storage: true 13 | auto_debug: false 14 | ajax: false 15 | max_header_length: 2048 16 | check_local_ip: true 17 | find_source: true 18 | enabled_in_admin: true 19 | # Let DebugBar include jQuery. Set this to false to include your own jQuery version 20 | include_jquery: true 21 | # Maximum number of queries to display 22 | query_limit: 200 23 | # Number of DB queries before a warning will be displayed 24 | warn_query_limit: 100 25 | # When a warning is shown for a high number of DB queries, the following link will be used for a 26 | # performance guide 27 | performance_guide_link: https://docs.silverstripe.org/en/developer_guides/performance/ 28 | # Threshold (seconds) for how long a database query can run for before it will be shown as a warning 29 | warn_dbqueries_threshold_seconds: 1.0 30 | # Threshold (seconds) for what constitutes a *dangerously* long page request (upper limit) 31 | warn_request_time_seconds: 5.0 32 | # Ratio to divide the warning request time by to get the *warning* level 33 | warn_warning_ratio: 0.5 34 | # Hide FQN in the database profiling tab 35 | show_namespaces: false 36 | # Enable or disable collectors below 37 | config_collector: true 38 | config_track_empty: false 39 | db_collector: true 40 | db_save_csv: false 41 | cache_collector: true 42 | cache_collector_show_get: false 43 | partial_cache_collector: true 44 | email_collector: true 45 | header_collector: true 46 | # Threshold (seconds) for how long a template can take to render before issuing a warning 47 | # set 0 to disable 48 | template_rendering_warning_level: 2.0 49 | show_db_warning: true 50 | user_admin_only: false 51 | SilverStripe\Control\Director: 52 | rules: 53 | '__debugbar': 'LeKoala\DebugBar\DebugBarController' 54 | SilverStripe\Core\Injector\Injector: 55 | Symfony\Component\Cache\Psr16Cache: 56 | class: LeKoala\DebugBar\Proxy\CacheProxy 57 | SilverStripe\View\SSViewer: 58 | class: LeKoala\DebugBar\Proxy\SSViewerProxy 59 | DebugBarMiddleware: 60 | class: LeKoala\DebugBar\Middleware\DebugBarMiddleware 61 | SilverStripe\Control\Director: 62 | properties: 63 | Middlewares: 64 | DebugBarMiddleware: '%$DebugBarMiddleware' 65 | SilverStripe\Control\Controller: 66 | extensions: 67 | - LeKoala\DebugBar\Extension\ControllerExtension 68 | TractorCow\SilverStripeProxyDB\ProxyDBFactory: 69 | extensions: 70 | - LeKoala\DebugBar\Extension\ProxyDBExtension 71 | SilverStripe\Control\Email\MailerSubscriber: 72 | extensions: 73 | - LeKoala\DebugBar\Extension\DebugMailerExtension 74 | --- 75 | Only: 76 | moduleexists: silverstripe/admin 77 | --- 78 | SilverStripe\Admin\LeftAndMain: 79 | extensions: 80 | - LeKoala\DebugBar\Extension\LeftAndMainExtension 81 | -------------------------------------------------------------------------------- /_config/debugbar_cache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Name: debugbar_cache 3 | After: 4 | - '#corecache' 5 | Only: 6 | environment: 'dev' 7 | --- 8 | SilverStripe\Core\Injector\Injector: 9 | Psr\SimpleCache\CacheInterface.backend: 10 | factory: SilverStripe\Core\Cache\CacheFactory 11 | constructor: 12 | namespace: "cacheblock" 13 | defaultLifetime: 600 14 | Psr\SimpleCache\CacheInterface.cacheblock: '%$Psr\SimpleCache\CacheInterface.proxied' 15 | Psr\SimpleCache\CacheInterface.proxied: 16 | class: SilverStripe\Core\Injector\AopProxyService 17 | properties: 18 | proxied: '%$Psr\SimpleCache\CacheInterface.backend' 19 | afterCall: 20 | get: 21 | - '%$LeKoala\DebugBar\Aspects\CacheAfterCallAspect' 22 | -------------------------------------------------------------------------------- /assets/openhandler.css: -------------------------------------------------------------------------------- 1 | div.phpdebugbar-openhandler-overlay { 2 | position: fixed; 3 | left: 0; 4 | top: 0; 5 | width: 100%; 6 | height: 100%; 7 | background: #000; 8 | opacity: .3; 9 | z-index: 20000; 10 | } 11 | 12 | div.phpdebugbar-openhandler { 13 | position: fixed; 14 | margin: auto; 15 | top: 0; 16 | bottom: 0; 17 | left: 0; 18 | right: 0; 19 | width: 70%; 20 | height: 70%; 21 | background: #fff; 22 | color: #000; 23 | border: 2px solid #888; 24 | overflow: auto; 25 | z-index: 20001; 26 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif; 27 | font-size: 14px; 28 | padding-bottom: 10px; 29 | } 30 | div.phpdebugbar-openhandler a { 31 | color: #555; 32 | } 33 | div.phpdebugbar-openhandler .phpdebugbar-openhandler-header { 34 | background: #efefef url(data:image/png;base64,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) no-repeat 5px 4px; 35 | padding-left: 29px; 36 | min-height: 26px; 37 | line-height: 25px; 38 | color: #555; 39 | margin-bottom: 10px; 40 | } 41 | div.phpdebugbar-openhandler .phpdebugbar-openhandler-header a { 42 | font-size: 14px; 43 | color: #555; 44 | text-decoration: none; 45 | float: right; 46 | padding: 5px 8px; 47 | } 48 | div.phpdebugbar-openhandler table { 49 | width: 100%; 50 | table-layout: fixed; 51 | font-size: 14px; 52 | } 53 | div.phpdebugbar-openhandler table td { 54 | padding: 6px 3px; 55 | border-bottom: 1px solid #ddd; 56 | } 57 | div.phpdebugbar-openhandler table td a{ 58 | display: block; 59 | white-space: nowrap; 60 | overflow: hidden; 61 | text-overflow: ellipsis; 62 | } 63 | div.phpdebugbar-openhandler .phpdebugbar-openhandler-actions { 64 | text-align: center; 65 | padding: 7px 0; 66 | } 67 | div.phpdebugbar-openhandler .phpdebugbar-openhandler-actions a { 68 | margin: 0 10px; 69 | color: #555; 70 | } 71 | -------------------------------------------------------------------------------- /assets/openhandler.js: -------------------------------------------------------------------------------- 1 | if (typeof(PhpDebugBar) == 'undefined') { 2 | // namespace 3 | var PhpDebugBar = {}; 4 | PhpDebugBar.$ = jQuery; 5 | } 6 | 7 | (function($) { 8 | 9 | var csscls = function(cls) { 10 | return PhpDebugBar.utils.csscls(cls, 'phpdebugbar-openhandler-'); 11 | }; 12 | 13 | PhpDebugBar.OpenHandler = PhpDebugBar.Widget.extend({ 14 | 15 | className: 'phpdebugbar-openhandler', 16 | 17 | defaults: { 18 | items_per_page: 20 19 | }, 20 | 21 | render: function() { 22 | var self = this; 23 | 24 | this.$el.appendTo('body').hide(); 25 | this.$closebtn = $(''); 26 | this.$table = $(''); 27 | $('
PHP DebugBar | Open
').addClass(csscls('header')).append(this.$closebtn).appendTo(this.$el); 28 | $('
DateMethodURLIPFilter data
').append(this.$table).appendTo(this.$el); 29 | this.$actions = $('
').addClass(csscls('actions')).appendTo(this.$el); 30 | 31 | this.$closebtn.on('click', function() { 32 | self.hide(); 33 | }); 34 | 35 | this.$loadmorebtn = $('Load more') 36 | .appendTo(this.$actions) 37 | .on('click', function() { 38 | self.find(self.last_find_request, self.last_find_request.offset + self.get('items_per_page'), self.handleFind.bind(self)); 39 | }); 40 | 41 | this.$showonlycurrentbtn = $('Show only current URL') 42 | .appendTo(this.$actions) 43 | .on('click', function() { 44 | self.$table.empty(); 45 | self.find({uri: window.location.pathname}, 0, self.handleFind.bind(self)); 46 | }); 47 | 48 | this.$showallbtn = $('Show all') 49 | .appendTo(this.$actions) 50 | .on('click', function() { 51 | self.refresh(); 52 | }); 53 | 54 | this.$clearbtn = $('Delete all') 55 | .appendTo(this.$actions) 56 | .on('click', function() { 57 | self.clear(function() { 58 | self.hide(); 59 | }); 60 | }); 61 | 62 | this.addSearch(); 63 | 64 | this.$overlay = $('
').addClass(csscls('overlay')).hide().appendTo('body'); 65 | this.$overlay.on('click', function() { 66 | self.hide(); 67 | }); 68 | }, 69 | 70 | refresh: function() { 71 | this.$table.empty(); 72 | this.$loadmorebtn.show(); 73 | this.find({}, 0, this.handleFind.bind(this)); 74 | }, 75 | 76 | addSearch: function(){ 77 | var self = this; 78 | var searchBtn = $('