diff --git a/application/Config/App.php b/application/Config/App.php index 8c7e6041ed07..94a2bab44abf 100644 --- a/application/Config/App.php +++ b/application/Config/App.php @@ -270,6 +270,9 @@ class App extends BaseConfig | and state of your application during that page display. By default it will | NOT be displayed under production environments, and will only display if | CI_DEBUG is true, since if it's not, there's not much to display anyway. + | + | toolbarMaxHistory = Number of history files, 0 for none or -1 for unlimited + | */ public $toolbarCollectors = [ 'CodeIgniter\Debug\Toolbar\Collectors\Timers', @@ -281,6 +284,7 @@ class App extends BaseConfig 'CodeIgniter\Debug\Toolbar\Collectors\Routes', 'CodeIgniter\Debug\Toolbar\Collectors\Events', ]; + public $toolbarMaxHistory = 20; /* |-------------------------------------------------------------------------- diff --git a/application/Controllers/Ajax.php b/application/Controllers/Ajax.php deleted file mode 100644 index 0b2f95dbc68f..000000000000 --- a/application/Controllers/Ajax.php +++ /dev/null @@ -1,17 +0,0 @@ -response->setHeader('Content-Type', 'application/json') - ->setBody(json_encode($this->request->getVar())); - } -} diff --git a/application/Filters/DebugToolbar.php b/application/Filters/DebugToolbar.php index 9ff4f22fa61c..945108013c47 100644 --- a/application/Filters/DebugToolbar.php +++ b/application/Filters/DebugToolbar.php @@ -47,7 +47,7 @@ public function after(RequestInterface $request, ResponseInterface $response) $response ); - helper(['filesystem', 'url']); + helper('filesystem'); // Updated to time() so we can get history $time = time(); diff --git a/application/Views/ajax.php b/application/Views/ajax.php deleted file mode 100644 index 60f1d292eaf4..000000000000 --- a/application/Views/ajax.php +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - Ajax - - - -
- - -
-
- - - - - - - diff --git a/system/Debug/Toolbar.php b/system/Debug/Toolbar.php index bf20181bdea1..f02b73aac8cd 100644 --- a/system/Debug/Toolbar.php +++ b/system/Debug/Toolbar.php @@ -58,6 +58,13 @@ class Toolbar */ protected $collectors = []; + /** + * Incoming Request + * + * @var \CodeIgniter\HTTP\IncomingRequest + */ + protected static $request; + //-------------------------------------------------------------------- /** @@ -213,16 +220,12 @@ protected static function format(string $data, string $format = 'html') $files = []; - $current = Services::request()->getGet('debugbar_time'); + $current = self::$request->getGet('debugbar_time'); + $app = new \Config\App; for ($i = 0; $i < $total; $i++) { - if ($i >= 30) - { - unlink($filenames[$i]); - continue; - } - + // Get the contents of this specific history request ob_start(); include($filenames[$i]); $contents = ob_get_contents(); @@ -230,25 +233,34 @@ protected static function format(string $data, string $format = 'html') $file = json_decode($contents, true); + // Debugbar files shown in History Collector $files[$i] = [ - 'time' => substr($filenames[$i], -10), - 'datetime' => date('Y-m-d H:i:s', $time = substr($filenames[$i], -10)), + 'time' => (int)$time = substr($filenames[$i], -10), + 'datetime' => date('Y-m-d H:i:s', $time), 'active' => (int)($time == $current), 'status' => $file['vars']['response']['statusCode'], 'method' => $file['method'], 'url' => $file['url'], - 'isAJAX' => (int)$file['isAJAX'], + 'isAJAX' => $file['isAJAX'] ? 'Yes' : 'No', 'contentType' => $file['vars']['response']['contentType'], ]; + + // Oldest files will be deleted + if ($app->toolbarMaxHistory >= 0 && $i >= $app->toolbarMaxHistory) + { + unlink($filenames[$i]); + continue; + } } + // Set the History here. Class is not necessary $data['collectors'][] = [ 'title' => 'History', 'titleSafe' => 'history', 'titleDetails' => '', - 'display' => ['files'=>$files], - 'badgeValue' => $hc = count($files), - 'isEmpty' => ! (bool)$hc, + 'display' => ['files' => $files], + 'badgeValue' => $count = count($files), + 'isEmpty' => ! (bool)$count, 'hasTabContent' => true, 'hasLabel' => true, 'icon' => '', @@ -258,23 +270,25 @@ protected static function format(string $data, string $format = 'html') $output = ''; - if ($format === 'html') + switch ($format) { - extract($data); - $parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false); - ob_start(); - include(__DIR__.'/Toolbar/Views/toolbar.tpl.php'); - $output = ob_get_contents(); - ob_end_clean(); - } - elseif ($format === 'json') - { - $output = json_encode($data); - } - elseif ($format === 'xml') - { - $formatter = new XMLFormatter; - $output = $formatter->format($data); + case 'html': + extract($data); + $parser = Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false); + ob_start(); + include(__DIR__.'/Toolbar/Views/toolbar.tpl.php'); + $output = ob_get_contents(); + ob_end_clean(); + break; + case 'json': + $output = json_encode($data); + break; + case 'json': + $output = json_encode($data); + case 'xml': + $formatter = new XMLFormatter; + $output = $formatter->format($data); + break; } return $output; @@ -295,10 +309,8 @@ protected static function format(string $data, string $format = 'html') protected static function renderTimeline(array $collectors, $startTime, int $segmentCount, int $segmentDuration): string { $displayTime = $segmentCount*$segmentDuration; - - $rows = self::collectTimelineData($collectors); - - $output = ''; + $rows = self::collectTimelineData($collectors); + $output = ''; foreach ($rows as $row) { @@ -308,15 +320,12 @@ protected static function renderTimeline(array $collectors, $startTime, int $seg $output .= "".number_format($row['duration']*1000, 2)." ms"; $output .= ""; - $offset = ((($row['start']-$startTime)*1000)/ - $displayTime)*100; + $offset = ((($row['start']-$startTime)*1000)/$displayTime)*100; $length = (($row['duration']*1000)/$displayTime)*100; $output .= ""; - $output .= ""; - $output .= ""; } @@ -399,11 +408,11 @@ protected function roundTo($number, $increments = 5) */ public static function eventHandler() { - $request = Services::request(); + self::$request = Services::request(); // If the request contains '?debugbar then we're // simply returning the loading script - if ($request->getGet('debugbar') !== null) + if (self::$request->getGet('debugbar') !== null) { // Let the browser know that we are sending javascript header('Content-Type: application/javascript'); @@ -418,18 +427,19 @@ public static function eventHandler() // Otherwise, if it includes ?debugbar_time, then // we should return the entire debugbar. - if ($request->getGet('debugbar_time')) + if (self::$request->getGet('debugbar_time')) { helper('security'); - $format = $request->negotiate('media', [ + // Negotiate the content-type to format the output + $format = self::$request->negotiate('media', [ 'text/html', 'application/json', 'application/xml' ]); $format = explode('/', $format)[1]; - $file = sanitize_filename('debugbar_'.$request->getGet('debugbar_time')); + $file = sanitize_filename('debugbar_'.self::$request->getGet('debugbar_time')); $filename = WRITEPATH.'debugbar/'.$file; // Show the toolbar @@ -440,19 +450,8 @@ public static function eventHandler() } // File was not written or do not exists - $error = 'CI DebugBar: File "WRITEPATH/'.$file.'" not found.'; - switch ($format) - { - case 'json': - header('Content-Type: application/json'); - exit($error); - case 'xml': - header('Content-Type: application/xml'); - exit(''.$error.''); - default: - header('Content-Type: text/html'); - exit(''); - } + http_response_code(404); + exit(); // Exit here is needed to avoid load the index page } } } diff --git a/system/Debug/Toolbar/Collectors/History.php b/system/Debug/Toolbar/Collectors/History.php deleted file mode 100644 index d6da3748d892..000000000000 --- a/system/Debug/Toolbar/Collectors/History.php +++ /dev/null @@ -1,45 +0,0 @@ - $filename, - ]; - } - - return [ - 'files' => $files, - ]; - } - - public function getBadgeValue() - { - return count(glob(WRITEPATH . 'debugbar/debugbar_*')); - } - - public function isEmpty() - { - return ! (bool)count(glob(WRITEPATH . 'debugbar/debugbar_*')); - } - - public function icon(): string - { - return ''; - } -} diff --git a/system/Debug/Toolbar/Views/_history.tpl.php b/system/Debug/Toolbar/Views/_history.tpl.php index 4e1dd41299f8..e777b89d2abf 100644 --- a/system/Debug/Toolbar/Views/_history.tpl.php +++ b/system/Debug/Toolbar/Views/_history.tpl.php @@ -13,9 +13,8 @@ {files} - + - {datetime} {status} diff --git a/system/Debug/Toolbar/Views/toolbar.css b/system/Debug/Toolbar/Views/toolbar.css index 1a32d4b461ff..079157021d92 100644 --- a/system/Debug/Toolbar/Views/toolbar.css +++ b/system/Debug/Toolbar/Views/toolbar.css @@ -163,6 +163,10 @@ margin-left: 0.5em; } +#debug-bar span.ci-label .badge.active { + background-color: red; +} + #debug-bar button { border: 1px solid #ddd; background-color: #fff; diff --git a/system/Debug/Toolbar/Views/toolbar.js b/system/Debug/Toolbar/Views/toolbar.js index ce9b5d7f21f9..944893e10c3b 100644 --- a/system/Debug/Toolbar/Views/toolbar.js +++ b/system/Debug/Toolbar/Views/toolbar.js @@ -17,38 +17,28 @@ var ciDebugBar = { ciDebugBar.createListeners(); ciDebugBar.setToolbarState(); ciDebugBar.setToolbarPosition(); - ciDebugBar.toogleViewsHints(); + ciDebugBar.toggleViewsHints(); - document.getElementById('debug-bar-link').addEventListener('click', ciDebugBar.toggleToolbar, true); - document.getElementById('debug-icon-link').addEventListener('click', ciDebugBar.toggleToolbar, true); + document.getElementById('debug-bar-link').addEventListener('click', ciDebugBar.toggleToolbar, true); + document.getElementById('debug-icon-link').addEventListener('click', ciDebugBar.toggleToolbar, true); + // Allows to highlight the row of the current history request + var btn = document.querySelector('button[data-time="'+localStorage.getItem('debugbar-time')+'"]'); + ciDebugBar.addClass(btn.parentNode.parentNode, 'current'); - // Allows to highlight the row of the current request - var btn = document.querySelector('button[data-time="'+localStorage.getItem('debugbar-time')+'"]'); - ciDebugBar.addClass(btn.parentNode.parentNode, 'current'); + historyLoad = document.getElementsByClassName('ci-history-load'); - historyLoad = document.getElementsByClassName('ci-history-load'); - - for (var i = 0; i < historyLoad.length; i++) + for (var i = 0; i < historyLoad.length; i++) { historyLoad[i].addEventListener('click', function() { loadDoc(this.getAttribute('data-time')); }, true); } - historyDelete = document.getElementsByClassName('ci-history-delete'); - - for (var i = 0; i < historyDelete.length; i++) - { - historyDelete[i].addEventListener('click', function() { - console.log(this); - }, true); - } - + // Display the active Tab on page load var tab = ciDebugBar.readCookie('debug-bar-tab'); if (document.getElementById(tab)) { var el = document.getElementById(tab); - console.log(tab); el.style.display = 'block'; ciDebugBar.addClass(el, 'active'); tab = document.querySelector('[data-tab='+tab+']'); @@ -196,11 +186,14 @@ var ciDebugBar = { //-------------------------------------------------------------------- - toogleViewsHints: function() + toggleViewsHints: function() { + // Avoid toggle hints on history requests that are not the initial if (localStorage.getItem('debugbar-time') != localStorage.getItem('debugbar-time-new')) { - //return false; + var a = document.querySelector('a[data-tab="ci-views"]'); + a.href = '#'; + return; } var nodeList = []; // [ Element, NewElement( 1 )/OldElement( 0 ) ] @@ -458,7 +451,6 @@ var ciDebugBar = { // Determine Hints state on page load if (ciDebugBar.readCookie('debug-view')) { - // TODO: History is overriding it. Check if is the current time showHints(); } }, diff --git a/system/Debug/Toolbar/Views/toolbar.tpl.php b/system/Debug/Toolbar/Views/toolbar.tpl.php index f37147daa4b5..4c002cd200da 100644 --- a/system/Debug/Toolbar/Views/toolbar.tpl.php +++ b/system/Debug/Toolbar/Views/toolbar.tpl.php @@ -6,86 +6,86 @@
- + - - - ms   MB - - + + + ms   MB + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - Vars - - + + + Vars + + -

- - - - - - - - - - -

+

+ + + + + + + + + + +

- - - - + + + +
@@ -96,9 +96,9 @@ NAME COMPONENT DURATION - + ms - + @@ -109,45 +109,45 @@ - - -
-

+ + +
+

setData($c['display'])->render("_{$c['titleSafe']}.tpl") ?> -
- - +
+ +
- - $items) : ?> + + $items) : ?> - -

-
+ +

+
- + - - - $value) : ?> - - - - - - -
+ + + $value) : ?> + + + + + + +
- -

No data to display.

- - + +

No data to display.

+ + @@ -164,15 +164,15 @@ - +

No data to display.

- +

Session doesn't seem to be active.

- +

Request ( )

@@ -188,7 +188,7 @@ - + @@ -205,7 +205,7 @@ - + @@ -222,7 +222,7 @@ - + @@ -239,7 +239,7 @@ - + @@ -258,15 +258,17 @@ - + - +
- -
-

System Configuration

+ +
+

System Configuration

- setData($config)->render('_config.tpl') ?> -
+ setData($config)->render('_config.tpl') ?> +
+ +
diff --git a/system/Debug/Toolbar/toolbarloader.js.php b/system/Debug/Toolbar/toolbarloader.js.php index 6c93c3904f9d..17ab879f6369 100644 --- a/system/Debug/Toolbar/toolbarloader.js.php +++ b/system/Debug/Toolbar/toolbarloader.js.php @@ -1,60 +1,58 @@ - -document.addEventListener('DOMContentLoaded', loadDoc, false ); +document.addEventListener('DOMContentLoaded', loadDoc, false); function loadDoc(time) { if (isNaN(time)) { time = document.getElementById("debugbar_loader").getAttribute("data-time"); localStorage.setItem('debugbar-time', time); - localStorage.setItem('debugbar-view', true); } localStorage.setItem('debugbar-time-new', time); - var url = ""; - - var xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function () { - if (this.readyState == 4 && this.status == 200) { - var toolbar = document.getElementById("toolbarContainer"); - if (! toolbar) { - toolbar = document.createElement('div'); - toolbar.setAttribute('id', 'toolbarContainer'); - toolbar.innerHTML = this.responseText; - document.body.appendChild(toolbar); - } else { - toolbar.innerHTML = this.responseText; - } - eval(document.getElementById("toolbar_js").innerHTML); - if (typeof ciDebugBar === 'object') { - ciDebugBar.init(); - } - } - }; - - xhttp.open("GET", url + "?debugbar_time=" + time, true); - xhttp.send(); + var url = ""; + + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState === 4 && this.status === 200) { + var toolbar = document.getElementById("toolbarContainer"); + if (!toolbar) { + toolbar = document.createElement('div'); + toolbar.setAttribute('id', 'toolbarContainer'); + toolbar.innerHTML = this.responseText; + document.body.appendChild(toolbar); + } else { + toolbar.innerHTML = this.responseText; + } + eval(document.getElementById("toolbar_js").innerHTML); + if (typeof ciDebugBar === 'object') { + ciDebugBar.init(); + } + } else if (this.readyState === 4 && this.status === 404) { + console.log('CodeIgniter DebugBar: File "WRITEPATH/debugbar/debugbar_' + time + '" not found.'); + } + }; + + xhttp.open("GET", url + "?debugbar_time=" + time, true); + xhttp.send(); } +// Track all AJAX requests var oldXHR = window.XMLHttpRequest; -/** - * Track all the AJAX requests - */ function newXHR() { - var realXHR = new oldXHR(); - realXHR.addEventListener("readystatechange", function() { - // Only success responses and URLs that do not contains "debugbar_time" are tracked - if(realXHR.readyState == 4 && realXHR.status.toString()[0] == 2 && realXHR.responseURL.indexOf('debugbar_time') == -1 ) { - var debugbarTime = realXHR.getResponseHeader('Debugbar-Time'); - - if (debugbarTime) { - var h2 = document.querySelector('#ci-history > h2'); - h2.innerHTML = 'History You have new debug data. '; - var badge = document.querySelector('[data-tab="ci-history"] > span > .badge'); - badge.style.background = 'red'; - } - } - }, false); - return realXHR; + var realXHR = new oldXHR(); + realXHR.addEventListener("readystatechange", function() { + // Only success responses and URLs that do not contains "debugbar_time" are tracked + if (realXHR.readyState === 4 && realXHR.status.toString()[0] === '2' && realXHR.responseURL.indexOf('debugbar_time') === -1) { + var debugbarTime = realXHR.getResponseHeader('Debugbar-Time'); + if (debugbarTime) { + var h2 = document.querySelector('#ci-history > h2'); + h2.innerHTML = 'History You have new debug data. '; + var badge = document.querySelector('a[data-tab="ci-history"] > span > .badge'); + badge.className += ' active'; + } + } + }, false); + return realXHR; } + window.XMLHttpRequest = newXHR;