library/smarty/libs/sysplugins/smarty_internal_debug.php
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     1 <?php
       
     2 /**
       
     3  * Smarty Internal Plugin Debug
       
     4  * Class to collect data for the Smarty Debugging Console
       
     5  *
       
     6  * @package    Smarty
       
     7  * @subpackage Debug
       
     8  * @author     Uwe Tews
       
     9  */
       
    10 
       
    11 /**
       
    12  * Smarty Internal Plugin Debug Class
       
    13  *
       
    14  * @package    Smarty
       
    15  * @subpackage Debug
       
    16  */
       
    17 class Smarty_Internal_Debug extends Smarty_Internal_Data {
       
    18     /**
       
    19      * template data
       
    20      *
       
    21      * @var array
       
    22      */
       
    23     public static $template_data = array();
       
    24 
       
    25     /**
       
    26      * List of uid's which shall be ignored
       
    27      *
       
    28      * @var array
       
    29      */
       
    30     public static $ignore_uid = array();
       
    31 
       
    32     /**
       
    33      * Index of display() and fetch() calls
       
    34      *
       
    35      * @var int
       
    36      */
       
    37     public static $index = 0;
       
    38 
       
    39     /**
       
    40      * Counter for window offset
       
    41      *
       
    42      * @var int
       
    43      */
       
    44     public static $offset = 0;
       
    45 
       
    46     /**
       
    47      * Start logging template
       
    48      *
       
    49      * @param \Smarty_Internal_Template $template template
       
    50      * @param null $mode true: display   false: fetch  null: subtemolate
       
    51      */
       
    52     public static function start_template(Smarty_Internal_Template $template, $mode = null) {
       
    53         if (isset($mode)) {
       
    54             self::$index++;
       
    55             self::$offset++;
       
    56             self::$template_data[self::$index] = null;
       
    57         }
       
    58         $key = self::get_key($template);
       
    59         self::$template_data[self::$index][$key]['start_template_time'] = microtime(true);
       
    60     }
       
    61 
       
    62     /**
       
    63      * End logging of cache time
       
    64      *
       
    65      * @param \Smarty_Internal_Template $template cached template
       
    66      */
       
    67     public static function end_template(Smarty_Internal_Template $template) {
       
    68         $key = self::get_key($template);
       
    69         self::$template_data[self::$index][$key]['total_time'] += microtime(true) - self::$template_data[self::$index][$key]['start_template_time'];
       
    70         self::$template_data[self::$index][$key]['properties'] = $template->properties;
       
    71     }
       
    72 
       
    73     /**
       
    74      * Start logging of compile time
       
    75      *
       
    76      * @param \Smarty_Internal_Template $template
       
    77      */
       
    78     public static function start_compile(Smarty_Internal_Template $template) {
       
    79         static $_is_stringy = array('string' => true, 'eval' => true);
       
    80         if (!empty($template->compiler->trace_uid)) {
       
    81             $key = $template->compiler->trace_uid;
       
    82             if (!isset(self::$template_data[self::$index][$key])) {
       
    83                 if (isset($_is_stringy[$template->source->type])) {
       
    84                     self::$template_data[self::$index][$key]['name'] = '\'' . substr($template->source->name, 0, 25) . '...\'';
       
    85                 } else {
       
    86                     self::$template_data[self::$index][$key]['name'] = $template->source->filepath;
       
    87                 }
       
    88                 self::$template_data[self::$index][$key]['compile_time'] = 0;
       
    89                 self::$template_data[self::$index][$key]['render_time'] = 0;
       
    90                 self::$template_data[self::$index][$key]['cache_time'] = 0;
       
    91             }
       
    92         } else {
       
    93             if (isset(self::$ignore_uid[$template->source->uid])) {
       
    94                 return;
       
    95             }
       
    96             $key = self::get_key($template);
       
    97         }
       
    98         self::$template_data[self::$index][$key]['start_time'] = microtime(true);
       
    99     }
       
   100 
       
   101     /**
       
   102      * End logging of compile time
       
   103      *
       
   104      * @param \Smarty_Internal_Template $template
       
   105      */
       
   106     public static function end_compile(Smarty_Internal_Template $template) {
       
   107         if (!empty($template->compiler->trace_uid)) {
       
   108             $key = $template->compiler->trace_uid;
       
   109         } else {
       
   110             if (isset(self::$ignore_uid[$template->source->uid])) {
       
   111                 return;
       
   112             }
       
   113 
       
   114             $key = self::get_key($template);
       
   115         }
       
   116         self::$template_data[self::$index][$key]['compile_time'] += microtime(true) - self::$template_data[self::$index][$key]['start_time'];
       
   117     }
       
   118 
       
   119     /**
       
   120      * Start logging of render time
       
   121      *
       
   122      * @param \Smarty_Internal_Template $template
       
   123      */
       
   124     public static function start_render(Smarty_Internal_Template $template) {
       
   125         $key = self::get_key($template);
       
   126         self::$template_data[self::$index][$key]['start_time'] = microtime(true);
       
   127     }
       
   128 
       
   129     /**
       
   130      * End logging of compile time
       
   131      *
       
   132      * @param \Smarty_Internal_Template $template
       
   133      */
       
   134     public static function end_render(Smarty_Internal_Template $template) {
       
   135         $key = self::get_key($template);
       
   136         self::$template_data[self::$index][$key]['render_time'] += microtime(true) - self::$template_data[self::$index][$key]['start_time'];
       
   137     }
       
   138 
       
   139     /**
       
   140      * Start logging of cache time
       
   141      *
       
   142      * @param \Smarty_Internal_Template $template cached template
       
   143      */
       
   144     public static function start_cache(Smarty_Internal_Template $template) {
       
   145         $key = self::get_key($template);
       
   146         self::$template_data[self::$index][$key]['start_time'] = microtime(true);
       
   147     }
       
   148 
       
   149     /**
       
   150      * End logging of cache time
       
   151      *
       
   152      * @param \Smarty_Internal_Template $template cached template
       
   153      */
       
   154     public static function end_cache(Smarty_Internal_Template $template) {
       
   155         $key = self::get_key($template);
       
   156         self::$template_data[self::$index][$key]['cache_time'] += microtime(true) - self::$template_data[self::$index][$key]['start_time'];
       
   157     }
       
   158 
       
   159     /**
       
   160      * Register template object
       
   161      *
       
   162      * @param \Smarty_Internal_Template $template cached template
       
   163      */
       
   164     public static function register_template(Smarty_Internal_Template $template) {
       
   165     }
       
   166 
       
   167     /**
       
   168      * Register data object
       
   169      *
       
   170      * @param \Smarty_Data $data data object
       
   171      */
       
   172     public static function register_data(Smarty_Data $data) {
       
   173     }
       
   174 
       
   175     /**
       
   176      * Opens a window for the Smarty Debugging Console and display the data
       
   177      *
       
   178      * @param Smarty_Internal_Template|Smarty $obj object to debug
       
   179      * @param bool $full
       
   180      */
       
   181     public static function display_debug($obj, $full = false) {
       
   182         if (!$full) {
       
   183             self::$offset++;
       
   184             $savedIndex = self::$index;
       
   185             self::$index = 9999;
       
   186         }
       
   187         if ($obj instanceof Smarty) {
       
   188             $smarty = $obj;
       
   189         } else {
       
   190             $smarty = $obj->smarty;
       
   191         }
       
   192         // create fresh instance of smarty for displaying the debug console
       
   193         // to avoid problems if the application did overload the Smarty class
       
   194         $debObj = new Smarty();
       
   195         // copy the working dirs from application
       
   196         $debObj->setCompileDir($smarty->getCompileDir());
       
   197         // init properties by hand as user may have edited the original Smarty class
       
   198         $debObj->setPluginsDir(is_dir(__DIR__ . '/../plugins') ? __DIR__ . '/../plugins' : $smarty->getPluginsDir());
       
   199         $debObj->force_compile = false;
       
   200         $debObj->compile_check = true;
       
   201         $debObj->left_delimiter = '{';
       
   202         $debObj->right_delimiter = '}';
       
   203         $debObj->security_policy = null;
       
   204         $debObj->debugging = false;
       
   205         $debObj->debugging_ctrl = 'NONE';
       
   206         $debObj->error_reporting = E_ALL & ~E_NOTICE;
       
   207         $debObj->debug_tpl = isset($smarty->debug_tpl) ? $smarty->debug_tpl : 'file:' . __DIR__ . '/../debug.tpl';
       
   208         $debObj->registered_plugins = array();
       
   209         $debObj->registered_resources = array();
       
   210         $debObj->registered_filters = array();
       
   211         $debObj->autoload_filters = array();
       
   212         $debObj->default_modifiers = array();
       
   213         $debObj->escape_html = true;
       
   214         $debObj->caching = false;
       
   215         $debObj->compile_id = null;
       
   216         $debObj->cache_id = null;
       
   217         // prepare information of assigned variables
       
   218         $ptr = self::get_debug_vars($obj);
       
   219         $_assigned_vars = $ptr->tpl_vars;
       
   220         ksort($_assigned_vars);
       
   221         $_config_vars = $ptr->config_vars;
       
   222         ksort($_config_vars);
       
   223         $debugging = $smarty->debugging;
       
   224 
       
   225         $_template = new Smarty_Internal_Template($debObj->debug_tpl, $debObj);
       
   226         if ($obj instanceof Smarty_Internal_Template) {
       
   227             $_template->assign('template_name', $obj->source->type . ':' . $obj->source->name);
       
   228         }
       
   229         if ($obj instanceof Smarty || $full) {
       
   230             $_template->assign('template_data', self::$template_data[self::$index]);
       
   231         } else {
       
   232             $_template->assign('template_data', null);
       
   233         }
       
   234         $_template->assign('assigned_vars', $_assigned_vars);
       
   235         $_template->assign('config_vars', $_config_vars);
       
   236         $_template->assign('execution_time', microtime(true) - $smarty->start_time);
       
   237         $_template->assign('display_mode', $debugging == 2 || !$full);
       
   238         $_template->assign('offset', self::$offset * 50);
       
   239         echo $_template->fetch();
       
   240         if (isset($full)) {
       
   241             self::$index--;
       
   242         }
       
   243         if (!$full) {
       
   244             self::$index = $savedIndex;
       
   245         }
       
   246     }
       
   247 
       
   248     /**
       
   249      * Recursively gets variables from all template/data scopes
       
   250      *
       
   251      * @param  Smarty_Internal_Template|Smarty_Data $obj object to debug
       
   252      *
       
   253      * @return StdClass
       
   254      */
       
   255     public static function get_debug_vars($obj) {
       
   256         $config_vars = array();
       
   257         foreach ($obj->config_vars as $key => $var) {
       
   258             $config_vars[$key]['value'] = $var;
       
   259             if ($obj instanceof Smarty_Internal_Template) {
       
   260                 $config_vars[$key]['scope'] = $obj->source->type . ':' . $obj->source->name;
       
   261             } elseif ($obj instanceof Smarty_Data) {
       
   262                 $tpl_vars[$key]['scope'] = $obj->dataObjectName;
       
   263             } else {
       
   264                 $config_vars[$key]['scope'] = 'Smarty object';
       
   265             }
       
   266         }
       
   267         $tpl_vars = array();
       
   268         foreach ($obj->tpl_vars as $key => $var) {
       
   269             foreach ($var as $varkey => $varvalue) {
       
   270                 if ($varkey == 'value') {
       
   271                     $tpl_vars[$key][$varkey] = $varvalue;
       
   272                 } else {
       
   273                     if ($varkey == 'nocache') {
       
   274                         if ($varvalue == true) {
       
   275                             $tpl_vars[$key][$varkey] = $varvalue;
       
   276                         }
       
   277                     } else {
       
   278                         if ($varkey != 'scope' || $varvalue !== 0) {
       
   279                             $tpl_vars[$key]['attributes'][$varkey] = $varvalue;
       
   280                         }
       
   281                     }
       
   282                 }
       
   283             }
       
   284             if ($obj instanceof Smarty_Internal_Template) {
       
   285                 $tpl_vars[$key]['scope'] = $obj->source->type . ':' . $obj->source->name;
       
   286             } elseif ($obj instanceof Smarty_Data) {
       
   287                 $tpl_vars[$key]['scope'] = $obj->dataObjectName;
       
   288             } else {
       
   289                 $tpl_vars[$key]['scope'] = 'Smarty object';
       
   290             }
       
   291         }
       
   292 
       
   293         if (isset($obj->parent)) {
       
   294             $parent = self::get_debug_vars($obj->parent);
       
   295             foreach ($parent->tpl_vars as $name => $pvar) {
       
   296                 if (isset($tpl_vars[$name]) && $tpl_vars[$name]['value'] === $pvar['value']) {
       
   297                     $tpl_vars[$name]['scope'] = $pvar['scope'];
       
   298                 }
       
   299             }
       
   300             $tpl_vars = array_merge($parent->tpl_vars, $tpl_vars);
       
   301 
       
   302             foreach ($parent->config_vars as $name => $pvar) {
       
   303                 if (isset($config_vars[$name]) && $config_vars[$name]['value'] === $pvar['value']) {
       
   304                     $config_vars[$name]['scope'] = $pvar['scope'];
       
   305                 }
       
   306             }
       
   307             $config_vars = array_merge($parent->config_vars, $config_vars);
       
   308         } else {
       
   309             foreach (Smarty::$global_tpl_vars as $key => $var) {
       
   310                 if (!array_key_exists($key, $tpl_vars)) {
       
   311                     foreach ($var as $varkey => $varvalue) {
       
   312                         if ($varkey == 'value') {
       
   313                             $tpl_vars[$key][$varkey] = $varvalue;
       
   314                         } else {
       
   315                             if ($varkey == 'nocache') {
       
   316                                 if ($varvalue == true) {
       
   317                                     $tpl_vars[$key][$varkey] = $varvalue;
       
   318                                 }
       
   319                             } else {
       
   320                                 if ($varkey != 'scope' || $varvalue !== 0) {
       
   321                                     $tpl_vars[$key]['attributes'][$varkey] = $varvalue;
       
   322                                 }
       
   323                             }
       
   324                         }
       
   325                     }
       
   326                     $tpl_vars[$key]['scope'] = 'Global';
       
   327                 }
       
   328             }
       
   329         }
       
   330 
       
   331         return (object)array('tpl_vars' => $tpl_vars, 'config_vars' => $config_vars);
       
   332     }
       
   333 
       
   334     /**
       
   335      * Return key into $template_data for template
       
   336      *
       
   337      * @param \Smarty_Internal_Template $template template object
       
   338      *
       
   339      * @return string key into $template_data
       
   340      */
       
   341     private static function get_key(Smarty_Internal_Template $template) {
       
   342         static $_is_stringy = array('string' => true, 'eval' => true);
       
   343         // calculate Uid if not already done
       
   344         if ($template->source->uid == '') {
       
   345             $template->source->filepath;
       
   346         }
       
   347         $key = $template->source->uid;
       
   348         if (isset(self::$template_data[self::$index][$key])) {
       
   349             return $key;
       
   350         } else {
       
   351             if (isset($_is_stringy[$template->source->type])) {
       
   352                 self::$template_data[self::$index][$key]['name'] = '\'' . substr($template->source->name, 0, 25) . '...\'';
       
   353             } else {
       
   354                 self::$template_data[self::$index][$key]['name'] = $template->source->filepath;
       
   355             }
       
   356             self::$template_data[self::$index][$key]['compile_time'] = 0;
       
   357             self::$template_data[self::$index][$key]['render_time'] = 0;
       
   358             self::$template_data[self::$index][$key]['cache_time'] = 0;
       
   359             self::$template_data[self::$index][$key]['total_time'] = 0;
       
   360 
       
   361             return $key;
       
   362         }
       
   363     }
       
   364 
       
   365     /**
       
   366      * Ignore template
       
   367      *
       
   368      * @param \Smarty_Internal_Template $template
       
   369      */
       
   370     public static function ignore(Smarty_Internal_Template $template) {
       
   371         // calculate Uid if not already done
       
   372         if ($template->source->uid == '') {
       
   373             $template->source->filepath;
       
   374         }
       
   375         self::$ignore_uid[$template->source->uid] = true;
       
   376     }
       
   377 
       
   378     /**
       
   379      * handle 'URL' debugging mode
       
   380      *
       
   381      * @param Smarty_Internal_Template $_template
       
   382      */
       
   383     public static function debugUrl(Smarty_Internal_Template $_template) {
       
   384         if (isset($_SERVER['QUERY_STRING'])) {
       
   385             $_query_string = $_SERVER['QUERY_STRING'];
       
   386         } else {
       
   387             $_query_string = '';
       
   388         }
       
   389         if (false !== strpos($_query_string, $_template->smarty->smarty_debug_id)) {
       
   390             if (false !== strpos($_query_string, $_template->smarty->smarty_debug_id . '=on')) {
       
   391                 // enable debugging for this browser session
       
   392                 setcookie('SMARTY_DEBUG', true);
       
   393                 $_template->smarty->debugging = true;
       
   394             } elseif (false !== strpos($_query_string, $_template->smarty->smarty_debug_id . '=off')) {
       
   395                 // disable debugging for this browser session
       
   396                 setcookie('SMARTY_DEBUG', false);
       
   397                 $_template->smarty->debugging = false;
       
   398             } else {
       
   399                 // enable debugging for this page
       
   400                 $_template->smarty->debugging = true;
       
   401             }
       
   402         } else {
       
   403             if (isset($_COOKIE['SMARTY_DEBUG'])) {
       
   404                 $_template->smarty->debugging = true;
       
   405             }
       
   406         }
       
   407     }
       
   408 }