Merge pull request #8 from uwetews/master

Debug Console Update
This commit is contained in:
uwetews
2014-11-03 22:31:13 +01:00
8 changed files with 219 additions and 41 deletions

View File

@@ -1,6 +1,15 @@
===== 3.1.22-dev ===== (xx.xx.2014)
03.11.2014
- bugfix Debug Console did not show included subtemplates since 3.1.17 (forum 25301)
- bugfix Modifier debug_print_var did not limit recursion or prevent recursive object display at Debug Console
(ATTENTION: parameter order has changed to be able to specify maximum recursion)
- bugfix Debug consol did not include subtemplate information with $smarty->merge_compiled_includes = true
- improvement The template variables are no longer displayed as objects on the Debug Console
- improvement $smarty->createData($parent = null, $name = null) new optional name parameter for display at Debug Console
- addition of some hooks for future extension of Debug Console
01.11.2014
-bugfix and enhancement on subtemplate {include} and template {function} tags.
- bugfix and enhancement on subtemplate {include} and template {function} tags.
* Calling a template which has a nocache section could fail if it was called from a cached and a not cached subtemplate.
* Calling the same subtemplate cached and not cached with the $smarty->merge_compiled_includes enabled could cause problems
* Many smaller related changes

View File

@@ -110,7 +110,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/**
* smarty version
*/
const SMARTY_VERSION = 'Smarty-3.1.21-dev/2';
const SMARTY_VERSION = '3.1.22-dev/2';
/**
* define variable scopes
@@ -1337,7 +1337,11 @@ class Smarty extends Smarty_Internal_TemplateBase
$tpl->tpl_vars[$_key] = new Smarty_variable($_val);
}
}
if ($this->debugging) {
if ($this->debugging) {
Smarty_Internal_Debug::register_template($tpl);
}
}
return $tpl;
}

View File

@@ -5,7 +5,7 @@
<title>Smarty Debug Console</title>
<style type="text/css">
{literal}
body, h1, h2, td, th, p {
body, h1, h2, h3, td, th, p {
font-family: sans-serif;
font-weight: normal;
font-size: 0.9em;
@@ -31,6 +31,13 @@
padding: 2px;
border-top: 1px solid black;
}
h3 {
text-align: left;
font-weight: bold;
color: black;
font-size: 0.7em;
padding: 2px;
}
body {
background: black;
@@ -54,7 +61,6 @@
font-family: monospace;
vertical-align: top;
text-align: left;
width: 50%;
}
td {
@@ -74,8 +80,20 @@
font-style: italic;
}
#bold div {
color: black;
font-weight: bold;
}
#blue h3 {
color: blue;
}
#normal div {
color: black;
font-weight: normal;
}
#table_assigned_vars th {
color: blue;
font-weight: bold;
}
#table_config_vars th {
@@ -88,17 +106,16 @@
<body>
<h1>Smarty Debug Console
- {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
- {if isset($template_name)}{$template_name|debug_print_var nofilter} {/if}{if !empty($template_data)}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
{if !empty($template_data)}
<h2>included templates &amp; config files (load time in seconds)</h2>
<div>
{foreach $template_data as $template}
<font color=brown>{$template.name}</font>
<span class="exectime">
(compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"}
)
</span>
<br>&nbsp;&nbsp;<span class="exectime">
(compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"})
</span>
<br>
{/foreach}
</div>
@@ -109,19 +126,24 @@
<table id="table_assigned_vars">
{foreach $assigned_vars as $vars}
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
<th>${$vars@key|escape:'html'}</th>
<td>{$vars|debug_print_var nofilter}</td>
</tr>
{/foreach}
<td><h3><font color=blue>${$vars@key|escape:'html'}</font></h3>
{if isset($vars['nocache'])}<b>Nocache</b></br>{/if}
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']}{/if}
</td>
<td><h3>Value</h3>{$vars['value']|debug_print_var nofilter}</td>
<td>{if isset($vars['attributes'])}<h3>Attributes</h3>{$vars['attributes']|debug_print_var nofilter} {/if}</td>
{/foreach}
</table>
<h2>assigned config file variables (outer template scope)</h2>
<h2>assigned config file variables</h2>
<table id="table_config_vars">
{foreach $config_vars as $vars}
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
<th>{$vars@key|escape:'html'}</th>
<td>{$vars|debug_print_var nofilter}</td>
<td><h3><font color=blue>#{$vars@key|escape:'html'}#</font></h3>
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']}{/if}
</td>
<td>{$vars['value']|debug_print_var nofilter}</td>
</tr>
{/foreach}

View File

@@ -14,26 +14,30 @@
*
* @author Monte Ohrt <monte at ohrt dot com>
*
* @param array|object $var variable to be formatted
* @param integer $depth maximum recursion depth if $var is an array
* @param integer $length maximum string length if $var is a string
* @param array|object $var variable to be formatted
* @param int $max maximum recursion depth if $var is an array or object
* @param int $length maximum string length if $var is a string
* @param int $depth actual recursion depth
* @param array $objects processed objects in actual depth to prevent recursive object processing
*
* @return string
*/
function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
function smarty_modifier_debug_print_var($var, $max = 10, $length = 40, $depth = 0, $objects = array())
{
$_replace = array("\n" => '<i>\n</i>',
"\r" => '<i>\r</i>',
"\t" => '<i>\t</i>'
);
switch (gettype($var)) {
case 'array' :
$results = '<b>Array (' . count($var) . ')</b>';
if ($depth == $max) {
break;
}
foreach ($var as $curr_key => $curr_val) {
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
. '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
. smarty_modifier_debug_print_var($curr_val, $max, $length, ++ $depth, $objects);
$depth --;
}
break;
@@ -41,10 +45,18 @@ function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
case 'object' :
$object_vars = get_object_vars($var);
$results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
if (in_array($var, $objects)) {
$results .= ' called recursive';
break;
}
if ($depth == $max) {
break;
}
$objects[] = $var;
foreach ($object_vars as $curr_key => $curr_val) {
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
. '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
. smarty_modifier_debug_print_var($curr_val, $max, $length, ++ $depth, $objects);
$depth --;
}
break;

View File

@@ -454,6 +454,19 @@ class Smarty_Internal_Data
*/
class Smarty_Data extends Smarty_Internal_Data
{
/**
* Counter
*
* @var int
*/
static $count = 0;
/**
* Data block name
*
* @var string
*/
public $dataObjectName = '';
/**
* Smarty object
*
@@ -466,11 +479,14 @@ class Smarty_Data extends Smarty_Internal_Data
*
* @param Smarty|array $_parent parent template
* @param Smarty|Smarty_Internal_Template $smarty global smarty instance
* @param string $name optional data block name
*
* @throws SmartyException
*/
public function __construct($_parent = null, $smarty = null)
public function __construct($_parent = null, $smarty = null, $name = null)
{
self::$count++;
$this->dataObjectName = 'Data_object ' . (isset($name) ? "'{$name}'" : self::$count);
$this->smarty = $smarty;
if (is_object($_parent)) {
// when object set up back pointer

View File

@@ -136,12 +136,54 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
self::$template_data[$key]['cache_time'] += microtime(true) - self::$template_data[$key]['start_time'];
}
/**
* Start logging of cache time
*
* @param object $template cached template
*/
public static function start_template($template)
{
$key = self::get_key($template);
self::$template_data[$key]['start_template_time'] = microtime(true);
}
/**
* End logging of cache time
*
* @param object $template cached template
*/
public static function end_template($template)
{
$key = self::get_key($template);
self::$template_data[$key]['total_time'] += microtime(true) - self::$template_data[$key]['start_template_time'];
self::$template_data[$key]['properties'] = $template->properties;
}
/**
* Register template object
*
* @param object $template cached template
*/
public static function register_template($template)
{
}
/**
* Register data object
*
* @param object $data data object
*/
public static function register_data($data)
{
}
/**
* Opens a window for the Smarty Debugging Consol and display the data
*
* @param Smarty_Internal_Template|Smarty $obj object to debug
*/
public static function display_debug($obj)
public static function display_debug($obj, $full = false)
{
// prepare information of assigned variables
$ptr = self::get_debug_vars($obj);
@@ -171,7 +213,7 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
if ($obj instanceof Smarty_Internal_Template) {
$_template->assign('template_name', $obj->source->type . ':' . $obj->source->name);
}
if ($obj instanceof Smarty) {
if ($obj instanceof Smarty || $full) {
$_template->assign('template_data', self::$template_data);
} else {
$_template->assign('template_data', null);
@@ -180,6 +222,10 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
$_template->assign('config_vars', $_config_vars);
$_template->assign('execution_time', microtime(true) - $smarty->start_time);
echo $_template->fetch();
if ($full) {
self::$ignore_uid = array();
self::$template_data = array();
}
}
/**
@@ -191,29 +237,74 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
*/
public static function get_debug_vars($obj)
{
$config_vars = $obj->config_vars;
$config_vars = array();
foreach ($obj->config_vars as $key => $var) {
$config_vars[$key]['value'] = $var;
if ($obj instanceof Smarty_Internal_Template) {
$config_vars[$key]['scope'] = $obj->source->type . ':' . $obj->source->name;
} elseif ($obj instanceof Smarty_Data) {
$tpl_vars[$key]['scope'] = $obj->dataObjectName;
} else {
$config_vars[$key]['scope'] = 'Smarty object';
}
}
$tpl_vars = array();
foreach ($obj->tpl_vars as $key => $var) {
$tpl_vars[$key] = clone $var;
foreach ($var as $varkey => $varvalue) {
if ($varkey == 'value') {
$tpl_vars[$key][$varkey] = $varvalue;
} else if ($varkey == 'nocache') {
if ($varvalue == true) {
$tpl_vars[$key][$varkey] = $varvalue;
}
} else {
if ($varkey != 'scope' || $varvalue !== 0)
$tpl_vars[$key]['attributes'][$varkey] = $varvalue;
}
}
if ($obj instanceof Smarty_Internal_Template) {
$tpl_vars[$key]->scope = $obj->source->type . ':' . $obj->source->name;
$tpl_vars[$key]['scope'] = $obj->source->type . ':' . $obj->source->name;
} elseif ($obj instanceof Smarty_Data) {
$tpl_vars[$key]->scope = 'Data object';
$tpl_vars[$key]['scope'] = $obj->dataObjectName;
} else {
$tpl_vars[$key]->scope = 'Smarty root';
$tpl_vars[$key]['scope'] = 'Smarty object';
}
}
if (isset($obj->parent)) {
$parent = self::get_debug_vars($obj->parent);
foreach($parent->tpl_vars as $name => $pvar){
if (isset($tpl_vars[$name]) && $tpl_vars[$name]['value'] === $pvar['value']) {
$tpl_vars[$name]['scope'] = $pvar['scope'];
}
}
$tpl_vars = array_merge($parent->tpl_vars, $tpl_vars);
foreach($parent->config_vars as $name => $pvar){
if (isset($config_vars[$name]) && $config_vars[$name]['value'] === $pvar['value']) {
$config_vars[$name]['scope'] = $pvar['scope'];
}
}
$config_vars = array_merge($parent->config_vars, $config_vars);
} else {
foreach (Smarty::$global_tpl_vars as $name => $var) {
if (!array_key_exists($name, $tpl_vars)) {
$clone = clone $var;
$clone->scope = 'Global';
$tpl_vars[$name] = $clone;
foreach (Smarty::$global_tpl_vars as $key => $var) {
if (!array_key_exists($key, $tpl_vars)) {
foreach ($var as $varkey => $varvalue) {
if ($varkey == 'value') {
$tpl_vars[$key][$varkey] = $varvalue;
} else {
if ($varkey == 'nocache') {
if ($varvalue == true) {
$tpl_vars[$key][$varkey] = $varvalue;
}
} else {
if ($varkey != 'scope' || $varvalue !== 0) {
$tpl_vars[$key]['attributes'][$varkey] = $varvalue;
}
}
}
}
$tpl_vars[$key]['scope'] = 'Global';
}
}
}
@@ -247,6 +338,7 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
self::$template_data[$key]['compile_time'] = 0;
self::$template_data[$key]['render_time'] = 0;
self::$template_data[$key]['cache_time'] = 0;
self::$template_data[$key]['total_time'] = 0;
return $key;
}

View File

@@ -371,8 +371,17 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
public function getInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash, $content_func)
{
$tpl = $this->setupInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash);
if ($this->debugging) {
Smarty_Internal_Debug::start_template($tpl);
Smarty_Internal_Debug::start_render($tpl);
}
ob_start();
$content_func($tpl);
if ($this->debugging) {
Smarty_Internal_Debug::end_template($tpl);
Smarty_Internal_Debug::end_render($tpl);
}
return str_replace($tpl->properties['nocache_hash'], $this->properties['nocache_hash'], ob_get_clean());
}

View File

@@ -36,7 +36,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
if ($template === null && $this instanceof $this->template_class) {
$template = $this;
}
if ($cache_id !== null && is_object($cache_id)) {
if ($cache_id !== null && is_object($cache_id)) {
$parent = $cache_id;
$cache_id = null;
}
@@ -47,6 +47,9 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
$_template = ($template instanceof $this->template_class)
? $template
: $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
if ($this->smarty->debugging) {
Smarty_Internal_Debug::start_template($_template);
}
// if called by Smarty object make sure we use current caching status
if ($this instanceof Smarty) {
$_template->caching = $this->caching;
@@ -385,9 +388,12 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
} else {
echo $_output;
}
if ($this->smarty->debugging) {
Smarty_Internal_Debug::end_template($_template);
}
// debug output
if ($this->smarty->debugging) {
Smarty_Internal_Debug::display_debug($_template);
Smarty_Internal_Debug::display_debug($_template, true);
}
if ($merge_tpl_vars) {
// restore local variables
@@ -402,6 +408,9 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
$_template->tpl_vars = $save_tpl_vars;
$_template->config_vars = $save_config_vars;
}
if ($this->smarty->debugging) {
Smarty_Internal_Debug::end_template($_template);
}
// return fetched content
return $_output;
}
@@ -450,12 +459,17 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
* creates a data object
*
* @param object $parent next higher level of Smarty variables
* @param string $name optional data block name
*
* @returns Smarty_Data data object
*/
public function createData($parent = null)
public function createData($parent = null, $name = null)
{
return new Smarty_Data($parent, $this);
$dataObj = new Smarty_Data($parent, $this, $name);
if ($this->debugging) {
Smarty_Internal_Debug::register_data($dataObj);
}
return $dataObj;
}
/**