diff --git a/XWebDebugRouter.php b/XWebDebugRouter.php
index e1335e4..3e60af8 100644
--- a/XWebDebugRouter.php
+++ b/XWebDebugRouter.php
@@ -1,5 +1,14 @@
/', '', $result, 1);
+ self::$_output = preg_replace('/<\\?php/', '', $result, 1);
}
return self::$_output;
@@ -175,7 +184,42 @@ private static function dumpInternal($var, $level) {
* Render debug panel to document using view and configuration parameters
*/
class yiiDebugPanel {
- public function render($items = array(), $config = array()) {
+ protected static $instance = null;
+ protected static $output = null;
+ protected static $config = null;
+ protected static $items;
+ public static $isRendered = false;
+
+ public function setConfig($config) {
+ self::$config['alignLeft'] = !empty($config['alignLeft']);
+ self::$config['opaque'] = !empty($config['opaque']);
+ self::$config['fixedPos'] = !empty($config['fixedPos']);
+ self::$config['collapsed'] = !empty($config['collapsed']);
+ }
+
+ public function setItems($items) {
+ self::$items = $items;
+ }
+
+ public function getItems() {
+ return self::$items;
+ }
+
+ public static function getInstance() {
+ if( null === self::$instance ) {
+ self::$instance = new self;
+ }
+ return self::$instance;
+ }
+
+ protected function __clone() {}
+
+ protected function __construct() {}
+
+ public static function render() {
+ $items = self::$items;
+ $config = self::$config;
+
$msg = "Run rendering...\n";
$alignLeft = !empty($config['alignLeft']);
$opaque = !empty($config['opaque']);
@@ -183,8 +227,9 @@ public function render($items = array(), $config = array()) {
$collapsed = !empty($config['collapsed']);
$viewFile = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . 'debugPanel.php';
- include(Yii::app()->findLocalizedFile($viewFile, 'en'));
+ require(Yii::app()->findLocalizedFile($viewFile, 'en'));
}
+
}
/**
@@ -198,26 +243,37 @@ public static function timestampToTime($timestamp) {
return date('H:i:s.', $timestamp) . (int)(($timestamp - (int)$timestamp) * 1000000);
}
- public static function render($items) {
+ public static function render($items, $config=null) {
$result = '';
$odd = true;
+ $categories = array();
foreach ($items as $item) {
list($message, $level, $category, $timestamp) = $item;
+ if( !in_array($category, $categories) )
+ $categories[] = $category;
$message = CHtml::encode($message);
// put each source file on its own line
$message = implode("
", explode("\n", $message));
$time = yiiDebugTrace::timestampToTime($timestamp);
$odd = !$odd;
- $result .= '
| ' . $time . ' | ' . $level . ' | ' . $category . ' | ' . $message . ' |
';
+ $result .= '| ' . $time . ' | ' . $level . ' | ' . $category . ' | ' . $message . ' |
';
}
if ($result !== '') {
$result = '' . $result . '';
}
- $result = '| Time | Level | Category | Message |
' . $result . '
';
+ $category_controls = '';
+ foreach($categories as $category) {
+ $category_controls .= ''.$category.'
';
+ }
+
+ $comment = '';
+ if(!is_null($config) && isset($config['comment']))
+ $comment = ''.$config['comment'].'
'.PHP_EOL;
+ $result = $comment.$category_controls.PHP_EOL.'| Time | Level | Category | Message |
' . $result . '
';
return $result;
}
@@ -230,68 +286,197 @@ public static function getInfo($data, $config = null) {
}
class yiiDebugDB extends yiiDebugClass {
+ static $count = 0;
+ static $cached = 0;
+ static $items = array();
+ static $minimized = false;
+ static $information_schema_count = 0;
+ static $queryCount = 0;
+ static $activeRecordCount = 0;
+ static $config = '';
+ static $textHighlighter = null;
+ static $highlightSql = true;
+
public static function getInfo($data, $config = null) {
parent::getInfo($data);
$result = array();
$result['panelTitle'] = 'Database Queries';
-
- $count = 0;
- $cached = 0;
- $items = array();
+ if( self::$minimized ) $result['panelTitle'].=' ('.self::$information_schema_count.' information_schema Queries)';
foreach ($data as $row) {
+ switch($row[2]) {
+ case 'system.db.ar.CActiveRecord' : self::$activeRecordCount++; break;
+ }
if (substr($row[2], 0, 9) == 'system.db') {
- $items[] = $row;
-
- if ($row[2] == 'system.db.CDbCommand') {
+ if ($row[2] == 'system.db.CDbCommand') {
if (strpos($row[0], 'Querying SQL') !== false) {
- $count++;
+ $row[0] = str_replace('Querying SQL:', 'Querying SQL:'.PHP_EOL,$row[0]);
+ self::$count++;
}
if (strpos($row[0], 'Query result found in cache') !== false) {
- $cached++;
+ self::$cached++;
+ }
+
+ if( strpos($row[0], '[INFORMATION_SCHEMA]') !== false ) {
+ $row[2] = $row[2].'_information'; // we modify the category
+ self::$information_schema_count++;
+ // don't log information schema if minimized is enabled
+ if( self::$minimized )
+ return $result;
+ } else {
+ // Query Count contains only Application Queries, no DBAL (information_schema)
+ self::$queryCount++;
}
}
+ $row = self::formatLogEntry($row);
+ self::$items[] = $row;
}
}
- if (count($items) > 0) {
- $result['content'] = yiiDebugTrace::render($items);
+ self::$config['comment'] = 'Operations: '.self::$count.' | Application Queries: '.self::$queryCount.' | DBAL Queries: '.self::$information_schema_count.' | ActiveRecords: '.self::$activeRecordCount;
+
+ if (count(self::$items) > 0) {
+ $result['content'] = yiiDebugDB::render(self::$items, self::$config);
}
- $result['title'] = 'DB Query: ' . $count;
+ $result['title'] = 'DB Ops: ' . self::$count;
- if ($cached > 0) {
- $result['title'] .= " ($cached found in cache)";
+ if (self::$cached > 0) {
+ $result['title'] .= " (".self::$cached." cached)";
}
return $result;
}
+
+ public static function render($items, $config=null) {
+ $result = '';
+ $odd = true;
+ $categories = array();
+
+ foreach ($items as $item) {
+ list($message, $level, $category, $timestamp) = $item;
+ if( !in_array($category, $categories) )
+ $categories[] = $category;
+ //$message = CHtml::encode($message);
+ // put each source file on its own line
+ $message = implode("
", explode("\n", $message));
+ $time = yiiDebugTrace::timestampToTime($timestamp);
+ $odd = !$odd;
+
+ $result .= '| ' . $time . ' | ' . $level . ' | ' . $category . ' | ' . $message . ' |
';
+ }
+
+ if ($result !== '') {
+ $result = '' . $result . '';
+ }
+
+ $category_controls = '';
+ foreach($categories as $category) {
+ $category_controls .= ''.$category.'
';
+ }
+
+ $comment = '';
+ if(!is_null($config) && isset($config['comment']))
+ $comment = ''.$config['comment'].'
'.PHP_EOL;
+ $result = $comment.$category_controls.PHP_EOL.'| Time | Level | Category | Message |
' . $result . '
';
+
+ return $result;
+ }
+
+ /**
+ * Format log entry
+ *
+ * @param array $entry
+ * @return array
+ */
+ public static function formatLogEntry(array $entry)
+ {
+ // extract query from the entry
+ $queryString = $entry[0];
+ $sqlStart = strpos($queryString, "Querying SQL:");
+ // if we have no query we return the whole entry as is
+ if($sqlStart === FALSE) return $entry;
+ $sqlStart += 14;
+ $sqlEnd = strpos($queryString , "\nin D:");
+ //$sqlEnd = strlen($queryString);
+ $sqlLength = $sqlEnd - $sqlStart;
+
+ $beforeQuery = substr($queryString, 0, $sqlStart);
+ $afterQuery = substr($queryString, $sqlEnd);
+ $queryString = substr($queryString, $sqlStart, $sqlLength);
+
+ if (false !== strpos($queryString, '. Bound with '))
+ {
+ list($query, $params) = explode('. Bound with ', $queryString);
+
+ $binds = array();
+ $matchResult = preg_match_all("/(?[a-z0-9\.\_\-\:]+)=(?[\d\.e\-\+]+|''|'.+?(?highlight($entry[0]);
+ $entry[0] = $entry[0].$afterQuery;
+ $entry[0] = $entry[0].PHP_EOL.'Origin: '.str_replace('Bound with',PHP_EOL.'Bound with',$queryString);
+ }
+
+ $entry[0] = strip_tags($entry[0], ',');
+ return $entry;
+ }
+
+ /**
+ * @return CTextHighlighter the text highlighter
+ */
+ private static function getTextHighlighter()
+ {
+ if (null === self::$textHighlighter)
+ {
+ self::$textHighlighter = Yii::createComponent(array(
+ 'class' => 'CTextHighlighter',
+ 'language' => 'sql',
+ 'showLineNumbers' => false,
+ ));
+ }
+ return self::$textHighlighter;
+ }
+
}
class yiiDebugTrace extends yiiDebugClass {
+ static $items = array();
+
public static function getInfo($data, $config = null) {
parent::getInfo($data);
$result = array();
$result['title'] = 'App Log';
$result['panelTitle'] = 'Application Log';
- $items = array();
foreach ($data as $row) {
if (substr($row[2], 0, 9) != 'system.db')
- $items[] = $row;
+ self::$items[] = $row;
}
- if (count($items) > 0) {
- $result['content'] = yiiDebugTrace::render($items);
+ if (count(self::$items) > 0) {
+ $result['content'] = yiiDebugTrace::render(self::$items);
}
return $result;
}
}
-
class yiiDebugTime extends yiiDebugClass {
public static function getInfo($data, $config = null) {
parent::getInfo($data);
@@ -319,7 +504,6 @@ public static function getInfo($data, $config = null) {
return $result;
}
}
-
class yiiDebugConfig extends yiiDebugClass {
public static $yamlStyle = false;
@@ -427,7 +611,7 @@ public static function requestAsArray() {
public static function yiiAppAsArray() {
$result = Yii::app();
- return Yii::app();
+ return $result;
}
protected static function formatArrayAsHtml($id, $values, $highlight = false) {
@@ -465,6 +649,7 @@ public static function getInfo($data, $config = null) {
* and renders self output to the end of server output (after