Skip to content

Commit

Permalink
Saves the encoded debugbar data and enables decoding by content type
Browse files Browse the repository at this point in the history
  • Loading branch information
natanfelles committed Jan 18, 2018
1 parent a6fd7a1 commit 803b460
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 179 deletions.
4 changes: 2 additions & 2 deletions application/Filters/DebugToolbar.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function after(RequestInterface $request, ResponseInterface $response)

$toolbar = Services::toolbar(new App());
$stats = $app->getPerformanceStats();
$output = $toolbar->run(
$data = $toolbar->run(
$stats['startTime'],
$stats['totalTime'],
$stats['startMemory'],
Expand All @@ -59,7 +59,7 @@ public function after(RequestInterface $request, ResponseInterface $response)
mkdir(WRITEPATH.'debugbar', 0777);
}

write_file(WRITEPATH .'debugbar/'.'debugbar_' . $time, $output, 'w+');
write_file(WRITEPATH .'debugbar/'.'debugbar_' . $time, $data, 'w+');

$script = PHP_EOL
. '<script type="text/javascript" id="debugbar_loader" '
Expand Down
195 changes: 162 additions & 33 deletions system/Debug/Toolbar.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
*/
use CodeIgniter\Config\BaseConfig;
use Config\Services;
use CodeIgniter\Format\XMLFormatter;

/**
* Debug Toolbar
Expand All @@ -57,11 +58,6 @@ class Toolbar
*/
protected $collectors = [];

/**
* @var float App start time
*/
protected $startTime;

//--------------------------------------------------------------------

/**
Expand All @@ -86,33 +82,146 @@ public function __construct(BaseConfig $config)
//--------------------------------------------------------------------

/**
* Run
* Returns all the data required by Debug Bar
*
* @param float $startTime
* @param float $startTime App start time
* @param float $totalTime
* @param float $startMemory
* @param \CodeIgniter\HTTP\RequestInterface $request
* @param \CodeIgniter\HTTP\ResponseInterface $response
*
* @return string
* @return string JSON encoded data
*/
public function run($startTime, $totalTime, $startMemory, $request, $response): string
{
$this->startTime = $startTime;

// Data items used within the view.
$collectors = $this->collectors;
$data['startTime'] = $startTime;
$data['totalTime'] = $totalTime*1000;
$data['totalMemory'] = number_format((memory_get_peak_usage()-$startMemory)/1048576, 3);
$data['segmentDuration'] = $this->roundTo($data['totalTime']/7, 5);
$data['segmentCount'] = (int)ceil($data['totalTime']/$data['segmentDuration']);
$data['CI_VERSION'] = \CodeIgniter\CodeIgniter::CI_VERSION;
$data['collectors'] = [];

foreach($this->collectors as $collector)
{
$data['collectors'][] = [
'title' => $collector->getTitle(),
'titleSafe' => $collector->getTitle(true),
'titleDetails' => $collector->getTitleDetails(),
'display' => $collector->display(),
'badgeValue' => $collector->getBadgeValue(),
'isEmpty' => $collector->isEmpty(),
'hasTabContent' => $collector->hasTabContent(),
'hasLabel' => $collector->hasLabel(),
'icon' => $collector->icon(),
'hasTimelineData' => $collector->hasTimelineData(),
'timelineData' => $collector->timelineData(),
];
}

foreach ($this->collectVarData() as $heading => $items)
{
$vardata = [];

if (is_array($items))
{
foreach ($items as $key => $value)
{
$vardata[esc($key)] = is_string($value) ? esc($value) : print_r($value, true);
}
}

$data['vars']['varData'][esc($heading)] = $vardata;
}

if (isset($_SESSION) && ! empty($_SESSION))
{
foreach ($_SESSION as $key => $value)
{
$data['vars']['session'][esc($key)] = is_string($value) ? esc($value) : print_r($value, true);
}
}

foreach ($request->getGet() as $name => $value)
{
$data['vars']['get'][esc($name)] = esc($value);
}

foreach ($request->getPost() as $name => $value)
{
$data['vars']['post'][esc($name)] = is_array($value) ? esc(print_r($value, true)) : esc($value);
}

foreach ($request->getHeaders() as $header => $value)
{
if (empty($value))
{
continue;
}

if (! is_array($value))
{
$value = [$value];
}

foreach ($value as $h)
{
$data['vars']['headers'][esc($h->getName())] = esc($h->getValueLine());
}
}

foreach ($request->getCookie() as $name => $value)
{
$data['vars']['cookies'][esc($name)] = esc($value);
}

$data['vars']['request'] = ($request->isSecure() ? 'HTTPS' : 'HTTP').'/'.$request->getProtocolVersion();

$data['vars']['response'] = [
'statusCode' => $response->getStatusCode(),
'reason' => esc($response->getReason()),
];

$data['config'] = \CodeIgniter\Debug\Toolbar\Collectors\Config::display();

return json_encode($data);
}

//--------------------------------------------------------------------

/**
* Format output
*
* @param string $data JSON encoded Toolbar data
* @param string $format html, json, xml
*
* @return string
*/
protected static function format(string $data, string $format = 'html')
{
if ($format === 'json')
{
return $data;
}

$totalTime = $totalTime*1000;
$totalMemory = number_format((memory_get_peak_usage()-$startMemory)/1048576, 3);
$segmentDuration = $this->roundTo($totalTime/7, 5);
$segmentCount = (int)ceil($totalTime/$segmentDuration);
$varData = $this->collectVarData();
$data = json_decode($data, true);
$output = '';

ob_start();
include(__DIR__.'/Toolbar/Views/toolbar.tpl.php');
$output = ob_get_contents();
ob_end_clean();
if ($format === 'html')
{
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 === 'xml')
{
$formatter = new XMLFormatter;
$output = $formatter->format($data);
}

return $output;
}
Expand All @@ -122,16 +231,18 @@ public function run($startTime, $totalTime, $startMemory, $request, $response):
/**
* Called within the view to display the timeline itself.
*
* @param int $segmentCount
* @param int $segmentDuration
* @param array $collectors
* @param float $startTime
* @param int $segmentCount
* @param int $segmentDuration
*
* @return string
*/
protected function renderTimeline(int $segmentCount, int $segmentDuration): string
protected static function renderTimeline(array $collectors, $startTime, int $segmentCount, int $segmentDuration): string
{
$displayTime = $segmentCount*$segmentDuration;

$rows = $this->collectTimelineData();
$rows = self::collectTimelineData($collectors);

$output = '';

Expand All @@ -143,7 +254,7 @@ protected function renderTimeline(int $segmentCount, int $segmentDuration): stri
$output .= "<td style='text-align: right'>".number_format($row['duration']*1000, 2)." ms</td>";
$output .= "<td colspan='{$segmentCount}' style='overflow: hidden'>";

$offset = ((($row['start']-$this->startTime)*1000)/
$offset = ((($row['start']-$startTime)*1000)/
$displayTime)*100;
$length = (($row['duration']*1000)/$displayTime)*100;

Expand All @@ -165,24 +276,23 @@ protected function renderTimeline(int $segmentCount, int $segmentDuration): stri
*
* @return array
*/
protected function collectTimelineData(): array
protected static function collectTimelineData($collectors): array
{
$data = [];

// Collect it
foreach ($this->collectors as $collector)
foreach ($collectors as $collector)
{
if (! $collector->hasTimelineData())
if (! $collector['hasTimelineData'])
{
continue;
}

$data = array_merge($data, $collector->timelineData());
$data = array_merge($data, $collector['timelineData']);
}

// Sort it


return $data;
}

Expand Down Expand Up @@ -258,19 +368,38 @@ public static function eventHandler()
{
helper('security');

$format = $request->negotiate('media', [
'text/html',
'application/json',
'application/xml'
]);
$format = explode('/', $format)[1];

$file = sanitize_filename('debugbar_'.$request->getGet('debugbar_time'));
$filename = WRITEPATH.'debugbar/'.$file;

// Show the toolbar
if (file_exists($filename))
{
$contents = file_get_contents($filename);
unlink($filename);
$contents = self::format(file_get_contents($filename), $format);
//unlink($filename); // TODO - Keep history? 10 files
exit($contents);
}

// File was not written or do not exists
exit('<script id="toolbar_js">console.log(\'CI DebugBar: File "WRITEPATH/'.$file.'" not found.\')</script>');
$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('<?xml version="1.0" encoding="UTF-8"?><error>'.$error.'</error>');
default:
header('Content-Type: application/javascript');
exit('<script id="toolbar_js">console.log(\''.$error.'\')</script>');
}
}
}
}
9 changes: 4 additions & 5 deletions system/Debug/Toolbar/Collectors/BaseCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,13 @@ protected function formatTimelineData(): array
//--------------------------------------------------------------------

/**
* Builds and returns the HTML needed to fill a tab to display
* within the Debug Bar
* Returns the data of this collector to be formatted in the toolbar
*
* @return string
* @return array
*/
public function display(): string
public function display(): array
{
return '';
return [];
}

//--------------------------------------------------------------------
Expand Down
25 changes: 9 additions & 16 deletions system/Debug/Toolbar/Collectors/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,17 @@ class Config
public static function display()
{
$config = new App();
$parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false);

$data = [
'ciVersion' => CodeIgniter::CI_VERSION,
'phpVersion' => phpversion(),
'phpSAPI' => php_sapi_name(),
return [
'ciVersion' => CodeIgniter::CI_VERSION,
'phpVersion' => phpversion(),
'phpSAPI' => php_sapi_name(),
'environment' => ENVIRONMENT,
'baseURL' => $config->baseURL,
'timezone' => app_timezone(),
'locale' => Services::request()->getLocale(),
'cspEnabled' => $config->CSPEnabled,
'salt' => $config->salt,
'baseURL' => $config->baseURL,
'timezone' => app_timezone(),
'locale' => Services::request()->getLocale(),
'cspEnabled' => $config->CSPEnabled,
'salt' => $config->salt,
];


$output = $parser->setData($data)
->render('_config.tpl');

return $output;
}
}
13 changes: 4 additions & 9 deletions system/Debug/Toolbar/Collectors/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,20 +149,18 @@ protected function formatTimelineData(): array
//--------------------------------------------------------------------

/**
* Returns the HTML to fill the Database tab in the toolbar.
* Returns the data of this collector to be formatted in the toolbar
*
* @return string The data formatted for the toolbar.
* @return array
*/
public function display(): string
public function display(): array
{
// Key words we want bolded
$highlight = ['SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY',
'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR&nbsp;', 'HAVING', 'OFFSET', 'NOT&nbsp;IN',
'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')'
];

$parser = \Config\Services::parser(BASEPATH . 'Debug/Toolbar/Views/', null,false);

$data = [
'queries' => []
];
Expand All @@ -182,10 +180,7 @@ public function display(): string
];
}

$output = $parser->setData($data)
->render('_database.tpl');

return $output;
return $data;
}

//--------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 803b460

Please sign in to comment.