function show_debug_console($return = false)
{
// if
if ($this->debug && is_array($this->debugger_ip) && (empty($this->debugger_ip) || in_array($_SERVER['REMOTE_ADDR'], $this->debugger_ip))) {
// include the SqlFormatter library
require 'includes/SqlFormatter.php';
// set some properties for the formatter
SqlFormatter::$number_attributes = SqlFormatter::$boundary_attributes = 'class="symbol"';
SqlFormatter::$quote_attributes = 'class="string"';
SqlFormatter::$reserved_attributes = 'class="keyword"';
SqlFormatter::$tab = ' ';
// if warnings are not disabled
if (!$this->disable_warnings) {
// if there are any warning messages iterate through them
foreach (array_keys($this->warnings) as $warning) {
// add them to the debugging console
$this->_log('warnings', array('message' => $this->language['warning_' . $warning]), false);
}
}
// blocks to be shown in the debugging console
$blocks = array('errors' => array('counter' => 0, 'identifier' => 'e', 'generated' => ''), 'successful-queries' => array('counter' => 0, 'identifier' => 'sq', 'generated' => ''), 'unsuccessful-queries' => array('counter' => 0, 'identifier' => 'uq', 'generated' => ''), 'warnings' => array('counter' => 0, 'identifier' => 'w', 'generated' => ''), 'globals' => array('generated' => ''));
// there are no warnings
$warnings = false;
// prepare output for each block
foreach (array_keys($blocks) as $block) {
$output = '';
// if there is any information for the current block
if (isset($this->debug_info[$block])) {
// iterate through the error message
foreach ($this->debug_info[$block] as $debug_info) {
// increment the messages counter
$counter = ++$blocks[$block]['counter'];
$identifier = $blocks[$block]['identifier'];
// if block is about queries
if ($block == 'successful-queries' || $block == 'unsuccessful-queries') {
// format and highlight query
$debug_info['query'] = SqlFormatter::format($debug_info['query']);
}
// all blocks are enclosed in tables
$output .= '
<table cellspacing="0" cellpadding="0" border="0" class="zdc-entry' . ($counter % 2 == 0 ? ' even' : '') . (isset($debug_info['highlight']) && $debug_info['highlight'] == 1 ? ' zdc-highlight' : '') . '">
<tr>
<td class="zdc-counter" valign="top">' . str_pad($counter, 3, '0', STR_PAD_LEFT) . '</td>
<td class="zdc-data">
';
// are there any error messages issued by the script?
if (isset($debug_info['message']) && trim($debug_info['message']) != '') {
$output .= '
<div class="zdc-box zdc-error">
' . $debug_info['message'] . '
</div>
';
}
// are there any error messages issued by MySQL?
if (isset($debug_info['error']) && trim($debug_info['error']) != '') {
$output .= '
<div class="zdc-box zdc-error">
' . $debug_info['error'] . '
</div>
';
}
// are there any warning messages issued by the script?
if (isset($debug_info['warning']) && trim($debug_info['warning']) != '') {
$output .= '
<div class="zdc-box zdc-error">' . $debug_info['warning'] . '
</div>
';
// set a flag so that we show in the minimized debugging console that there are warnings
$warnings = true;
}
// is there a query to be displayed?
if (isset($debug_info['query'])) {
$output .= '
<div class="zdc-box' . (isset($debug_info['transaction']) && $debug_info['transaction'] ? ' zdc-transaction' : '') . '">' . preg_replace('/^\\<br\\>/', '', html_entity_decode($debug_info['query'])) . '
</div>
';
}
// start generating the actions box
$output .= '
<div class="zdc-box zdc-actions">
<ul>
';
// actions specific to successful queries
if ($block == 'successful-queries') {
// info about whether the query results were taken from cache or not
if ($debug_info['from_cache'] != 'nocache') {
$output .= '
<li class="zdc-cache">
<strong>' . $this->language['from_cache'] . ' (' . $this->caching_method . ')</strong>
</li>
';
}
// info about execution time
$output .= '
<li class="zdc-time">' . $this->language['execution_time'] . ': ' . $this->_fix_pow($debug_info['execution_time']) . ' ' . $this->language['miliseconds'] . ' (<strong>' . number_format($this->total_execution_time != 0 ? $debug_info['execution_time'] * 100 / $this->total_execution_time : 0, 2, '.', ',') . '</strong>%)
</li>
';
// if not an action query
if ($debug_info['affected_rows'] === false) {
// button for reviewing returned rows
$output .= '
<li class="zdc-records">
<a href="javascript:zdc_toggle(\'zdc-records-sq' . $counter . '\')">' . $this->language['returned_rows'] . ': <strong>' . $debug_info['returned_rows'] . '</strong>
</a>
</li>
';
} else {
// info about affected rows
$output .= '
<li class="zdc-affected">' . $this->language['affected_rows'] . ': <strong>' . $debug_info['affected_rows'] . '</strong>
</li>
';
}
// if EXPLAIN is available (only for SELECT queries)
if (is_array($debug_info['explain'])) {
// button for reviewing EXPLAIN results
$output .= '
<li class="zdc-explain">
<a href="javascript:zdc_toggle(\'zdc-explain-sq' . $counter . '\')">' . $this->language['explain'] . '
</a>
</li>
';
}
}
// if backtrace information is available
if (isset($debug_info['backtrace'])) {
$output .= '
<li class="zdc-backtrace">
<a href="javascript:zdc_toggle(\'zdc-backtrace-' . $identifier . $counter . '\')">' . $this->language['backtrace'] . '
</a>
</li>
';
}
// common actions (to top, close all)
$output .= '
<li class="zdc-top">
<a href="' . preg_replace('/\\#zdc\\-top$/i', '', $_SERVER['REQUEST_URI']) . '#zdc-top">' . $this->language['to_top'] . '
</a>
</li>
<li class="zdc-close">
<a href="javascript:zdc_closeAll(\'\')">' . $this->language['close_all'] . '
</a>
</li>
';
// wrap up actions bar
$output .= '
</ul>
<div class="clear"></div>
</div>
';
// data tables (backtrace, returned rows, explain)
// let's see what tables do we need to display
$tables = array();
// if query did return records
if (!empty($debug_info['records'])) {
$tables[] = 'records';
}
// if explain is available
if (isset($debug_info['explain']) && is_array($debug_info['explain'])) {
$tables[] = 'explain';
}
// if backtrace is available
if (isset($debug_info['backtrace'])) {
$tables[] = 'backtrace';
}
// let's display data
foreach ($tables as $table) {
// start generating output
$output .= '
<div id="zdc-' . $table . '-' . $identifier . $counter . '" class="zdc-box zdc-' . $table . '-table">
<table cellspacing="0" cellpadding="0" border="0">
<tr>
';
// print table headers
foreach (array_keys($debug_info[$table][0]) as $header) {
$output .= '<th>' . $header . '</th>';
}
$output .= '</tr>';
// print table rows and columns
foreach ($debug_info[$table] as $index => $row) {
$output .= '<tr class="' . (($index + 1) % 2 == 0 ? 'even' : '') . '">';
foreach (array_values($row) as $column) {
$output .= '<td valign="top">' . $column . '</td>';
}
$output .= '</tr>';
}
// wrap up data tables
$output .= '
</table>
</div>
';
}
// finish block
$output .= '
</td>
</tr>
</table>
';
}
// if anything was generated for the current block
// enclose generated output in a special div
if ($counter > 0) {
$blocks[$block]['generated'] = '<div id="zdc-' . $block . '">' . $output . '</div>';
}
} elseif ($block == 'globals') {
// globals to show
$globals = array('POST', 'GET', 'SESSION', 'COOKIE', 'FILES', 'SERVER');
// start building output
$output = '
<div id="zdc-globals-submenu">
<ul>
';
// iterate through the superglobals to show
foreach ($globals as $global) {
// add button to submenu
$output .= '<li>
<a href="javascript:zdc_toggle(\'zdc-globals-' . strtolower($global) . '\')">$_' . $global . '
</a>
</li>
';
}
// finish building the submenu
$output .= '
</ul>
<div class="clear"></div>
</div>
';
// iterate thought the superglobals to show
foreach ($globals as $global) {
// make the superglobal available
global ${'_' . $global};
// add to the generated output
$output .= '
<table cellspacing="0" cellpadding="0" border="0" id="zdc-globals-' . strtolower($global) . '" class="zdc-entry">
<tr>
<td class="zdc-counter" valign="top">001</td>
<td class="zdc-data">
<div class="zdc-box">
<strong>$_' . $global . '</strong>
<pre>' . htmlentities(var_export(${'_' . $global}, true)) . '</pre>
</div>
</td>
</tr>
</table>
';
}
// enclose generated output in a special div
$output = '<div id="zdc-globals">' . $output . '</div>';
$blocks[$block]['generated'] = $output;
}
}
// if there's an error, show the console
if ($blocks['unsuccessful-queries']['counter'] > 0 || $blocks['errors']['counter'] > 0) {
$this->minimize_console = false;
}
// finalize output by enclosing the debugging console's menu and generated blocks in a container
$output = '
<div id="zdc" style="display:' . ($this->minimize_console ? 'none' : 'block') . '">
<a name="zdc-top"></a>
<ul class="zdc-main">
';
// are there any error messages?
if ($blocks['errors']['counter'] > 0) {
// button for reviewing errors
$output .= '
<li>
<a href="javascript:zdc_toggle(\'zdc-errors\')">' . $this->language['errors'] . ': <span>' . $blocks['errors']['counter'] . '</span>
</a>
</li>
';
}
// common buttons
$output .= '
<li>
<a href="javascript:zdc_toggle(\'zdc-successful-queries\')">' . $this->language['successful_queries'] . ': <span>' . $blocks['successful-queries']['counter'] . '</span> (' . $this->_fix_pow($this->total_execution_time) . ' ' . $this->language['miliseconds'] . ')
</a>
</li>
<li>
<a href="javascript:zdc_toggle(\'zdc-unsuccessful-queries\')">' . $this->language['unsuccessful_queries'] . ': <span>' . $blocks['unsuccessful-queries']['counter'] . '</span>
</a>
</li>
';
if (isset($this->debug_info['warnings'])) {
$output .= '
<li>
<a href="javascript:zdc_toggle(\'zdc-warnings\')">' . $this->language['warnings'] . ': <span>' . count($this->warnings) . '</span>
</a>
</li>
';
}
$output .= '
<li>
<a href="javascript:zdc_toggle(\'zdc-globals-submenu\')">' . $this->language['globals'] . '
</a>
</li>
';
// wrap up debugging console's menu
$output .= '
</ul>
<div class="clear"></div>
';
foreach (array_keys($blocks) as $block) {
$output .= $blocks[$block]['generated'];
}
// wrap up
$output .= '</div>';
// add the minified version of the debugging console
$output .= '
<div id="zdc-mini">
<a href="javascript:zdc_toggle(\'console\')">' . $blocks['successful-queries']['counter'] . ($warnings ? '<span>!</span>' : '') . ' / ' . $blocks['unsuccessful-queries']['counter'] . '
</a>
</div>
';
// use the provided resource path for stylesheets and javascript (if any)
if (!is_null($this->resource_path)) {
$path = rtrim(preg_replace('/\\\\/', '/', '//' . $_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] != '80' ? ':' . $_SERVER['SERVER_PORT'] : '') . DIRECTORY_SEPARATOR . $this->resource_path), '/');
} else {
// this is the url that will be used for automatically including
// the CSS and the JavaScript files
$path = rtrim(preg_replace('/\\\\/', '/', '//' . $_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] != '80' ? ':' . $_SERVER['SERVER_PORT'] : '') . DIRECTORY_SEPARATOR . substr(dirname(__FILE__), strlen(realpath($_SERVER['DOCUMENT_ROOT'])))), '/');
}
// link the required javascript
$output = '<script type="text/javascript" src="' . $path . '/public/javascript/database.js"></script>' . $output;
// link the required css file
$output = '<link rel="stylesheet" href="' . $path . '/public/css/database.css" type="text/css">' . $output;
// if output is to be returned rather than printed to the screen
if ($return) {
return $output;
}
// show generated output
echo $output;
}
}