Showing
6 changed files
with
4950 additions
and
0 deletions
Too many changes to show.
To preserve performance only 6 of 6+ files are displayed.
.htaccess
0 → 100644
ADM_Login.php
0 → 100644
| 1 | +<?PHP | |
| 2 | +//***************************************************************************** | |
| 3 | +//* | |
| 4 | +//* プログラム名:ログイン画面 | |
| 5 | +//* プログラムID:login.php | |
| 6 | +//* 機能 : | |
| 7 | +//* 作成者 : | |
| 8 | +//* | |
| 9 | +//***************************************************************************** | |
| 10 | +header("Content-type: text/html; charset=EUC-JP"); | |
| 11 | + | |
| 12 | +session_start(); | |
| 13 | +$_SESSION = array(); | |
| 14 | + | |
| 15 | + | |
| 16 | +?> | |
| 17 | +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |
| 18 | +<HTML> | |
| 19 | +<HEAD> | |
| 20 | +<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> | |
| 21 | +<meta http-equiv="Content-Style-Type" content="text/css"> | |
| 22 | +<link rel="stylesheet" type="text/css" href="css/login.css"> | |
| 23 | +<TITLE>【e-イベント】管理画面</TITLE> | |
| 24 | +</HEAD> | |
| 25 | +<body> | |
| 26 | +<center> | |
| 27 | +<form action="loginchk.php" method="POST"> | |
| 28 | + <TABLE width="100%" height="509" border="0" cellpadding="0" cellspacing="1" bgcolor="#99CC66"> | |
| 29 | + <tr> | |
| 30 | + <td height="100" class="admin_title"><img src="image/admin_logo.jpg" alt="e-イベント管理画面"></td> | |
| 31 | + </tr> | |
| 32 | + <TR> | |
| 33 | + <TD height="305" valign="top" bgcolor="#FFFFFF"> | |
| 34 | + <div align="center"> | |
| 35 | + <div class="login"> | |
| 36 | + <TABLE width="318" height="175" border="0"> | |
| 37 | + <TR bgcolor="#FFFFFF"> | |
| 38 | + <TD align="center" colspan=2 height="20"> </TD> | |
| 39 | + </TR> | |
| 40 | + <TR bgcolor="#FFFFFF"> | |
| 41 | + <TD align="center" colspan=2 height="20"><b>【ログイン】</b></TD> | |
| 42 | + </TR> | |
| 43 | + <TR> | |
| 44 | + <TD width="124" height="20"><div class="text">>> ID</div></TD> | |
| 45 | + <TD width="184" height="20"> <INPUT type="text" size="15" name="LoginID"></TD> | |
| 46 | + </TR> | |
| 47 | + <TR> | |
| 48 | + <TD height="20"><div class="text">>> パスワード</div></TD> | |
| 49 | + <TD height="20"> <INPUT type="password" size="15" name="Passwd"></TD> | |
| 50 | + </TR> | |
| 51 | + <TR> | |
| 52 | + <TD height="20"> </TD> | |
| 53 | + <TD height="20"><INPUT type="submit" value="ログイン"></TD> | |
| 54 | + </TR> | |
| 55 | + <TR> | |
| 56 | + <TD colspan=2 height="30"></TD> | |
| 57 | + </TR> | |
| 58 | + </TABLE> | |
| 59 | + </div></div> | |
| 60 | + </TD> | |
| 61 | + </TR> | |
| 62 | + <TR> | |
| 63 | + <TD class="admin_footer" align="center">Copyright © <a href="http://www.media-tek.co.jp/" target="_blank">メディアテック株式会社</a>All rights reserved.</TD> | |
| 64 | + </TR> | |
| 65 | + </TABLE> | |
| 66 | +</form> | |
| 67 | +</center> | |
| 68 | +</body> | |
| 69 | +</HTML> | |
| \ No newline at end of file | ... | ... |
Smarty/Config_File.class.php
0 → 100644
| 1 | +<?PHP | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Config_File class. | |
| 5 | + * | |
| 6 | + * This library is free software; you can redistribute it and/or | |
| 7 | + * modify it under the terms of the GNU Lesser General Public | |
| 8 | + * License as published by the Free Software Foundation; either | |
| 9 | + * version 2.1 of the License, or (at your option) any later version. | |
| 10 | + * | |
| 11 | + * This library is distributed in the hope that it will be useful, | |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 14 | + * Lesser General Public License for more details. | |
| 15 | + * | |
| 16 | + * You should have received a copy of the GNU Lesser General Public | |
| 17 | + * License along with this library; if not, write to the Free Software | |
| 18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 | + * | |
| 20 | + * For questions, help, comments, discussion, etc., please join the | |
| 21 | + * Smarty mailing list. Send a blank e-mail to | |
| 22 | + * smarty-discussion-subscribe@googlegroups.com | |
| 23 | + * | |
| 24 | + * @link http://www.smarty.net/ | |
| 25 | + * @version 2.6.26 | |
| 26 | + * @copyright Copyright: 2001-2005 New Digital Group, Inc. | |
| 27 | + * @author Andrei Zmievski <andrei@php.net> | |
| 28 | + * @access public | |
| 29 | + * @package Smarty | |
| 30 | + */ | |
| 31 | + | |
| 32 | +/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */ | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * Config file reading class | |
| 36 | + * @package Smarty | |
| 37 | + */ | |
| 38 | +class Config_File { | |
| 39 | + /**#@+ | |
| 40 | + * Options | |
| 41 | + * @var boolean | |
| 42 | + */ | |
| 43 | + /** | |
| 44 | + * Controls whether variables with the same name overwrite each other. | |
| 45 | + */ | |
| 46 | + var $overwrite = true; | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * Controls whether config values of on/true/yes and off/false/no get | |
| 50 | + * converted to boolean values automatically. | |
| 51 | + */ | |
| 52 | + var $booleanize = true; | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * Controls whether hidden config sections/vars are read from the file. | |
| 56 | + */ | |
| 57 | + var $read_hidden = true; | |
| 58 | + | |
| 59 | + /** | |
| 60 | + * Controls whether or not to fix mac or dos formatted newlines. | |
| 61 | + * If set to true, \r or \r\n will be changed to \n. | |
| 62 | + */ | |
| 63 | + var $fix_newlines = true; | |
| 64 | + /**#@-*/ | |
| 65 | + | |
| 66 | + /** @access private */ | |
| 67 | + var $_config_path = ""; | |
| 68 | + var $_config_data = array(); | |
| 69 | + /**#@-*/ | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Constructs a new config file class. | |
| 73 | + * | |
| 74 | + * @param string $config_path (optional) path to the config files | |
| 75 | + */ | |
| 76 | + function Config_File($config_path = NULL) | |
| 77 | + { | |
| 78 | + if (isset($config_path)) | |
| 79 | + $this->set_path($config_path); | |
| 80 | + } | |
| 81 | + | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * Set the path where configuration files can be found. | |
| 85 | + * | |
| 86 | + * @param string $config_path path to the config files | |
| 87 | + */ | |
| 88 | + function set_path($config_path) | |
| 89 | + { | |
| 90 | + if (!empty($config_path)) { | |
| 91 | + if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { | |
| 92 | + $this->_trigger_error_msg("Bad config file path '$config_path'"); | |
| 93 | + return; | |
| 94 | + } | |
| 95 | + if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { | |
| 96 | + $config_path .= DIRECTORY_SEPARATOR; | |
| 97 | + } | |
| 98 | + | |
| 99 | + $this->_config_path = $config_path; | |
| 100 | + } | |
| 101 | + } | |
| 102 | + | |
| 103 | + | |
| 104 | + /** | |
| 105 | + * Retrieves config info based on the file, section, and variable name. | |
| 106 | + * | |
| 107 | + * @param string $file_name config file to get info for | |
| 108 | + * @param string $section_name (optional) section to get info for | |
| 109 | + * @param string $var_name (optional) variable to get info for | |
| 110 | + * @return string|array a value or array of values | |
| 111 | + */ | |
| 112 | + function get($file_name, $section_name = NULL, $var_name = NULL) | |
| 113 | + { | |
| 114 | + if (empty($file_name)) { | |
| 115 | + $this->_trigger_error_msg('Empty config file name'); | |
| 116 | + return; | |
| 117 | + } else { | |
| 118 | + $file_name = $this->_config_path . $file_name; | |
| 119 | + if (!isset($this->_config_data[$file_name])) | |
| 120 | + $this->load_file($file_name, false); | |
| 121 | + } | |
| 122 | + | |
| 123 | + if (!empty($var_name)) { | |
| 124 | + if (empty($section_name)) { | |
| 125 | + return $this->_config_data[$file_name]["vars"][$var_name]; | |
| 126 | + } else { | |
| 127 | + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) | |
| 128 | + return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; | |
| 129 | + else | |
| 130 | + return array(); | |
| 131 | + } | |
| 132 | + } else { | |
| 133 | + if (empty($section_name)) { | |
| 134 | + return (array)$this->_config_data[$file_name]["vars"]; | |
| 135 | + } else { | |
| 136 | + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) | |
| 137 | + return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; | |
| 138 | + else | |
| 139 | + return array(); | |
| 140 | + } | |
| 141 | + } | |
| 142 | + } | |
| 143 | + | |
| 144 | + | |
| 145 | + /** | |
| 146 | + * Retrieves config info based on the key. | |
| 147 | + * | |
| 148 | + * @param $file_name string config key (filename/section/var) | |
| 149 | + * @return string|array same as get() | |
| 150 | + * @uses get() retrieves information from config file and returns it | |
| 151 | + */ | |
| 152 | + function &get_key($config_key) | |
| 153 | + { | |
| 154 | + list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); | |
| 155 | + $result = &$this->get($file_name, $section_name, $var_name); | |
| 156 | + return $result; | |
| 157 | + } | |
| 158 | + | |
| 159 | + /** | |
| 160 | + * Get all loaded config file names. | |
| 161 | + * | |
| 162 | + * @return array an array of loaded config file names | |
| 163 | + */ | |
| 164 | + function get_file_names() | |
| 165 | + { | |
| 166 | + return array_keys($this->_config_data); | |
| 167 | + } | |
| 168 | + | |
| 169 | + | |
| 170 | + /** | |
| 171 | + * Get all section names from a loaded file. | |
| 172 | + * | |
| 173 | + * @param string $file_name config file to get section names from | |
| 174 | + * @return array an array of section names from the specified file | |
| 175 | + */ | |
| 176 | + function get_section_names($file_name) | |
| 177 | + { | |
| 178 | + $file_name = $this->_config_path . $file_name; | |
| 179 | + if (!isset($this->_config_data[$file_name])) { | |
| 180 | + $this->_trigger_error_msg("Unknown config file '$file_name'"); | |
| 181 | + return; | |
| 182 | + } | |
| 183 | + | |
| 184 | + return array_keys($this->_config_data[$file_name]["sections"]); | |
| 185 | + } | |
| 186 | + | |
| 187 | + | |
| 188 | + /** | |
| 189 | + * Get all global or section variable names. | |
| 190 | + * | |
| 191 | + * @param string $file_name config file to get info for | |
| 192 | + * @param string $section_name (optional) section to get info for | |
| 193 | + * @return array an array of variables names from the specified file/section | |
| 194 | + */ | |
| 195 | + function get_var_names($file_name, $section = NULL) | |
| 196 | + { | |
| 197 | + if (empty($file_name)) { | |
| 198 | + $this->_trigger_error_msg('Empty config file name'); | |
| 199 | + return; | |
| 200 | + } else if (!isset($this->_config_data[$file_name])) { | |
| 201 | + $this->_trigger_error_msg("Unknown config file '$file_name'"); | |
| 202 | + return; | |
| 203 | + } | |
| 204 | + | |
| 205 | + if (empty($section)) | |
| 206 | + return array_keys($this->_config_data[$file_name]["vars"]); | |
| 207 | + else | |
| 208 | + return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); | |
| 209 | + } | |
| 210 | + | |
| 211 | + | |
| 212 | + /** | |
| 213 | + * Clear loaded config data for a certain file or all files. | |
| 214 | + * | |
| 215 | + * @param string $file_name file to clear config data for | |
| 216 | + */ | |
| 217 | + function clear($file_name = NULL) | |
| 218 | + { | |
| 219 | + if ($file_name === NULL) | |
| 220 | + $this->_config_data = array(); | |
| 221 | + else if (isset($this->_config_data[$file_name])) | |
| 222 | + $this->_config_data[$file_name] = array(); | |
| 223 | + } | |
| 224 | + | |
| 225 | + | |
| 226 | + /** | |
| 227 | + * Load a configuration file manually. | |
| 228 | + * | |
| 229 | + * @param string $file_name file name to load | |
| 230 | + * @param boolean $prepend_path whether current config path should be | |
| 231 | + * prepended to the filename | |
| 232 | + */ | |
| 233 | + function load_file($file_name, $prepend_path = true) | |
| 234 | + { | |
| 235 | + if ($prepend_path && $this->_config_path != "") | |
| 236 | + $config_file = $this->_config_path . $file_name; | |
| 237 | + else | |
| 238 | + $config_file = $file_name; | |
| 239 | + | |
| 240 | + ini_set('track_errors', true); | |
| 241 | + $fp = @fopen($config_file, "r"); | |
| 242 | + if (!is_resource($fp)) { | |
| 243 | + $this->_trigger_error_msg("Could not open config file '$config_file'"); | |
| 244 | + return false; | |
| 245 | + } | |
| 246 | + | |
| 247 | + $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; | |
| 248 | + fclose($fp); | |
| 249 | + | |
| 250 | + $this->_config_data[$config_file] = $this->parse_contents($contents); | |
| 251 | + return true; | |
| 252 | + } | |
| 253 | + | |
| 254 | + /** | |
| 255 | + * Store the contents of a file manually. | |
| 256 | + * | |
| 257 | + * @param string $config_file file name of the related contents | |
| 258 | + * @param string $contents the file-contents to parse | |
| 259 | + */ | |
| 260 | + function set_file_contents($config_file, $contents) | |
| 261 | + { | |
| 262 | + $this->_config_data[$config_file] = $this->parse_contents($contents); | |
| 263 | + return true; | |
| 264 | + } | |
| 265 | + | |
| 266 | + /** | |
| 267 | + * parse the source of a configuration file manually. | |
| 268 | + * | |
| 269 | + * @param string $contents the file-contents to parse | |
| 270 | + */ | |
| 271 | + function parse_contents($contents) | |
| 272 | + { | |
| 273 | + if($this->fix_newlines) { | |
| 274 | + // fix mac/dos formatted newlines | |
| 275 | + $contents = preg_replace('!\r\n?!', "\n", $contents); | |
| 276 | + } | |
| 277 | + | |
| 278 | + $config_data = array(); | |
| 279 | + $config_data['sections'] = array(); | |
| 280 | + $config_data['vars'] = array(); | |
| 281 | + | |
| 282 | + /* reference to fill with data */ | |
| 283 | + $vars =& $config_data['vars']; | |
| 284 | + | |
| 285 | + /* parse file line by line */ | |
| 286 | + preg_match_all('!^.*\r?\n?!m', $contents, $match); | |
| 287 | + $lines = $match[0]; | |
| 288 | + for ($i=0, $count=count($lines); $i<$count; $i++) { | |
| 289 | + $line = $lines[$i]; | |
| 290 | + if (empty($line)) continue; | |
| 291 | + | |
| 292 | + if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { | |
| 293 | + /* section found */ | |
| 294 | + if (substr($match[1], 0, 1) == '.') { | |
| 295 | + /* hidden section */ | |
| 296 | + if ($this->read_hidden) { | |
| 297 | + $section_name = substr($match[1], 1); | |
| 298 | + } else { | |
| 299 | + /* break reference to $vars to ignore hidden section */ | |
| 300 | + unset($vars); | |
| 301 | + $vars = array(); | |
| 302 | + continue; | |
| 303 | + } | |
| 304 | + } else { | |
| 305 | + $section_name = $match[1]; | |
| 306 | + } | |
| 307 | + if (!isset($config_data['sections'][$section_name])) | |
| 308 | + $config_data['sections'][$section_name] = array('vars' => array()); | |
| 309 | + $vars =& $config_data['sections'][$section_name]['vars']; | |
| 310 | + continue; | |
| 311 | + } | |
| 312 | + | |
| 313 | + if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { | |
| 314 | + /* variable found */ | |
| 315 | + $var_name = rtrim($match[1]); | |
| 316 | + if (strpos($match[2], '"""') === 0) { | |
| 317 | + /* handle multiline-value */ | |
| 318 | + $lines[$i] = substr($match[2], 3); | |
| 319 | + $var_value = ''; | |
| 320 | + while ($i<$count) { | |
| 321 | + if (($pos = strpos($lines[$i], '"""')) === false) { | |
| 322 | + $var_value .= $lines[$i++]; | |
| 323 | + } else { | |
| 324 | + /* end of multiline-value */ | |
| 325 | + $var_value .= substr($lines[$i], 0, $pos); | |
| 326 | + break; | |
| 327 | + } | |
| 328 | + } | |
| 329 | + $booleanize = false; | |
| 330 | + | |
| 331 | + } else { | |
| 332 | + /* handle simple value */ | |
| 333 | + $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); | |
| 334 | + $booleanize = $this->booleanize; | |
| 335 | + | |
| 336 | + } | |
| 337 | + $this->_set_config_var($vars, $var_name, $var_value, $booleanize); | |
| 338 | + } | |
| 339 | + /* else unparsable line / means it is a comment / means ignore it */ | |
| 340 | + } | |
| 341 | + return $config_data; | |
| 342 | + } | |
| 343 | + | |
| 344 | + /**#@+ @access private */ | |
| 345 | + /** | |
| 346 | + * @param array &$container | |
| 347 | + * @param string $var_name | |
| 348 | + * @param mixed $var_value | |
| 349 | + * @param boolean $booleanize determines whether $var_value is converted to | |
| 350 | + * to true/false | |
| 351 | + */ | |
| 352 | + function _set_config_var(&$container, $var_name, $var_value, $booleanize) | |
| 353 | + { | |
| 354 | + if (substr($var_name, 0, 1) == '.') { | |
| 355 | + if (!$this->read_hidden) | |
| 356 | + return; | |
| 357 | + else | |
| 358 | + $var_name = substr($var_name, 1); | |
| 359 | + } | |
| 360 | + | |
| 361 | + if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { | |
| 362 | + $this->_trigger_error_msg("Bad variable name '$var_name'"); | |
| 363 | + return; | |
| 364 | + } | |
| 365 | + | |
| 366 | + if ($booleanize) { | |
| 367 | + if (preg_match("/^(on|true|yes)$/i", $var_value)) | |
| 368 | + $var_value = true; | |
| 369 | + else if (preg_match("/^(off|false|no)$/i", $var_value)) | |
| 370 | + $var_value = false; | |
| 371 | + } | |
| 372 | + | |
| 373 | + if (!isset($container[$var_name]) || $this->overwrite) | |
| 374 | + $container[$var_name] = $var_value; | |
| 375 | + else { | |
| 376 | + settype($container[$var_name], 'array'); | |
| 377 | + $container[$var_name][] = $var_value; | |
| 378 | + } | |
| 379 | + } | |
| 380 | + | |
| 381 | + /** | |
| 382 | + * @uses trigger_error() creates a PHP warning/error | |
| 383 | + * @param string $error_msg | |
| 384 | + * @param integer $error_type one of | |
| 385 | + */ | |
| 386 | + function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) | |
| 387 | + { | |
| 388 | + trigger_error("Config_File error: $error_msg", $error_type); | |
| 389 | + } | |
| 390 | + /**#@-*/ | |
| 391 | +} | |
| 392 | + | |
| 393 | +?> | ... | ... |
Smarty/Smarty.class.php
0 → 100644
| 1 | +<?PHP | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Project: Smarty: the PHP compiling template engine | |
| 5 | + * File: Smarty.class.php | |
| 6 | + * | |
| 7 | + * This library is free software; you can redistribute it and/or | |
| 8 | + * modify it under the terms of the GNU Lesser General Public | |
| 9 | + * License as published by the Free Software Foundation; either | |
| 10 | + * version 2.1 of the License, or (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This library is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | + * Lesser General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU Lesser General Public | |
| 18 | + * License along with this library; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 20 | + * | |
| 21 | + * For questions, help, comments, discussion, etc., please join the | |
| 22 | + * Smarty mailing list. Send a blank e-mail to | |
| 23 | + * smarty-discussion-subscribe@googlegroups.com | |
| 24 | + * | |
| 25 | + * @link http://www.smarty.net/ | |
| 26 | + * @copyright 2001-2005 New Digital Group, Inc. | |
| 27 | + * @author Monte Ohrt <monte at ohrt dot com> | |
| 28 | + * @author Andrei Zmievski <andrei@php.net> | |
| 29 | + * @package Smarty | |
| 30 | + * @version 2.6.26 | |
| 31 | + */ | |
| 32 | + | |
| 33 | +/* $Id: Smarty.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */ | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * DIR_SEP isn't used anymore, but third party apps might | |
| 37 | + */ | |
| 38 | +if(!defined('DIR_SEP')) { | |
| 39 | + define('DIR_SEP', DIRECTORY_SEPARATOR); | |
| 40 | +} | |
| 41 | + | |
| 42 | +/** | |
| 43 | + * set SMARTY_DIR to absolute path to Smarty library files. | |
| 44 | + * if not defined, include_path will be used. Sets SMARTY_DIR only if user | |
| 45 | + * application has not already defined it. | |
| 46 | + */ | |
| 47 | + | |
| 48 | +if (!defined('SMARTY_DIR')) { | |
| 49 | + define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); | |
| 50 | +} | |
| 51 | + | |
| 52 | +if (!defined('SMARTY_CORE_DIR')) { | |
| 53 | + define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR); | |
| 54 | +} | |
| 55 | + | |
| 56 | +define('SMARTY_PHP_PASSTHRU', 0); | |
| 57 | +define('SMARTY_PHP_QUOTE', 1); | |
| 58 | +define('SMARTY_PHP_REMOVE', 2); | |
| 59 | +define('SMARTY_PHP_ALLOW', 3); | |
| 60 | + | |
| 61 | +/** | |
| 62 | + * @package Smarty | |
| 63 | + */ | |
| 64 | +class Smarty | |
| 65 | +{ | |
| 66 | + /**#@+ | |
| 67 | + * Smarty Configuration Section | |
| 68 | + */ | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * The name of the directory where templates are located. | |
| 72 | + * | |
| 73 | + * @var string | |
| 74 | + */ | |
| 75 | + var $template_dir = 'templates'; | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * The directory where compiled templates are located. | |
| 79 | + * | |
| 80 | + * @var string | |
| 81 | + */ | |
| 82 | + var $compile_dir = 'templates_c'; | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * The directory where config files are located. | |
| 86 | + * | |
| 87 | + * @var string | |
| 88 | + */ | |
| 89 | + var $config_dir = 'configs'; | |
| 90 | + | |
| 91 | + /** | |
| 92 | + * An array of directories searched for plugins. | |
| 93 | + * | |
| 94 | + * @var array | |
| 95 | + */ | |
| 96 | + var $plugins_dir = array('plugins'); | |
| 97 | + | |
| 98 | + /** | |
| 99 | + * If debugging is enabled, a debug console window will display | |
| 100 | + * when the page loads (make sure your browser allows unrequested | |
| 101 | + * popup windows) | |
| 102 | + * | |
| 103 | + * @var boolean | |
| 104 | + */ | |
| 105 | + var $debugging = false; | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * When set, smarty does uses this value as error_reporting-level. | |
| 109 | + * | |
| 110 | + * @var integer | |
| 111 | + */ | |
| 112 | + var $error_reporting = null; | |
| 113 | + | |
| 114 | + /** | |
| 115 | + * This is the path to the debug console template. If not set, | |
| 116 | + * the default one will be used. | |
| 117 | + * | |
| 118 | + * @var string | |
| 119 | + */ | |
| 120 | + var $debug_tpl = ''; | |
| 121 | + | |
| 122 | + /** | |
| 123 | + * This determines if debugging is enable-able from the browser. | |
| 124 | + * <ul> | |
| 125 | + * <li>NONE => no debugging control allowed</li> | |
| 126 | + * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> | |
| 127 | + * </ul> | |
| 128 | + * @link http://www.foo.dom/index.php?SMARTY_DEBUG | |
| 129 | + * @var string | |
| 130 | + */ | |
| 131 | + var $debugging_ctrl = 'NONE'; | |
| 132 | + | |
| 133 | + /** | |
| 134 | + * This tells Smarty whether to check for recompiling or not. Recompiling | |
| 135 | + * does not need to happen unless a template or config file is changed. | |
| 136 | + * Typically you enable this during development, and disable for | |
| 137 | + * production. | |
| 138 | + * | |
| 139 | + * @var boolean | |
| 140 | + */ | |
| 141 | + var $compile_check = true; | |
| 142 | + | |
| 143 | + /** | |
| 144 | + * This forces templates to compile every time. Useful for development | |
| 145 | + * or debugging. | |
| 146 | + * | |
| 147 | + * @var boolean | |
| 148 | + */ | |
| 149 | + var $force_compile = false; | |
| 150 | + | |
| 151 | + /** | |
| 152 | + * This enables template caching. | |
| 153 | + * <ul> | |
| 154 | + * <li>0 = no caching</li> | |
| 155 | + * <li>1 = use class cache_lifetime value</li> | |
| 156 | + * <li>2 = use cache_lifetime in cache file</li> | |
| 157 | + * </ul> | |
| 158 | + * @var integer | |
| 159 | + */ | |
| 160 | + var $caching = 0; | |
| 161 | + | |
| 162 | + /** | |
| 163 | + * The name of the directory for cache files. | |
| 164 | + * | |
| 165 | + * @var string | |
| 166 | + */ | |
| 167 | + var $cache_dir = 'cache'; | |
| 168 | + | |
| 169 | + /** | |
| 170 | + * This is the number of seconds cached content will persist. | |
| 171 | + * <ul> | |
| 172 | + * <li>0 = always regenerate cache</li> | |
| 173 | + * <li>-1 = never expires</li> | |
| 174 | + * </ul> | |
| 175 | + * | |
| 176 | + * @var integer | |
| 177 | + */ | |
| 178 | + var $cache_lifetime = 3600; | |
| 179 | + | |
| 180 | + /** | |
| 181 | + * Only used when $caching is enabled. If true, then If-Modified-Since headers | |
| 182 | + * are respected with cached content, and appropriate HTTP headers are sent. | |
| 183 | + * This way repeated hits to a cached page do not send the entire page to the | |
| 184 | + * client every time. | |
| 185 | + * | |
| 186 | + * @var boolean | |
| 187 | + */ | |
| 188 | + var $cache_modified_check = false; | |
| 189 | + | |
| 190 | + /** | |
| 191 | + * This determines how Smarty handles "<?PHP ... ?>" tags in templates. | |
| 192 | + * possible values: | |
| 193 | + * <ul> | |
| 194 | + * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li> | |
| 195 | + * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li> | |
| 196 | + * <li>SMARTY_PHP_REMOVE -> remove php tags</li> | |
| 197 | + * <li>SMARTY_PHP_ALLOW -> execute php tags</li> | |
| 198 | + * </ul> | |
| 199 | + * | |
| 200 | + * @var integer | |
| 201 | + */ | |
| 202 | + var $php_handling = SMARTY_PHP_PASSTHRU; | |
| 203 | + | |
| 204 | + /** | |
| 205 | + * This enables template security. When enabled, many things are restricted | |
| 206 | + * in the templates that normally would go unchecked. This is useful when | |
| 207 | + * untrusted parties are editing templates and you want a reasonable level | |
| 208 | + * of security. (no direct execution of PHP in templates for example) | |
| 209 | + * | |
| 210 | + * @var boolean | |
| 211 | + */ | |
| 212 | + var $security = false; | |
| 213 | + | |
| 214 | + /** | |
| 215 | + * This is the list of template directories that are considered secure. This | |
| 216 | + * is used only if {@link $security} is enabled. One directory per array | |
| 217 | + * element. {@link $template_dir} is in this list implicitly. | |
| 218 | + * | |
| 219 | + * @var array | |
| 220 | + */ | |
| 221 | + var $secure_dir = array(); | |
| 222 | + | |
| 223 | + /** | |
| 224 | + * These are the security settings for Smarty. They are used only when | |
| 225 | + * {@link $security} is enabled. | |
| 226 | + * | |
| 227 | + * @var array | |
| 228 | + */ | |
| 229 | + var $security_settings = array( | |
| 230 | + 'PHP_HANDLING' => false, | |
| 231 | + 'IF_FUNCS' => array('array', 'list', | |
| 232 | + 'isset', 'empty', | |
| 233 | + 'count', 'sizeof', | |
| 234 | + 'in_array', 'is_array', | |
| 235 | + 'true', 'false', 'null'), | |
| 236 | + 'INCLUDE_ANY' => false, | |
| 237 | + 'PHP_TAGS' => false, | |
| 238 | + 'MODIFIER_FUNCS' => array('count'), | |
| 239 | + 'ALLOW_CONSTANTS' => false, | |
| 240 | + 'ALLOW_SUPER_GLOBALS' => true | |
| 241 | + ); | |
| 242 | + | |
| 243 | + /** | |
| 244 | + * This is an array of directories where trusted php scripts reside. | |
| 245 | + * {@link $security} is disabled during their inclusion/execution. | |
| 246 | + * | |
| 247 | + * @var array | |
| 248 | + */ | |
| 249 | + var $trusted_dir = array(); | |
| 250 | + | |
| 251 | + /** | |
| 252 | + * The left delimiter used for the template tags. | |
| 253 | + * | |
| 254 | + * @var string | |
| 255 | + */ | |
| 256 | + var $left_delimiter = '{'; | |
| 257 | + | |
| 258 | + /** | |
| 259 | + * The right delimiter used for the template tags. | |
| 260 | + * | |
| 261 | + * @var string | |
| 262 | + */ | |
| 263 | + var $right_delimiter = '}'; | |
| 264 | + | |
| 265 | + /** | |
| 266 | + * The order in which request variables are registered, similar to | |
| 267 | + * variables_order in php.ini E = Environment, G = GET, P = POST, | |
| 268 | + * C = Cookies, S = Server | |
| 269 | + * | |
| 270 | + * @var string | |
| 271 | + */ | |
| 272 | + var $request_vars_order = 'EGPCS'; | |
| 273 | + | |
| 274 | + /** | |
| 275 | + * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) | |
| 276 | + * are uses as request-vars or $_*[]-vars. note: if | |
| 277 | + * request_use_auto_globals is true, then $request_vars_order has | |
| 278 | + * no effect, but the php-ini-value "gpc_order" | |
| 279 | + * | |
| 280 | + * @var boolean | |
| 281 | + */ | |
| 282 | + var $request_use_auto_globals = true; | |
| 283 | + | |
| 284 | + /** | |
| 285 | + * Set this if you want different sets of compiled files for the same | |
| 286 | + * templates. This is useful for things like different languages. | |
| 287 | + * Instead of creating separate sets of templates per language, you | |
| 288 | + * set different compile_ids like 'en' and 'de'. | |
| 289 | + * | |
| 290 | + * @var string | |
| 291 | + */ | |
| 292 | + var $compile_id = null; | |
| 293 | + | |
| 294 | + /** | |
| 295 | + * This tells Smarty whether or not to use sub dirs in the cache/ and | |
| 296 | + * templates_c/ directories. sub directories better organized, but | |
| 297 | + * may not work well with PHP safe mode enabled. | |
| 298 | + * | |
| 299 | + * @var boolean | |
| 300 | + * | |
| 301 | + */ | |
| 302 | + var $use_sub_dirs = false; | |
| 303 | + | |
| 304 | + /** | |
| 305 | + * This is a list of the modifiers to apply to all template variables. | |
| 306 | + * Put each modifier in a separate array element in the order you want | |
| 307 | + * them applied. example: <code>array('escape:"htmlall"');</code> | |
| 308 | + * | |
| 309 | + * @var array | |
| 310 | + */ | |
| 311 | + var $default_modifiers = array(); | |
| 312 | + | |
| 313 | + /** | |
| 314 | + * This is the resource type to be used when not specified | |
| 315 | + * at the beginning of the resource path. examples: | |
| 316 | + * $smarty->display('file:index.tpl'); | |
| 317 | + * $smarty->display('db:index.tpl'); | |
| 318 | + * $smarty->display('index.tpl'); // will use default resource type | |
| 319 | + * {include file="file:index.tpl"} | |
| 320 | + * {include file="db:index.tpl"} | |
| 321 | + * {include file="index.tpl"} {* will use default resource type *} | |
| 322 | + * | |
| 323 | + * @var array | |
| 324 | + */ | |
| 325 | + var $default_resource_type = 'file'; | |
| 326 | + | |
| 327 | + /** | |
| 328 | + * The function used for cache file handling. If not set, built-in caching is used. | |
| 329 | + * | |
| 330 | + * @var null|string function name | |
| 331 | + */ | |
| 332 | + var $cache_handler_func = null; | |
| 333 | + | |
| 334 | + /** | |
| 335 | + * This indicates which filters are automatically loaded into Smarty. | |
| 336 | + * | |
| 337 | + * @var array array of filter names | |
| 338 | + */ | |
| 339 | + var $autoload_filters = array(); | |
| 340 | + | |
| 341 | + /**#@+ | |
| 342 | + * @var boolean | |
| 343 | + */ | |
| 344 | + /** | |
| 345 | + * This tells if config file vars of the same name overwrite each other or not. | |
| 346 | + * if disabled, same name variables are accumulated in an array. | |
| 347 | + */ | |
| 348 | + var $config_overwrite = true; | |
| 349 | + | |
| 350 | + /** | |
| 351 | + * This tells whether or not to automatically booleanize config file variables. | |
| 352 | + * If enabled, then the strings "on", "true", and "yes" are treated as boolean | |
| 353 | + * true, and "off", "false" and "no" are treated as boolean false. | |
| 354 | + */ | |
| 355 | + var $config_booleanize = true; | |
| 356 | + | |
| 357 | + /** | |
| 358 | + * This tells whether hidden sections [.foobar] are readable from the | |
| 359 | + * tempalates or not. Normally you would never allow this since that is | |
| 360 | + * the point behind hidden sections: the application can access them, but | |
| 361 | + * the templates cannot. | |
| 362 | + */ | |
| 363 | + var $config_read_hidden = false; | |
| 364 | + | |
| 365 | + /** | |
| 366 | + * This tells whether or not automatically fix newlines in config files. | |
| 367 | + * It basically converts \r (mac) or \r\n (dos) to \n | |
| 368 | + */ | |
| 369 | + var $config_fix_newlines = true; | |
| 370 | + /**#@-*/ | |
| 371 | + | |
| 372 | + /** | |
| 373 | + * If a template cannot be found, this PHP function will be executed. | |
| 374 | + * Useful for creating templates on-the-fly or other special action. | |
| 375 | + * | |
| 376 | + * @var string function name | |
| 377 | + */ | |
| 378 | + var $default_template_handler_func = ''; | |
| 379 | + | |
| 380 | + /** | |
| 381 | + * The file that contains the compiler class. This can a full | |
| 382 | + * pathname, or relative to the php_include path. | |
| 383 | + * | |
| 384 | + * @var string | |
| 385 | + */ | |
| 386 | + var $compiler_file = 'Smarty_Compiler.class.php'; | |
| 387 | + | |
| 388 | + /** | |
| 389 | + * The class used for compiling templates. | |
| 390 | + * | |
| 391 | + * @var string | |
| 392 | + */ | |
| 393 | + var $compiler_class = 'Smarty_Compiler'; | |
| 394 | + | |
| 395 | + /** | |
| 396 | + * The class used to load config vars. | |
| 397 | + * | |
| 398 | + * @var string | |
| 399 | + */ | |
| 400 | + var $config_class = 'Config_File'; | |
| 401 | + | |
| 402 | +/**#@+ | |
| 403 | + * END Smarty Configuration Section | |
| 404 | + * There should be no need to touch anything below this line. | |
| 405 | + * @access private | |
| 406 | + */ | |
| 407 | + /** | |
| 408 | + * where assigned template vars are kept | |
| 409 | + * | |
| 410 | + * @var array | |
| 411 | + */ | |
| 412 | + var $_tpl_vars = array(); | |
| 413 | + | |
| 414 | + /** | |
| 415 | + * stores run-time $smarty.* vars | |
| 416 | + * | |
| 417 | + * @var null|array | |
| 418 | + */ | |
| 419 | + var $_smarty_vars = null; | |
| 420 | + | |
| 421 | + /** | |
| 422 | + * keeps track of sections | |
| 423 | + * | |
| 424 | + * @var array | |
| 425 | + */ | |
| 426 | + var $_sections = array(); | |
| 427 | + | |
| 428 | + /** | |
| 429 | + * keeps track of foreach blocks | |
| 430 | + * | |
| 431 | + * @var array | |
| 432 | + */ | |
| 433 | + var $_foreach = array(); | |
| 434 | + | |
| 435 | + /** | |
| 436 | + * keeps track of tag hierarchy | |
| 437 | + * | |
| 438 | + * @var array | |
| 439 | + */ | |
| 440 | + var $_tag_stack = array(); | |
| 441 | + | |
| 442 | + /** | |
| 443 | + * configuration object | |
| 444 | + * | |
| 445 | + * @var Config_file | |
| 446 | + */ | |
| 447 | + var $_conf_obj = null; | |
| 448 | + | |
| 449 | + /** | |
| 450 | + * loaded configuration settings | |
| 451 | + * | |
| 452 | + * @var array | |
| 453 | + */ | |
| 454 | + var $_config = array(array('vars' => array(), 'files' => array())); | |
| 455 | + | |
| 456 | + /** | |
| 457 | + * md5 checksum of the string 'Smarty' | |
| 458 | + * | |
| 459 | + * @var string | |
| 460 | + */ | |
| 461 | + var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; | |
| 462 | + | |
| 463 | + /** | |
| 464 | + * Smarty version number | |
| 465 | + * | |
| 466 | + * @var string | |
| 467 | + */ | |
| 468 | + var $_version = '2.6.26'; | |
| 469 | + | |
| 470 | + /** | |
| 471 | + * current template inclusion depth | |
| 472 | + * | |
| 473 | + * @var integer | |
| 474 | + */ | |
| 475 | + var $_inclusion_depth = 0; | |
| 476 | + | |
| 477 | + /** | |
| 478 | + * for different compiled templates | |
| 479 | + * | |
| 480 | + * @var string | |
| 481 | + */ | |
| 482 | + var $_compile_id = null; | |
| 483 | + | |
| 484 | + /** | |
| 485 | + * text in URL to enable debug mode | |
| 486 | + * | |
| 487 | + * @var string | |
| 488 | + */ | |
| 489 | + var $_smarty_debug_id = 'SMARTY_DEBUG'; | |
| 490 | + | |
| 491 | + /** | |
| 492 | + * debugging information for debug console | |
| 493 | + * | |
| 494 | + * @var array | |
| 495 | + */ | |
| 496 | + var $_smarty_debug_info = array(); | |
| 497 | + | |
| 498 | + /** | |
| 499 | + * info that makes up a cache file | |
| 500 | + * | |
| 501 | + * @var array | |
| 502 | + */ | |
| 503 | + var $_cache_info = array(); | |
| 504 | + | |
| 505 | + /** | |
| 506 | + * default file permissions | |
| 507 | + * | |
| 508 | + * @var integer | |
| 509 | + */ | |
| 510 | + var $_file_perms = 0644; | |
| 511 | + | |
| 512 | + /** | |
| 513 | + * default dir permissions | |
| 514 | + * | |
| 515 | + * @var integer | |
| 516 | + */ | |
| 517 | + var $_dir_perms = 0771; | |
| 518 | + | |
| 519 | + /** | |
| 520 | + * registered objects | |
| 521 | + * | |
| 522 | + * @var array | |
| 523 | + */ | |
| 524 | + var $_reg_objects = array(); | |
| 525 | + | |
| 526 | + /** | |
| 527 | + * table keeping track of plugins | |
| 528 | + * | |
| 529 | + * @var array | |
| 530 | + */ | |
| 531 | + var $_plugins = array( | |
| 532 | + 'modifier' => array(), | |
| 533 | + 'function' => array(), | |
| 534 | + 'block' => array(), | |
| 535 | + 'compiler' => array(), | |
| 536 | + 'prefilter' => array(), | |
| 537 | + 'postfilter' => array(), | |
| 538 | + 'outputfilter' => array(), | |
| 539 | + 'resource' => array(), | |
| 540 | + 'insert' => array()); | |
| 541 | + | |
| 542 | + | |
| 543 | + /** | |
| 544 | + * cache serials | |
| 545 | + * | |
| 546 | + * @var array | |
| 547 | + */ | |
| 548 | + var $_cache_serials = array(); | |
| 549 | + | |
| 550 | + /** | |
| 551 | + * name of optional cache include file | |
| 552 | + * | |
| 553 | + * @var string | |
| 554 | + */ | |
| 555 | + var $_cache_include = null; | |
| 556 | + | |
| 557 | + /** | |
| 558 | + * indicate if the current code is used in a compiled | |
| 559 | + * include | |
| 560 | + * | |
| 561 | + * @var string | |
| 562 | + */ | |
| 563 | + var $_cache_including = false; | |
| 564 | + | |
| 565 | + /**#@-*/ | |
| 566 | + /** | |
| 567 | + * The class constructor. | |
| 568 | + */ | |
| 569 | + function Smarty() | |
| 570 | + { | |
| 571 | + $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] | |
| 572 | + : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); | |
| 573 | + } | |
| 574 | + | |
| 575 | + /** | |
| 576 | + * assigns values to template variables | |
| 577 | + * | |
| 578 | + * @param array|string $tpl_var the template variable name(s) | |
| 579 | + * @param mixed $value the value to assign | |
| 580 | + */ | |
| 581 | + function assign($tpl_var, $value = null) | |
| 582 | + { | |
| 583 | + if (is_array($tpl_var)){ | |
| 584 | + foreach ($tpl_var as $key => $val) { | |
| 585 | + if ($key != '') { | |
| 586 | + $this->_tpl_vars[$key] = $val; | |
| 587 | + } | |
| 588 | + } | |
| 589 | + } else { | |
| 590 | + if ($tpl_var != '') | |
| 591 | + $this->_tpl_vars[$tpl_var] = $value; | |
| 592 | + } | |
| 593 | + } | |
| 594 | + | |
| 595 | + /** | |
| 596 | + * assigns values to template variables by reference | |
| 597 | + * | |
| 598 | + * @param string $tpl_var the template variable name | |
| 599 | + * @param mixed $value the referenced value to assign | |
| 600 | + */ | |
| 601 | + function assign_by_ref($tpl_var, &$value) | |
| 602 | + { | |
| 603 | + if ($tpl_var != '') | |
| 604 | + $this->_tpl_vars[$tpl_var] = &$value; | |
| 605 | + } | |
| 606 | + | |
| 607 | + /** | |
| 608 | + * appends values to template variables | |
| 609 | + * | |
| 610 | + * @param array|string $tpl_var the template variable name(s) | |
| 611 | + * @param mixed $value the value to append | |
| 612 | + */ | |
| 613 | + function append($tpl_var, $value=null, $merge=false) | |
| 614 | + { | |
| 615 | + if (is_array($tpl_var)) { | |
| 616 | + // $tpl_var is an array, ignore $value | |
| 617 | + foreach ($tpl_var as $_key => $_val) { | |
| 618 | + if ($_key != '') { | |
| 619 | + if(!@is_array($this->_tpl_vars[$_key])) { | |
| 620 | + settype($this->_tpl_vars[$_key],'array'); | |
| 621 | + } | |
| 622 | + if($merge && is_array($_val)) { | |
| 623 | + foreach($_val as $_mkey => $_mval) { | |
| 624 | + $this->_tpl_vars[$_key][$_mkey] = $_mval; | |
| 625 | + } | |
| 626 | + } else { | |
| 627 | + $this->_tpl_vars[$_key][] = $_val; | |
| 628 | + } | |
| 629 | + } | |
| 630 | + } | |
| 631 | + } else { | |
| 632 | + if ($tpl_var != '' && isset($value)) { | |
| 633 | + if(!@is_array($this->_tpl_vars[$tpl_var])) { | |
| 634 | + settype($this->_tpl_vars[$tpl_var],'array'); | |
| 635 | + } | |
| 636 | + if($merge && is_array($value)) { | |
| 637 | + foreach($value as $_mkey => $_mval) { | |
| 638 | + $this->_tpl_vars[$tpl_var][$_mkey] = $_mval; | |
| 639 | + } | |
| 640 | + } else { | |
| 641 | + $this->_tpl_vars[$tpl_var][] = $value; | |
| 642 | + } | |
| 643 | + } | |
| 644 | + } | |
| 645 | + } | |
| 646 | + | |
| 647 | + /** | |
| 648 | + * appends values to template variables by reference | |
| 649 | + * | |
| 650 | + * @param string $tpl_var the template variable name | |
| 651 | + * @param mixed $value the referenced value to append | |
| 652 | + */ | |
| 653 | + function append_by_ref($tpl_var, &$value, $merge=false) | |
| 654 | + { | |
| 655 | + if ($tpl_var != '' && isset($value)) { | |
| 656 | + if(!@is_array($this->_tpl_vars[$tpl_var])) { | |
| 657 | + settype($this->_tpl_vars[$tpl_var],'array'); | |
| 658 | + } | |
| 659 | + if ($merge && is_array($value)) { | |
| 660 | + foreach($value as $_key => $_val) { | |
| 661 | + $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key]; | |
| 662 | + } | |
| 663 | + } else { | |
| 664 | + $this->_tpl_vars[$tpl_var][] = &$value; | |
| 665 | + } | |
| 666 | + } | |
| 667 | + } | |
| 668 | + | |
| 669 | + | |
| 670 | + /** | |
| 671 | + * clear the given assigned template variable. | |
| 672 | + * | |
| 673 | + * @param string $tpl_var the template variable to clear | |
| 674 | + */ | |
| 675 | + function clear_assign($tpl_var) | |
| 676 | + { | |
| 677 | + if (is_array($tpl_var)) | |
| 678 | + foreach ($tpl_var as $curr_var) | |
| 679 | + unset($this->_tpl_vars[$curr_var]); | |
| 680 | + else | |
| 681 | + unset($this->_tpl_vars[$tpl_var]); | |
| 682 | + } | |
| 683 | + | |
| 684 | + | |
| 685 | + /** | |
| 686 | + * Registers custom function to be used in templates | |
| 687 | + * | |
| 688 | + * @param string $function the name of the template function | |
| 689 | + * @param string $function_impl the name of the PHP function to register | |
| 690 | + */ | |
| 691 | + function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) | |
| 692 | + { | |
| 693 | + $this->_plugins['function'][$function] = | |
| 694 | + array($function_impl, null, null, false, $cacheable, $cache_attrs); | |
| 695 | + | |
| 696 | + } | |
| 697 | + | |
| 698 | + /** | |
| 699 | + * Unregisters custom function | |
| 700 | + * | |
| 701 | + * @param string $function name of template function | |
| 702 | + */ | |
| 703 | + function unregister_function($function) | |
| 704 | + { | |
| 705 | + unset($this->_plugins['function'][$function]); | |
| 706 | + } | |
| 707 | + | |
| 708 | + /** | |
| 709 | + * Registers object to be used in templates | |
| 710 | + * | |
| 711 | + * @param string $object name of template object | |
| 712 | + * @param object &$object_impl the referenced PHP object to register | |
| 713 | + * @param null|array $allowed list of allowed methods (empty = all) | |
| 714 | + * @param boolean $smarty_args smarty argument format, else traditional | |
| 715 | + * @param null|array $block_functs list of methods that are block format | |
| 716 | + */ | |
| 717 | + function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) | |
| 718 | + { | |
| 719 | + settype($allowed, 'array'); | |
| 720 | + settype($smarty_args, 'boolean'); | |
| 721 | + $this->_reg_objects[$object] = | |
| 722 | + array(&$object_impl, $allowed, $smarty_args, $block_methods); | |
| 723 | + } | |
| 724 | + | |
| 725 | + /** | |
| 726 | + * Unregisters object | |
| 727 | + * | |
| 728 | + * @param string $object name of template object | |
| 729 | + */ | |
| 730 | + function unregister_object($object) | |
| 731 | + { | |
| 732 | + unset($this->_reg_objects[$object]); | |
| 733 | + } | |
| 734 | + | |
| 735 | + | |
| 736 | + /** | |
| 737 | + * Registers block function to be used in templates | |
| 738 | + * | |
| 739 | + * @param string $block name of template block | |
| 740 | + * @param string $block_impl PHP function to register | |
| 741 | + */ | |
| 742 | + function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) | |
| 743 | + { | |
| 744 | + $this->_plugins['block'][$block] = | |
| 745 | + array($block_impl, null, null, false, $cacheable, $cache_attrs); | |
| 746 | + } | |
| 747 | + | |
| 748 | + /** | |
| 749 | + * Unregisters block function | |
| 750 | + * | |
| 751 | + * @param string $block name of template function | |
| 752 | + */ | |
| 753 | + function unregister_block($block) | |
| 754 | + { | |
| 755 | + unset($this->_plugins['block'][$block]); | |
| 756 | + } | |
| 757 | + | |
| 758 | + /** | |
| 759 | + * Registers compiler function | |
| 760 | + * | |
| 761 | + * @param string $function name of template function | |
| 762 | + * @param string $function_impl name of PHP function to register | |
| 763 | + */ | |
| 764 | + function register_compiler_function($function, $function_impl, $cacheable=true) | |
| 765 | + { | |
| 766 | + $this->_plugins['compiler'][$function] = | |
| 767 | + array($function_impl, null, null, false, $cacheable); | |
| 768 | + } | |
| 769 | + | |
| 770 | + /** | |
| 771 | + * Unregisters compiler function | |
| 772 | + * | |
| 773 | + * @param string $function name of template function | |
| 774 | + */ | |
| 775 | + function unregister_compiler_function($function) | |
| 776 | + { | |
| 777 | + unset($this->_plugins['compiler'][$function]); | |
| 778 | + } | |
| 779 | + | |
| 780 | + /** | |
| 781 | + * Registers modifier to be used in templates | |
| 782 | + * | |
| 783 | + * @param string $modifier name of template modifier | |
| 784 | + * @param string $modifier_impl name of PHP function to register | |
| 785 | + */ | |
| 786 | + function register_modifier($modifier, $modifier_impl) | |
| 787 | + { | |
| 788 | + $this->_plugins['modifier'][$modifier] = | |
| 789 | + array($modifier_impl, null, null, false); | |
| 790 | + } | |
| 791 | + | |
| 792 | + /** | |
| 793 | + * Unregisters modifier | |
| 794 | + * | |
| 795 | + * @param string $modifier name of template modifier | |
| 796 | + */ | |
| 797 | + function unregister_modifier($modifier) | |
| 798 | + { | |
| 799 | + unset($this->_plugins['modifier'][$modifier]); | |
| 800 | + } | |
| 801 | + | |
| 802 | + /** | |
| 803 | + * Registers a resource to fetch a template | |
| 804 | + * | |
| 805 | + * @param string $type name of resource | |
| 806 | + * @param array $functions array of functions to handle resource | |
| 807 | + */ | |
| 808 | + function register_resource($type, $functions) | |
| 809 | + { | |
| 810 | + if (count($functions)==4) { | |
| 811 | + $this->_plugins['resource'][$type] = | |
| 812 | + array($functions, false); | |
| 813 | + | |
| 814 | + } elseif (count($functions)==5) { | |
| 815 | + $this->_plugins['resource'][$type] = | |
| 816 | + array(array(array(&$functions[0], $functions[1]) | |
| 817 | + ,array(&$functions[0], $functions[2]) | |
| 818 | + ,array(&$functions[0], $functions[3]) | |
| 819 | + ,array(&$functions[0], $functions[4])) | |
| 820 | + ,false); | |
| 821 | + | |
| 822 | + } else { | |
| 823 | + $this->trigger_error("malformed function-list for '$type' in register_resource"); | |
| 824 | + | |
| 825 | + } | |
| 826 | + } | |
| 827 | + | |
| 828 | + /** | |
| 829 | + * Unregisters a resource | |
| 830 | + * | |
| 831 | + * @param string $type name of resource | |
| 832 | + */ | |
| 833 | + function unregister_resource($type) | |
| 834 | + { | |
| 835 | + unset($this->_plugins['resource'][$type]); | |
| 836 | + } | |
| 837 | + | |
| 838 | + /** | |
| 839 | + * Registers a prefilter function to apply | |
| 840 | + * to a template before compiling | |
| 841 | + * | |
| 842 | + * @param callback $function | |
| 843 | + */ | |
| 844 | + function register_prefilter($function) | |
| 845 | + { | |
| 846 | + $this->_plugins['prefilter'][$this->_get_filter_name($function)] | |
| 847 | + = array($function, null, null, false); | |
| 848 | + } | |
| 849 | + | |
| 850 | + /** | |
| 851 | + * Unregisters a prefilter function | |
| 852 | + * | |
| 853 | + * @param callback $function | |
| 854 | + */ | |
| 855 | + function unregister_prefilter($function) | |
| 856 | + { | |
| 857 | + unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]); | |
| 858 | + } | |
| 859 | + | |
| 860 | + /** | |
| 861 | + * Registers a postfilter function to apply | |
| 862 | + * to a compiled template after compilation | |
| 863 | + * | |
| 864 | + * @param callback $function | |
| 865 | + */ | |
| 866 | + function register_postfilter($function) | |
| 867 | + { | |
| 868 | + $this->_plugins['postfilter'][$this->_get_filter_name($function)] | |
| 869 | + = array($function, null, null, false); | |
| 870 | + } | |
| 871 | + | |
| 872 | + /** | |
| 873 | + * Unregisters a postfilter function | |
| 874 | + * | |
| 875 | + * @param callback $function | |
| 876 | + */ | |
| 877 | + function unregister_postfilter($function) | |
| 878 | + { | |
| 879 | + unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]); | |
| 880 | + } | |
| 881 | + | |
| 882 | + /** | |
| 883 | + * Registers an output filter function to apply | |
| 884 | + * to a template output | |
| 885 | + * | |
| 886 | + * @param callback $function | |
| 887 | + */ | |
| 888 | + function register_outputfilter($function) | |
| 889 | + { | |
| 890 | + $this->_plugins['outputfilter'][$this->_get_filter_name($function)] | |
| 891 | + = array($function, null, null, false); | |
| 892 | + } | |
| 893 | + | |
| 894 | + /** | |
| 895 | + * Unregisters an outputfilter function | |
| 896 | + * | |
| 897 | + * @param callback $function | |
| 898 | + */ | |
| 899 | + function unregister_outputfilter($function) | |
| 900 | + { | |
| 901 | + unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]); | |
| 902 | + } | |
| 903 | + | |
| 904 | + /** | |
| 905 | + * load a filter of specified type and name | |
| 906 | + * | |
| 907 | + * @param string $type filter type | |
| 908 | + * @param string $name filter name | |
| 909 | + */ | |
| 910 | + function load_filter($type, $name) | |
| 911 | + { | |
| 912 | + switch ($type) { | |
| 913 | + case 'output': | |
| 914 | + $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); | |
| 915 | + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); | |
| 916 | + smarty_core_load_plugins($_params, $this); | |
| 917 | + break; | |
| 918 | + | |
| 919 | + case 'pre': | |
| 920 | + case 'post': | |
| 921 | + if (!isset($this->_plugins[$type . 'filter'][$name])) | |
| 922 | + $this->_plugins[$type . 'filter'][$name] = false; | |
| 923 | + break; | |
| 924 | + } | |
| 925 | + } | |
| 926 | + | |
| 927 | + /** | |
| 928 | + * clear cached content for the given template and cache id | |
| 929 | + * | |
| 930 | + * @param string $tpl_file name of template file | |
| 931 | + * @param string $cache_id name of cache_id | |
| 932 | + * @param string $compile_id name of compile_id | |
| 933 | + * @param string $exp_time expiration time | |
| 934 | + * @return boolean | |
| 935 | + */ | |
| 936 | + function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) | |
| 937 | + { | |
| 938 | + | |
| 939 | + if (!isset($compile_id)) | |
| 940 | + $compile_id = $this->compile_id; | |
| 941 | + | |
| 942 | + if (!isset($tpl_file)) | |
| 943 | + $compile_id = null; | |
| 944 | + | |
| 945 | + $_auto_id = $this->_get_auto_id($cache_id, $compile_id); | |
| 946 | + | |
| 947 | + if (!empty($this->cache_handler_func)) { | |
| 948 | + return call_user_func_array($this->cache_handler_func, | |
| 949 | + array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time)); | |
| 950 | + } else { | |
| 951 | + $_params = array('auto_base' => $this->cache_dir, | |
| 952 | + 'auto_source' => $tpl_file, | |
| 953 | + 'auto_id' => $_auto_id, | |
| 954 | + 'exp_time' => $exp_time); | |
| 955 | + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); | |
| 956 | + return smarty_core_rm_auto($_params, $this); | |
| 957 | + } | |
| 958 | + | |
| 959 | + } | |
| 960 | + | |
| 961 | + | |
| 962 | + /** | |
| 963 | + * clear the entire contents of cache (all templates) | |
| 964 | + * | |
| 965 | + * @param string $exp_time expire time | |
| 966 | + * @return boolean results of {@link smarty_core_rm_auto()} | |
| 967 | + */ | |
| 968 | + function clear_all_cache($exp_time = null) | |
| 969 | + { | |
| 970 | + return $this->clear_cache(null, null, null, $exp_time); | |
| 971 | + } | |
| 972 | + | |
| 973 | + | |
| 974 | + /** | |
| 975 | + * test to see if valid cache exists for this template | |
| 976 | + * | |
| 977 | + * @param string $tpl_file name of template file | |
| 978 | + * @param string $cache_id | |
| 979 | + * @param string $compile_id | |
| 980 | + * @return string|false results of {@link _read_cache_file()} | |
| 981 | + */ | |
| 982 | + function is_cached($tpl_file, $cache_id = null, $compile_id = null) | |
| 983 | + { | |
| 984 | + if (!$this->caching) | |
| 985 | + return false; | |
| 986 | + | |
| 987 | + if (!isset($compile_id)) | |
| 988 | + $compile_id = $this->compile_id; | |
| 989 | + | |
| 990 | + $_params = array( | |
| 991 | + 'tpl_file' => $tpl_file, | |
| 992 | + 'cache_id' => $cache_id, | |
| 993 | + 'compile_id' => $compile_id | |
| 994 | + ); | |
| 995 | + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); | |
| 996 | + return smarty_core_read_cache_file($_params, $this); | |
| 997 | + } | |
| 998 | + | |
| 999 | + | |
| 1000 | + /** | |
| 1001 | + * clear all the assigned template variables. | |
| 1002 | + * | |
| 1003 | + */ | |
| 1004 | + function clear_all_assign() | |
| 1005 | + { | |
| 1006 | + $this->_tpl_vars = array(); | |
| 1007 | + } | |
| 1008 | + | |
| 1009 | + /** | |
| 1010 | + * clears compiled version of specified template resource, | |
| 1011 | + * or all compiled template files if one is not specified. | |
| 1012 | + * This function is for advanced use only, not normally needed. | |
| 1013 | + * | |
| 1014 | + * @param string $tpl_file | |
| 1015 | + * @param string $compile_id | |
| 1016 | + * @param string $exp_time | |
| 1017 | + * @return boolean results of {@link smarty_core_rm_auto()} | |
| 1018 | + */ | |
| 1019 | + function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) | |
| 1020 | + { | |
| 1021 | + if (!isset($compile_id)) { | |
| 1022 | + $compile_id = $this->compile_id; | |
| 1023 | + } | |
| 1024 | + $_params = array('auto_base' => $this->compile_dir, | |
| 1025 | + 'auto_source' => $tpl_file, | |
| 1026 | + 'auto_id' => $compile_id, | |
| 1027 | + 'exp_time' => $exp_time, | |
| 1028 | + 'extensions' => array('.inc', '.php')); | |
| 1029 | + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); | |
| 1030 | + return smarty_core_rm_auto($_params, $this); | |
| 1031 | + } | |
| 1032 | + | |
| 1033 | + /** | |
| 1034 | + * Checks whether requested template exists. | |
| 1035 | + * | |
| 1036 | + * @param string $tpl_file | |
| 1037 | + * @return boolean | |
| 1038 | + */ | |
| 1039 | + function template_exists($tpl_file) | |
| 1040 | + { | |
| 1041 | + $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false); | |
| 1042 | + return $this->_fetch_resource_info($_params); | |
| 1043 | + } | |
| 1044 | + | |
| 1045 | + /** | |
| 1046 | + * Returns an array containing template variables | |
| 1047 | + * | |
| 1048 | + * @param string $name | |
| 1049 | + * @param string $type | |
| 1050 | + * @return array | |
| 1051 | + */ | |
| 1052 | + function &get_template_vars($name=null) | |
| 1053 | + { | |
| 1054 | + if(!isset($name)) { | |
| 1055 | + return $this->_tpl_vars; | |
| 1056 | + } elseif(isset($this->_tpl_vars[$name])) { | |
| 1057 | + return $this->_tpl_vars[$name]; | |
| 1058 | + } else { | |
| 1059 | + // var non-existant, return valid reference | |
| 1060 | + $_tmp = null; | |
| 1061 | + return $_tmp; | |
| 1062 | + } | |
| 1063 | + } | |
| 1064 | + | |
| 1065 | + /** | |
| 1066 | + * Returns an array containing config variables | |
| 1067 | + * | |
| 1068 | + * @param string $name | |
| 1069 | + * @param string $type | |
| 1070 | + * @return array | |
| 1071 | + */ | |
| 1072 | + function &get_config_vars($name=null) | |
| 1073 | + { | |
| 1074 | + if(!isset($name) && is_array($this->_config[0])) { | |
| 1075 | + return $this->_config[0]['vars']; | |
| 1076 | + } else if(isset($this->_config[0]['vars'][$name])) { | |
| 1077 | + return $this->_config[0]['vars'][$name]; | |
| 1078 | + } else { | |
| 1079 | + // var non-existant, return valid reference | |
| 1080 | + $_tmp = null; | |
| 1081 | + return $_tmp; | |
| 1082 | + } | |
| 1083 | + } | |
| 1084 | + | |
| 1085 | + /** | |
| 1086 | + * trigger Smarty error | |
| 1087 | + * | |
| 1088 | + * @param string $error_msg | |
| 1089 | + * @param integer $error_type | |
| 1090 | + */ | |
| 1091 | + function trigger_error($error_msg, $error_type = E_USER_WARNING) | |
| 1092 | + { | |
| 1093 | + trigger_error("Smarty error: $error_msg", $error_type); | |
| 1094 | + } | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + /** | |
| 1098 | + * executes & displays the template results | |
| 1099 | + * | |
| 1100 | + * @param string $resource_name | |
| 1101 | + * @param string $cache_id | |
| 1102 | + * @param string $compile_id | |
| 1103 | + */ | |
| 1104 | + function display($resource_name, $cache_id = null, $compile_id = null) | |
| 1105 | + { | |
| 1106 | + $this->fetch($resource_name, $cache_id, $compile_id, true); | |
| 1107 | + } | |
| 1108 | + | |
| 1109 | + /** | |
| 1110 | + * executes & returns or displays the template results | |
| 1111 | + * | |
| 1112 | + * @param string $resource_name | |
| 1113 | + * @param string $cache_id | |
| 1114 | + * @param string $compile_id | |
| 1115 | + * @param boolean $display | |
| 1116 | + */ | |
| 1117 | + function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) | |
| 1118 | + { | |
| 1119 | + static $_cache_info = array(); | |
| 1120 | + | |
| 1121 | + $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting) | |
| 1122 | + ? $this->error_reporting : error_reporting() & ~E_NOTICE); | |
| 1123 | + | |
| 1124 | + if (!$this->debugging && $this->debugging_ctrl == 'URL') { | |
| 1125 | + $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']; | |
| 1126 | + if (@strstr($_query_string, $this->_smarty_debug_id)) { | |
| 1127 | + if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) { | |
| 1128 | + // enable debugging for this browser session | |
| 1129 | + @setcookie('SMARTY_DEBUG', true); | |
| 1130 | + $this->debugging = true; | |
| 1131 | + } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) { | |
| 1132 | + // disable debugging for this browser session | |
| 1133 | + @setcookie('SMARTY_DEBUG', false); | |
| 1134 | + $this->debugging = false; | |
| 1135 | + } else { | |
| 1136 | + // enable debugging for this page | |
| 1137 | + $this->debugging = true; | |
| 1138 | + } | |
| 1139 | + } else { | |
| 1140 | + $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']); | |
| 1141 | + } | |
| 1142 | + } | |
| 1143 | + | |
| 1144 | + if ($this->debugging) { | |
| 1145 | + // capture time for debugging info | |
| 1146 | + $_params = array(); | |
| 1147 | + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); | |
| 1148 | + $_debug_start_time = smarty_core_get_microtime($_params, $this); | |
| 1149 | + $this->_smarty_debug_info[] = array('type' => 'template', | |
| 1150 | + 'filename' => $resource_name, | |
| 1151 | + 'depth' => 0); | |
| 1152 | + $_included_tpls_idx = count($this->_smarty_debug_info) - 1; | |
| 1153 | + } | |
| 1154 | + | |
| 1155 | + if (!isset($compile_id)) { | |
| 1156 | + $compile_id = $this->compile_id; | |
| 1157 | + } | |
| 1158 | + | |
| 1159 | + $this->_compile_id = $compile_id; | |
| 1160 | + $this->_inclusion_depth = 0; | |
| 1161 | + | |
| 1162 | + if ($this->caching) { | |
| 1163 | + // save old cache_info, initialize cache_info | |
| 1164 | + array_push($_cache_info, $this->_cache_info); | |
| 1165 | + $this->_cache_info = array(); | |
| 1166 | + $_params = array( | |
| 1167 | + 'tpl_file' => $resource_name, | |
| 1168 | + 'cache_id' => $cache_id, | |
| 1169 | + 'compile_id' => $compile_id, | |
| 1170 | + 'results' => null | |
| 1171 | + ); | |
| 1172 | + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); | |
| 1173 | + if (smarty_core_read_cache_file($_params, $this)) { | |
| 1174 | + $_smarty_results = $_params['results']; | |
| 1175 | + if (!empty($this->_cache_info['insert_tags'])) { | |
| 1176 | + $_params = array('plugins' => $this->_cache_info['insert_tags']); | |
| 1177 | + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); | |
| 1178 | + smarty_core_load_plugins($_params, $this); | |
| 1179 | + $_params = array('results' => $_smarty_results); | |
| 1180 | + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); | |
| 1181 | + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); | |
| 1182 | + } | |
| 1183 | + if (!empty($this->_cache_info['cache_serials'])) { | |
| 1184 | + $_params = array('results' => $_smarty_results); | |
| 1185 | + require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php'); | |
| 1186 | + $_smarty_results = smarty_core_process_compiled_include($_params, $this); | |
| 1187 | + } | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + if ($display) { | |
| 1191 | + if ($this->debugging) | |
| 1192 | + { | |
| 1193 | + // capture time for debugging info | |
| 1194 | + $_params = array(); | |
| 1195 | + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); | |
| 1196 | + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; | |
| 1197 | + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); | |
| 1198 | + $_smarty_results .= smarty_core_display_debug_console($_params, $this); | |
| 1199 | + } | |
| 1200 | + if ($this->cache_modified_check) { | |
| 1201 | + $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; | |
| 1202 | + $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); | |
| 1203 | + $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; | |
| 1204 | + if (@count($this->_cache_info['insert_tags']) == 0 | |
| 1205 | + && !$this->_cache_serials | |
| 1206 | + && $_gmt_mtime == $_last_modified_date) { | |
| 1207 | + if (php_sapi_name()=='cgi') | |
| 1208 | + header('Status: 304 Not Modified'); | |
| 1209 | + else | |
| 1210 | + header('HTTP/1.1 304 Not Modified'); | |
| 1211 | + | |
| 1212 | + } else { | |
| 1213 | + header('Last-Modified: '.$_gmt_mtime); | |
| 1214 | + echo $_smarty_results; | |
| 1215 | + } | |
| 1216 | + } else { | |
| 1217 | + echo $_smarty_results; | |
| 1218 | + } | |
| 1219 | + error_reporting($_smarty_old_error_level); | |
| 1220 | + // restore initial cache_info | |
| 1221 | + $this->_cache_info = array_pop($_cache_info); | |
| 1222 | + return true; | |
| 1223 | + } else { | |
| 1224 | + error_reporting($_smarty_old_error_level); | |
| 1225 | + // restore initial cache_info | |
| 1226 | + $this->_cache_info = array_pop($_cache_info); | |
| 1227 | + return $_smarty_results; | |
| 1228 | + } | |
| 1229 | + } else { | |
| 1230 | + $this->_cache_info['template'][$resource_name] = true; | |
| 1231 | + if ($this->cache_modified_check && $display) { | |
| 1232 | + header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); | |
| 1233 | + } | |
| 1234 | + } | |
| 1235 | + } | |
| 1236 | + | |
| 1237 | + // load filters that are marked as autoload | |
| 1238 | + if (count($this->autoload_filters)) { | |
| 1239 | + foreach ($this->autoload_filters as $_filter_type => $_filters) { | |
| 1240 | + foreach ($_filters as $_filter) { | |
| 1241 | + $this->load_filter($_filter_type, $_filter); | |
| 1242 | + } | |
| 1243 | + } | |
| 1244 | + } | |
| 1245 | + | |
| 1246 | + $_smarty_compile_path = $this->_get_compile_path($resource_name); | |
| 1247 | + | |
| 1248 | + // if we just need to display the results, don't perform output | |
| 1249 | + // buffering - for speed | |
| 1250 | + $_cache_including = $this->_cache_including; | |
| 1251 | + $this->_cache_including = false; | |
| 1252 | + if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) { | |
| 1253 | + if ($this->_is_compiled($resource_name, $_smarty_compile_path) | |
| 1254 | + || $this->_compile_resource($resource_name, $_smarty_compile_path)) | |
| 1255 | + { | |
| 1256 | + include($_smarty_compile_path); | |
| 1257 | + } | |
| 1258 | + } else { | |
| 1259 | + ob_start(); | |
| 1260 | + if ($this->_is_compiled($resource_name, $_smarty_compile_path) | |
| 1261 | + || $this->_compile_resource($resource_name, $_smarty_compile_path)) | |
| 1262 | + { | |
| 1263 | + include($_smarty_compile_path); | |
| 1264 | + } | |
| 1265 | + $_smarty_results = ob_get_contents(); | |
| 1266 | + ob_end_clean(); | |
| 1267 | + | |
| 1268 | + foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) { | |
| 1269 | + $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this)); | |
| 1270 | + } | |
| 1271 | + } | |
| 1272 | + | |
| 1273 | + if ($this->caching) { | |
| 1274 | + $_params = array('tpl_file' => $resource_name, | |
| 1275 | + 'cache_id' => $cache_id, | |
| 1276 | + 'compile_id' => $compile_id, | |
| 1277 | + 'results' => $_smarty_results); | |
| 1278 | + require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php'); | |
| 1279 | + smarty_core_write_cache_file($_params, $this); | |
| 1280 | + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); | |
| 1281 | + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); | |
| 1282 | + | |
| 1283 | + if ($this->_cache_serials) { | |
| 1284 | + // strip nocache-tags from output | |
| 1285 | + $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s' | |
| 1286 | + ,'' | |
| 1287 | + ,$_smarty_results); | |
| 1288 | + } | |
| 1289 | + // restore initial cache_info | |
| 1290 | + $this->_cache_info = array_pop($_cache_info); | |
| 1291 | + } | |
| 1292 | + $this->_cache_including = $_cache_including; | |
| 1293 | + | |
| 1294 | + if ($display) { | |
| 1295 | + if (isset($_smarty_results)) { echo $_smarty_results; } | |
| 1296 | + if ($this->debugging) { | |
| 1297 | + // capture time for debugging info | |
| 1298 | + $_params = array(); | |
| 1299 | + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); | |
| 1300 | + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); | |
| 1301 | + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); | |
| 1302 | + echo smarty_core_display_debug_console($_params, $this); | |
| 1303 | + } | |
| 1304 | + error_reporting($_smarty_old_error_level); | |
| 1305 | + return; | |
| 1306 | + } else { | |
| 1307 | + error_reporting($_smarty_old_error_level); | |
| 1308 | + if (isset($_smarty_results)) { return $_smarty_results; } | |
| 1309 | + } | |
| 1310 | + } | |
| 1311 | + | |
| 1312 | + /** | |
| 1313 | + * load configuration values | |
| 1314 | + * | |
| 1315 | + * @param string $file | |
| 1316 | + * @param string $section | |
| 1317 | + * @param string $scope | |
| 1318 | + */ | |
| 1319 | + function config_load($file, $section = null, $scope = 'global') | |
| 1320 | + { | |
| 1321 | + require_once($this->_get_plugin_filepath('function', 'config_load')); | |
| 1322 | + smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this); | |
| 1323 | + } | |
| 1324 | + | |
| 1325 | + /** | |
| 1326 | + * return a reference to a registered object | |
| 1327 | + * | |
| 1328 | + * @param string $name | |
| 1329 | + * @return object | |
| 1330 | + */ | |
| 1331 | + function &get_registered_object($name) { | |
| 1332 | + if (!isset($this->_reg_objects[$name])) | |
| 1333 | + $this->_trigger_fatal_error("'$name' is not a registered object"); | |
| 1334 | + | |
| 1335 | + if (!is_object($this->_reg_objects[$name][0])) | |
| 1336 | + $this->_trigger_fatal_error("registered '$name' is not an object"); | |
| 1337 | + | |
| 1338 | + return $this->_reg_objects[$name][0]; | |
| 1339 | + } | |
| 1340 | + | |
| 1341 | + /** | |
| 1342 | + * clear configuration values | |
| 1343 | + * | |
| 1344 | + * @param string $var | |
| 1345 | + */ | |
| 1346 | + function clear_config($var = null) | |
| 1347 | + { | |
| 1348 | + if(!isset($var)) { | |
| 1349 | + // clear all values | |
| 1350 | + $this->_config = array(array('vars' => array(), | |
| 1351 | + 'files' => array())); | |
| 1352 | + } else { | |
| 1353 | + unset($this->_config[0]['vars'][$var]); | |
| 1354 | + } | |
| 1355 | + } | |
| 1356 | + | |
| 1357 | + /** | |
| 1358 | + * get filepath of requested plugin | |
| 1359 | + * | |
| 1360 | + * @param string $type | |
| 1361 | + * @param string $name | |
| 1362 | + * @return string|false | |
| 1363 | + */ | |
| 1364 | + function _get_plugin_filepath($type, $name) | |
| 1365 | + { | |
| 1366 | + $_params = array('type' => $type, 'name' => $name); | |
| 1367 | + require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php'); | |
| 1368 | + return smarty_core_assemble_plugin_filepath($_params, $this); | |
| 1369 | + } | |
| 1370 | + | |
| 1371 | + /** | |
| 1372 | + * test if resource needs compiling | |
| 1373 | + * | |
| 1374 | + * @param string $resource_name | |
| 1375 | + * @param string $compile_path | |
| 1376 | + * @return boolean | |
| 1377 | + */ | |
| 1378 | + function _is_compiled($resource_name, $compile_path) | |
| 1379 | + { | |
| 1380 | + if (!$this->force_compile && file_exists($compile_path)) { | |
| 1381 | + if (!$this->compile_check) { | |
| 1382 | + // no need to check compiled file | |
| 1383 | + return true; | |
| 1384 | + } else { | |
| 1385 | + // get file source and timestamp | |
| 1386 | + $_params = array('resource_name' => $resource_name, 'get_source'=>false); | |
| 1387 | + if (!$this->_fetch_resource_info($_params)) { | |
| 1388 | + return false; | |
| 1389 | + } | |
| 1390 | + if ($_params['resource_timestamp'] <= filemtime($compile_path)) { | |
| 1391 | + // template not expired, no recompile | |
| 1392 | + return true; | |
| 1393 | + } else { | |
| 1394 | + // compile template | |
| 1395 | + return false; | |
| 1396 | + } | |
| 1397 | + } | |
| 1398 | + } else { | |
| 1399 | + // compiled template does not exist, or forced compile | |
| 1400 | + return false; | |
| 1401 | + } | |
| 1402 | + } | |
| 1403 | + | |
| 1404 | + /** | |
| 1405 | + * compile the template | |
| 1406 | + * | |
| 1407 | + * @param string $resource_name | |
| 1408 | + * @param string $compile_path | |
| 1409 | + * @return boolean | |
| 1410 | + */ | |
| 1411 | + function _compile_resource($resource_name, $compile_path) | |
| 1412 | + { | |
| 1413 | + | |
| 1414 | + $_params = array('resource_name' => $resource_name); | |
| 1415 | + if (!$this->_fetch_resource_info($_params)) { | |
| 1416 | + return false; | |
| 1417 | + } | |
| 1418 | + | |
| 1419 | + $_source_content = $_params['source_content']; | |
| 1420 | + $_cache_include = substr($compile_path, 0, -4).'.inc'; | |
| 1421 | + | |
| 1422 | + if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { | |
| 1423 | + // if a _cache_serial was set, we also have to write an include-file: | |
| 1424 | + if ($this->_cache_include_info) { | |
| 1425 | + require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php'); | |
| 1426 | + smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this); | |
| 1427 | + } | |
| 1428 | + | |
| 1429 | + $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content); | |
| 1430 | + require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); | |
| 1431 | + smarty_core_write_compiled_resource($_params, $this); | |
| 1432 | + | |
| 1433 | + return true; | |
| 1434 | + } else { | |
| 1435 | + return false; | |
| 1436 | + } | |
| 1437 | + | |
| 1438 | + } | |
| 1439 | + | |
| 1440 | + /** | |
| 1441 | + * compile the given source | |
| 1442 | + * | |
| 1443 | + * @param string $resource_name | |
| 1444 | + * @param string $source_content | |
| 1445 | + * @param string $compiled_content | |
| 1446 | + * @return boolean | |
| 1447 | + */ | |
| 1448 | + function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) | |
| 1449 | + { | |
| 1450 | + if (file_exists(SMARTY_DIR . $this->compiler_file)) { | |
| 1451 | + require_once(SMARTY_DIR . $this->compiler_file); | |
| 1452 | + } else { | |
| 1453 | + // use include_path | |
| 1454 | + require_once($this->compiler_file); | |
| 1455 | + } | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + $smarty_compiler = new $this->compiler_class; | |
| 1459 | + | |
| 1460 | + $smarty_compiler->template_dir = $this->template_dir; | |
| 1461 | + $smarty_compiler->compile_dir = $this->compile_dir; | |
| 1462 | + $smarty_compiler->plugins_dir = $this->plugins_dir; | |
| 1463 | + $smarty_compiler->config_dir = $this->config_dir; | |
| 1464 | + $smarty_compiler->force_compile = $this->force_compile; | |
| 1465 | + $smarty_compiler->caching = $this->caching; | |
| 1466 | + $smarty_compiler->php_handling = $this->php_handling; | |
| 1467 | + $smarty_compiler->left_delimiter = $this->left_delimiter; | |
| 1468 | + $smarty_compiler->right_delimiter = $this->right_delimiter; | |
| 1469 | + $smarty_compiler->_version = $this->_version; | |
| 1470 | + $smarty_compiler->security = $this->security; | |
| 1471 | + $smarty_compiler->secure_dir = $this->secure_dir; | |
| 1472 | + $smarty_compiler->security_settings = $this->security_settings; | |
| 1473 | + $smarty_compiler->trusted_dir = $this->trusted_dir; | |
| 1474 | + $smarty_compiler->use_sub_dirs = $this->use_sub_dirs; | |
| 1475 | + $smarty_compiler->_reg_objects = &$this->_reg_objects; | |
| 1476 | + $smarty_compiler->_plugins = &$this->_plugins; | |
| 1477 | + $smarty_compiler->_tpl_vars = &$this->_tpl_vars; | |
| 1478 | + $smarty_compiler->default_modifiers = $this->default_modifiers; | |
| 1479 | + $smarty_compiler->compile_id = $this->_compile_id; | |
| 1480 | + $smarty_compiler->_config = $this->_config; | |
| 1481 | + $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; | |
| 1482 | + | |
| 1483 | + if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) { | |
| 1484 | + $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path]; | |
| 1485 | + } | |
| 1486 | + $smarty_compiler->_cache_include = $cache_include_path; | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content); | |
| 1490 | + | |
| 1491 | + if ($smarty_compiler->_cache_serial) { | |
| 1492 | + $this->_cache_include_info = array( | |
| 1493 | + 'cache_serial'=>$smarty_compiler->_cache_serial | |
| 1494 | + ,'plugins_code'=>$smarty_compiler->_plugins_code | |
| 1495 | + ,'include_file_path' => $cache_include_path); | |
| 1496 | + | |
| 1497 | + } else { | |
| 1498 | + $this->_cache_include_info = null; | |
| 1499 | + | |
| 1500 | + } | |
| 1501 | + | |
| 1502 | + return $_results; | |
| 1503 | + } | |
| 1504 | + | |
| 1505 | + /** | |
| 1506 | + * Get the compile path for this resource | |
| 1507 | + * | |
| 1508 | + * @param string $resource_name | |
| 1509 | + * @return string results of {@link _get_auto_filename()} | |
| 1510 | + */ | |
| 1511 | + function _get_compile_path($resource_name) | |
| 1512 | + { | |
| 1513 | + return $this->_get_auto_filename($this->compile_dir, $resource_name, | |
| 1514 | + $this->_compile_id) . '.php'; | |
| 1515 | + } | |
| 1516 | + | |
| 1517 | + /** | |
| 1518 | + * fetch the template info. Gets timestamp, and source | |
| 1519 | + * if get_source is true | |
| 1520 | + * | |
| 1521 | + * sets $source_content to the source of the template, and | |
| 1522 | + * $resource_timestamp to its time stamp | |
| 1523 | + * @param string $resource_name | |
| 1524 | + * @param string $source_content | |
| 1525 | + * @param integer $resource_timestamp | |
| 1526 | + * @param boolean $get_source | |
| 1527 | + * @param boolean $quiet | |
| 1528 | + * @return boolean | |
| 1529 | + */ | |
| 1530 | + | |
| 1531 | + function _fetch_resource_info(&$params) | |
| 1532 | + { | |
| 1533 | + if(!isset($params['get_source'])) { $params['get_source'] = true; } | |
| 1534 | + if(!isset($params['quiet'])) { $params['quiet'] = false; } | |
| 1535 | + | |
| 1536 | + $_return = false; | |
| 1537 | + $_params = array('resource_name' => $params['resource_name']) ; | |
| 1538 | + if (isset($params['resource_base_path'])) | |
| 1539 | + $_params['resource_base_path'] = $params['resource_base_path']; | |
| 1540 | + else | |
| 1541 | + $_params['resource_base_path'] = $this->template_dir; | |
| 1542 | + | |
| 1543 | + if ($this->_parse_resource_name($_params)) { | |
| 1544 | + $_resource_type = $_params['resource_type']; | |
| 1545 | + $_resource_name = $_params['resource_name']; | |
| 1546 | + switch ($_resource_type) { | |
| 1547 | + case 'file': | |
| 1548 | + if ($params['get_source']) { | |
| 1549 | + $params['source_content'] = $this->_read_file($_resource_name); | |
| 1550 | + } | |
| 1551 | + $params['resource_timestamp'] = filemtime($_resource_name); | |
| 1552 | + $_return = is_file($_resource_name) && is_readable($_resource_name); | |
| 1553 | + break; | |
| 1554 | + | |
| 1555 | + default: | |
| 1556 | + // call resource functions to fetch the template source and timestamp | |
| 1557 | + if ($params['get_source']) { | |
| 1558 | + $_source_return = isset($this->_plugins['resource'][$_resource_type]) && | |
| 1559 | + call_user_func_array($this->_plugins['resource'][$_resource_type][0][0], | |
| 1560 | + array($_resource_name, &$params['source_content'], &$this)); | |
| 1561 | + } else { | |
| 1562 | + $_source_return = true; | |
| 1563 | + } | |
| 1564 | + | |
| 1565 | + $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) && | |
| 1566 | + call_user_func_array($this->_plugins['resource'][$_resource_type][0][1], | |
| 1567 | + array($_resource_name, &$params['resource_timestamp'], &$this)); | |
| 1568 | + | |
| 1569 | + $_return = $_source_return && $_timestamp_return; | |
| 1570 | + break; | |
| 1571 | + } | |
| 1572 | + } | |
| 1573 | + | |
| 1574 | + if (!$_return) { | |
| 1575 | + // see if we can get a template with the default template handler | |
| 1576 | + if (!empty($this->default_template_handler_func)) { | |
| 1577 | + if (!is_callable($this->default_template_handler_func)) { | |
| 1578 | + $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist."); | |
| 1579 | + } else { | |
| 1580 | + $_return = call_user_func_array( | |
| 1581 | + $this->default_template_handler_func, | |
| 1582 | + array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this)); | |
| 1583 | + } | |
| 1584 | + } | |
| 1585 | + } | |
| 1586 | + | |
| 1587 | + if (!$_return) { | |
| 1588 | + if (!$params['quiet']) { | |
| 1589 | + $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); | |
| 1590 | + } | |
| 1591 | + } else if ($_return && $this->security) { | |
| 1592 | + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); | |
| 1593 | + if (!smarty_core_is_secure($_params, $this)) { | |
| 1594 | + if (!$params['quiet']) | |
| 1595 | + $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); | |
| 1596 | + $params['source_content'] = null; | |
| 1597 | + $params['resource_timestamp'] = null; | |
| 1598 | + return false; | |
| 1599 | + } | |
| 1600 | + } | |
| 1601 | + return $_return; | |
| 1602 | + } | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + /** | |
| 1606 | + * parse out the type and name from the resource | |
| 1607 | + * | |
| 1608 | + * @param string $resource_base_path | |
| 1609 | + * @param string $resource_name | |
| 1610 | + * @param string $resource_type | |
| 1611 | + * @param string $resource_name | |
| 1612 | + * @return boolean | |
| 1613 | + */ | |
| 1614 | + | |
| 1615 | + function _parse_resource_name(&$params) | |
| 1616 | + { | |
| 1617 | + | |
| 1618 | + // split tpl_path by the first colon | |
| 1619 | + $_resource_name_parts = explode(':', $params['resource_name'], 2); | |
| 1620 | + | |
| 1621 | + if (count($_resource_name_parts) == 1) { | |
| 1622 | + // no resource type given | |
| 1623 | + $params['resource_type'] = $this->default_resource_type; | |
| 1624 | + $params['resource_name'] = $_resource_name_parts[0]; | |
| 1625 | + } else { | |
| 1626 | + if(strlen($_resource_name_parts[0]) == 1) { | |
| 1627 | + // 1 char is not resource type, but part of filepath | |
| 1628 | + $params['resource_type'] = $this->default_resource_type; | |
| 1629 | + $params['resource_name'] = $params['resource_name']; | |
| 1630 | + } else { | |
| 1631 | + $params['resource_type'] = $_resource_name_parts[0]; | |
| 1632 | + $params['resource_name'] = $_resource_name_parts[1]; | |
| 1633 | + } | |
| 1634 | + } | |
| 1635 | + | |
| 1636 | + if ($params['resource_type'] == 'file') { | |
| 1637 | + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) { | |
| 1638 | + // relative pathname to $params['resource_base_path'] | |
| 1639 | + // use the first directory where the file is found | |
| 1640 | + foreach ((array)$params['resource_base_path'] as $_curr_path) { | |
| 1641 | + $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; | |
| 1642 | + if (file_exists($_fullpath) && is_file($_fullpath)) { | |
| 1643 | + $params['resource_name'] = $_fullpath; | |
| 1644 | + return true; | |
| 1645 | + } | |
| 1646 | + // didn't find the file, try include_path | |
| 1647 | + $_params = array('file_path' => $_fullpath); | |
| 1648 | + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); | |
| 1649 | + if(smarty_core_get_include_path($_params, $this)) { | |
| 1650 | + $params['resource_name'] = $_params['new_file_path']; | |
| 1651 | + return true; | |
| 1652 | + } | |
| 1653 | + } | |
| 1654 | + return false; | |
| 1655 | + } else { | |
| 1656 | + /* absolute path */ | |
| 1657 | + return file_exists($params['resource_name']); | |
| 1658 | + } | |
| 1659 | + } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { | |
| 1660 | + $_params = array('type' => $params['resource_type']); | |
| 1661 | + require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php'); | |
| 1662 | + smarty_core_load_resource_plugin($_params, $this); | |
| 1663 | + } | |
| 1664 | + | |
| 1665 | + return true; | |
| 1666 | + } | |
| 1667 | + | |
| 1668 | + | |
| 1669 | + /** | |
| 1670 | + * Handle modifiers | |
| 1671 | + * | |
| 1672 | + * @param string|null $modifier_name | |
| 1673 | + * @param array|null $map_array | |
| 1674 | + * @return string result of modifiers | |
| 1675 | + */ | |
| 1676 | + function _run_mod_handler() | |
| 1677 | + { | |
| 1678 | + $_args = func_get_args(); | |
| 1679 | + list($_modifier_name, $_map_array) = array_splice($_args, 0, 2); | |
| 1680 | + list($_func_name, $_tpl_file, $_tpl_line) = | |
| 1681 | + $this->_plugins['modifier'][$_modifier_name]; | |
| 1682 | + | |
| 1683 | + $_var = $_args[0]; | |
| 1684 | + foreach ($_var as $_key => $_val) { | |
| 1685 | + $_args[0] = $_val; | |
| 1686 | + $_var[$_key] = call_user_func_array($_func_name, $_args); | |
| 1687 | + } | |
| 1688 | + return $_var; | |
| 1689 | + } | |
| 1690 | + | |
| 1691 | + /** | |
| 1692 | + * Remove starting and ending quotes from the string | |
| 1693 | + * | |
| 1694 | + * @param string $string | |
| 1695 | + * @return string | |
| 1696 | + */ | |
| 1697 | + function _dequote($string) | |
| 1698 | + { | |
| 1699 | + if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') && | |
| 1700 | + substr($string, -1) == substr($string, 0, 1)) | |
| 1701 | + return substr($string, 1, -1); | |
| 1702 | + else | |
| 1703 | + return $string; | |
| 1704 | + } | |
| 1705 | + | |
| 1706 | + | |
| 1707 | + /** | |
| 1708 | + * read in a file | |
| 1709 | + * | |
| 1710 | + * @param string $filename | |
| 1711 | + * @return string | |
| 1712 | + */ | |
| 1713 | + function _read_file($filename) | |
| 1714 | + { | |
| 1715 | + if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) { | |
| 1716 | + $contents = ''; | |
| 1717 | + while (!feof($fd)) { | |
| 1718 | + $contents .= fread($fd, 8192); | |
| 1719 | + } | |
| 1720 | + fclose($fd); | |
| 1721 | + return $contents; | |
| 1722 | + } else { | |
| 1723 | + return false; | |
| 1724 | + } | |
| 1725 | + } | |
| 1726 | + | |
| 1727 | + /** | |
| 1728 | + * get a concrete filename for automagically created content | |
| 1729 | + * | |
| 1730 | + * @param string $auto_base | |
| 1731 | + * @param string $auto_source | |
| 1732 | + * @param string $auto_id | |
| 1733 | + * @return string | |
| 1734 | + * @staticvar string|null | |
| 1735 | + * @staticvar string|null | |
| 1736 | + */ | |
| 1737 | + function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) | |
| 1738 | + { | |
| 1739 | + $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; | |
| 1740 | + $_return = $auto_base . DIRECTORY_SEPARATOR; | |
| 1741 | + | |
| 1742 | + if(isset($auto_id)) { | |
| 1743 | + // make auto_id safe for directory names | |
| 1744 | + $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id))); | |
| 1745 | + // split into separate directories | |
| 1746 | + $_return .= $auto_id . $_compile_dir_sep; | |
| 1747 | + } | |
| 1748 | + | |
| 1749 | + if(isset($auto_source)) { | |
| 1750 | + // make source name safe for filename | |
| 1751 | + $_filename = urlencode(basename($auto_source)); | |
| 1752 | + $_crc32 = sprintf('%08X', crc32($auto_source)); | |
| 1753 | + // prepend %% to avoid name conflicts with | |
| 1754 | + // with $params['auto_id'] names | |
| 1755 | + $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep . | |
| 1756 | + substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32; | |
| 1757 | + $_return .= '%%' . $_crc32 . '%%' . $_filename; | |
| 1758 | + } | |
| 1759 | + | |
| 1760 | + return $_return; | |
| 1761 | + } | |
| 1762 | + | |
| 1763 | + /** | |
| 1764 | + * unlink a file, possibly using expiration time | |
| 1765 | + * | |
| 1766 | + * @param string $resource | |
| 1767 | + * @param integer $exp_time | |
| 1768 | + */ | |
| 1769 | + function _unlink($resource, $exp_time = null) | |
| 1770 | + { | |
| 1771 | + if(isset($exp_time)) { | |
| 1772 | + if(time() - @filemtime($resource) >= $exp_time) { | |
| 1773 | + return @unlink($resource); | |
| 1774 | + } | |
| 1775 | + } else { | |
| 1776 | + return @unlink($resource); | |
| 1777 | + } | |
| 1778 | + } | |
| 1779 | + | |
| 1780 | + /** | |
| 1781 | + * returns an auto_id for auto-file-functions | |
| 1782 | + * | |
| 1783 | + * @param string $cache_id | |
| 1784 | + * @param string $compile_id | |
| 1785 | + * @return string|null | |
| 1786 | + */ | |
| 1787 | + function _get_auto_id($cache_id=null, $compile_id=null) { | |
| 1788 | + if (isset($cache_id)) | |
| 1789 | + return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id; | |
| 1790 | + elseif(isset($compile_id)) | |
| 1791 | + return $compile_id; | |
| 1792 | + else | |
| 1793 | + return null; | |
| 1794 | + } | |
| 1795 | + | |
| 1796 | + /** | |
| 1797 | + * trigger Smarty plugin error | |
| 1798 | + * | |
| 1799 | + * @param string $error_msg | |
| 1800 | + * @param string $tpl_file | |
| 1801 | + * @param integer $tpl_line | |
| 1802 | + * @param string $file | |
| 1803 | + * @param integer $line | |
| 1804 | + * @param integer $error_type | |
| 1805 | + */ | |
| 1806 | + function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null, | |
| 1807 | + $file = null, $line = null, $error_type = E_USER_ERROR) | |
| 1808 | + { | |
| 1809 | + if(isset($file) && isset($line)) { | |
| 1810 | + $info = ' ('.basename($file).", line $line)"; | |
| 1811 | + } else { | |
| 1812 | + $info = ''; | |
| 1813 | + } | |
| 1814 | + if (isset($tpl_line) && isset($tpl_file)) { | |
| 1815 | + $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type); | |
| 1816 | + } else { | |
| 1817 | + $this->trigger_error($error_msg . $info, $error_type); | |
| 1818 | + } | |
| 1819 | + } | |
| 1820 | + | |
| 1821 | + | |
| 1822 | + /** | |
| 1823 | + * callback function for preg_replace, to call a non-cacheable block | |
| 1824 | + * @return string | |
| 1825 | + */ | |
| 1826 | + function _process_compiled_include_callback($match) { | |
| 1827 | + $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3]; | |
| 1828 | + ob_start(); | |
| 1829 | + $_func($this); | |
| 1830 | + $_ret = ob_get_contents(); | |
| 1831 | + ob_end_clean(); | |
| 1832 | + return $_ret; | |
| 1833 | + } | |
| 1834 | + | |
| 1835 | + | |
| 1836 | + /** | |
| 1837 | + * called for included templates | |
| 1838 | + * | |
| 1839 | + * @param string $_smarty_include_tpl_file | |
| 1840 | + * @param string $_smarty_include_vars | |
| 1841 | + */ | |
| 1842 | + | |
| 1843 | + // $_smarty_include_tpl_file, $_smarty_include_vars | |
| 1844 | + | |
| 1845 | + function _smarty_include($params) | |
| 1846 | + { | |
| 1847 | + if ($this->debugging) { | |
| 1848 | + $_params = array(); | |
| 1849 | + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); | |
| 1850 | + $debug_start_time = smarty_core_get_microtime($_params, $this); | |
| 1851 | + $this->_smarty_debug_info[] = array('type' => 'template', | |
| 1852 | + 'filename' => $params['smarty_include_tpl_file'], | |
| 1853 | + 'depth' => ++$this->_inclusion_depth); | |
| 1854 | + $included_tpls_idx = count($this->_smarty_debug_info) - 1; | |
| 1855 | + } | |
| 1856 | + | |
| 1857 | + $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']); | |
| 1858 | + | |
| 1859 | + // config vars are treated as local, so push a copy of the | |
| 1860 | + // current ones onto the front of the stack | |
| 1861 | + array_unshift($this->_config, $this->_config[0]); | |
| 1862 | + | |
| 1863 | + $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']); | |
| 1864 | + | |
| 1865 | + | |
| 1866 | + if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path) | |
| 1867 | + || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path)) | |
| 1868 | + { | |
| 1869 | + include($_smarty_compile_path); | |
| 1870 | + } | |
| 1871 | + | |
| 1872 | + // pop the local vars off the front of the stack | |
| 1873 | + array_shift($this->_config); | |
| 1874 | + | |
| 1875 | + $this->_inclusion_depth--; | |
| 1876 | + | |
| 1877 | + if ($this->debugging) { | |
| 1878 | + // capture time for debugging info | |
| 1879 | + $_params = array(); | |
| 1880 | + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); | |
| 1881 | + $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; | |
| 1882 | + } | |
| 1883 | + | |
| 1884 | + if ($this->caching) { | |
| 1885 | + $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true; | |
| 1886 | + } | |
| 1887 | + } | |
| 1888 | + | |
| 1889 | + | |
| 1890 | + /** | |
| 1891 | + * get or set an array of cached attributes for function that is | |
| 1892 | + * not cacheable | |
| 1893 | + * @return array | |
| 1894 | + */ | |
| 1895 | + function &_smarty_cache_attrs($cache_serial, $count) { | |
| 1896 | + $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count]; | |
| 1897 | + | |
| 1898 | + if ($this->_cache_including) { | |
| 1899 | + /* return next set of cache_attrs */ | |
| 1900 | + $_return = current($_cache_attrs); | |
| 1901 | + next($_cache_attrs); | |
| 1902 | + return $_return; | |
| 1903 | + | |
| 1904 | + } else { | |
| 1905 | + /* add a reference to a new set of cache_attrs */ | |
| 1906 | + $_cache_attrs[] = array(); | |
| 1907 | + return $_cache_attrs[count($_cache_attrs)-1]; | |
| 1908 | + | |
| 1909 | + } | |
| 1910 | + | |
| 1911 | + } | |
| 1912 | + | |
| 1913 | + | |
| 1914 | + /** | |
| 1915 | + * wrapper for include() retaining $this | |
| 1916 | + * @return mixed | |
| 1917 | + */ | |
| 1918 | + function _include($filename, $once=false, $params=null) | |
| 1919 | + { | |
| 1920 | + if ($once) { | |
| 1921 | + return include_once($filename); | |
| 1922 | + } else { | |
| 1923 | + return include($filename); | |
| 1924 | + } | |
| 1925 | + } | |
| 1926 | + | |
| 1927 | + | |
| 1928 | + /** | |
| 1929 | + * wrapper for eval() retaining $this | |
| 1930 | + * @return mixed | |
| 1931 | + */ | |
| 1932 | + function _eval($code, $params=null) | |
| 1933 | + { | |
| 1934 | + return eval($code); | |
| 1935 | + } | |
| 1936 | + | |
| 1937 | + /** | |
| 1938 | + * Extracts the filter name from the given callback | |
| 1939 | + * | |
| 1940 | + * @param callback $function | |
| 1941 | + * @return string | |
| 1942 | + */ | |
| 1943 | + function _get_filter_name($function) | |
| 1944 | + { | |
| 1945 | + if (is_array($function)) { | |
| 1946 | + $_class_name = (is_object($function[0]) ? | |
| 1947 | + get_class($function[0]) : $function[0]); | |
| 1948 | + return $_class_name . '_' . $function[1]; | |
| 1949 | + } | |
| 1950 | + else { | |
| 1951 | + return $function; | |
| 1952 | + } | |
| 1953 | + } | |
| 1954 | + | |
| 1955 | + /**#@-*/ | |
| 1956 | + | |
| 1957 | +} | |
| 1958 | + | |
| 1959 | +/* vim: set expandtab: */ | |
| 1960 | + | |
| 1961 | +?> | ... | ... |
Smarty/Smarty_Compiler.class.php
0 → 100644
| 1 | +<?PHP | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Project: Smarty: the PHP compiling template engine | |
| 5 | + * File: Smarty_Compiler.class.php | |
| 6 | + * | |
| 7 | + * This library is free software; you can redistribute it and/or | |
| 8 | + * modify it under the terms of the GNU Lesser General Public | |
| 9 | + * License as published by the Free Software Foundation; either | |
| 10 | + * version 2.1 of the License, or (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This library is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | + * Lesser General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU Lesser General Public | |
| 18 | + * License along with this library; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 20 | + * | |
| 21 | + * @link http://smarty.php.net/ | |
| 22 | + * @author Monte Ohrt <monte at ohrt dot com> | |
| 23 | + * @author Andrei Zmievski <andrei@php.net> | |
| 24 | + * @version 2.6.26 | |
| 25 | + * @copyright 2001-2005 New Digital Group, Inc. | |
| 26 | + * @package Smarty | |
| 27 | + */ | |
| 28 | + | |
| 29 | +/* $Id: Smarty_Compiler.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */ | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * Template compiling class | |
| 33 | + * @package Smarty | |
| 34 | + */ | |
| 35 | +class Smarty_Compiler extends Smarty { | |
| 36 | + | |
| 37 | + // internal vars | |
| 38 | + /**#@+ | |
| 39 | + * @access private | |
| 40 | + */ | |
| 41 | + var $_folded_blocks = array(); // keeps folded template blocks | |
| 42 | + var $_current_file = null; // the current template being compiled | |
| 43 | + var $_current_line_no = 1; // line number for error messages | |
| 44 | + var $_capture_stack = array(); // keeps track of nested capture buffers | |
| 45 | + var $_plugin_info = array(); // keeps track of plugins to load | |
| 46 | + var $_init_smarty_vars = false; | |
| 47 | + var $_permitted_tokens = array('true','false','yes','no','on','off','null'); | |
| 48 | + var $_db_qstr_regexp = null; // regexps are setup in the constructor | |
| 49 | + var $_si_qstr_regexp = null; | |
| 50 | + var $_qstr_regexp = null; | |
| 51 | + var $_func_regexp = null; | |
| 52 | + var $_reg_obj_regexp = null; | |
| 53 | + var $_var_bracket_regexp = null; | |
| 54 | + var $_num_const_regexp = null; | |
| 55 | + var $_dvar_guts_regexp = null; | |
| 56 | + var $_dvar_regexp = null; | |
| 57 | + var $_cvar_regexp = null; | |
| 58 | + var $_svar_regexp = null; | |
| 59 | + var $_avar_regexp = null; | |
| 60 | + var $_mod_regexp = null; | |
| 61 | + var $_var_regexp = null; | |
| 62 | + var $_parenth_param_regexp = null; | |
| 63 | + var $_func_call_regexp = null; | |
| 64 | + var $_obj_ext_regexp = null; | |
| 65 | + var $_obj_start_regexp = null; | |
| 66 | + var $_obj_params_regexp = null; | |
| 67 | + var $_obj_call_regexp = null; | |
| 68 | + var $_cacheable_state = 0; | |
| 69 | + var $_cache_attrs_count = 0; | |
| 70 | + var $_nocache_count = 0; | |
| 71 | + var $_cache_serial = null; | |
| 72 | + var $_cache_include = null; | |
| 73 | + | |
| 74 | + var $_strip_depth = 0; | |
| 75 | + var $_additional_newline = "\n"; | |
| 76 | + | |
| 77 | + /**#@-*/ | |
| 78 | + /** | |
| 79 | + * The class constructor. | |
| 80 | + */ | |
| 81 | + function Smarty_Compiler() | |
| 82 | + { | |
| 83 | + // matches double quoted strings: | |
| 84 | + // "foobar" | |
| 85 | + // "foo\"bar" | |
| 86 | + $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"'; | |
| 87 | + | |
| 88 | + // matches single quoted strings: | |
| 89 | + // 'foobar' | |
| 90 | + // 'foo\'bar' | |
| 91 | + $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; | |
| 92 | + | |
| 93 | + // matches single or double quoted strings | |
| 94 | + $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')'; | |
| 95 | + | |
| 96 | + // matches bracket portion of vars | |
| 97 | + // [0] | |
| 98 | + // [foo] | |
| 99 | + // [$bar] | |
| 100 | + $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; | |
| 101 | + | |
| 102 | + // matches numerical constants | |
| 103 | + // 30 | |
| 104 | + // -12 | |
| 105 | + // 13.22 | |
| 106 | + $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; | |
| 107 | + | |
| 108 | + // matches $ vars (not objects): | |
| 109 | + // $foo | |
| 110 | + // $foo.bar | |
| 111 | + // $foo.bar.foobar | |
| 112 | + // $foo[0] | |
| 113 | + // $foo[$bar] | |
| 114 | + // $foo[5][blah] | |
| 115 | + // $foo[5].bar[$foobar][4] | |
| 116 | + $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; | |
| 117 | + $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; | |
| 118 | + $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp | |
| 119 | + . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; | |
| 120 | + $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; | |
| 121 | + | |
| 122 | + // matches config vars: | |
| 123 | + // #foo# | |
| 124 | + // #foobar123_foo# | |
| 125 | + $this->_cvar_regexp = '\#\w+\#'; | |
| 126 | + | |
| 127 | + // matches section vars: | |
| 128 | + // %foo.bar% | |
| 129 | + $this->_svar_regexp = '\%\w+\.\w+\%'; | |
| 130 | + | |
| 131 | + // matches all valid variables (no quotes, no modifiers) | |
| 132 | + $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|' | |
| 133 | + . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')'; | |
| 134 | + | |
| 135 | + // matches valid variable syntax: | |
| 136 | + // $foo | |
| 137 | + // $foo | |
| 138 | + // #foo# | |
| 139 | + // #foo# | |
| 140 | + // "text" | |
| 141 | + // "text" | |
| 142 | + $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; | |
| 143 | + | |
| 144 | + // matches valid object call (one level of object nesting allowed in parameters): | |
| 145 | + // $foo->bar | |
| 146 | + // $foo->bar() | |
| 147 | + // $foo->bar("text") | |
| 148 | + // $foo->bar($foo, $bar, "text") | |
| 149 | + // $foo->bar($foo, "foo") | |
| 150 | + // $foo->bar->foo() | |
| 151 | + // $foo->bar->foo->bar() | |
| 152 | + // $foo->bar($foo->bar) | |
| 153 | + // $foo->bar($foo->bar()) | |
| 154 | + // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) | |
| 155 | + $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; | |
| 156 | + $this->_obj_restricted_param_regexp = '(?:' | |
| 157 | + . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' | |
| 158 | + . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; | |
| 159 | + $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' | |
| 160 | + . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; | |
| 161 | + $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp | |
| 162 | + . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; | |
| 163 | + $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; | |
| 164 | + $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; | |
| 165 | + | |
| 166 | + // matches valid modifier syntax: | |
| 167 | + // |foo | |
| 168 | + // |@foo | |
| 169 | + // |foo:"bar" | |
| 170 | + // |foo:$bar | |
| 171 | + // |foo:"bar":$foobar | |
| 172 | + // |foo|bar | |
| 173 | + // |foo:$foo->bar | |
| 174 | + $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' | |
| 175 | + . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; | |
| 176 | + | |
| 177 | + // matches valid function name: | |
| 178 | + // foo123 | |
| 179 | + // _foo_bar | |
| 180 | + $this->_func_regexp = '[a-zA-Z_]\w*'; | |
| 181 | + | |
| 182 | + // matches valid registered object: | |
| 183 | + // foo->bar | |
| 184 | + $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*'; | |
| 185 | + | |
| 186 | + // matches valid parameter values: | |
| 187 | + // true | |
| 188 | + // $foo | |
| 189 | + // $foo|bar | |
| 190 | + // #foo# | |
| 191 | + // #foo#|bar | |
| 192 | + // "text" | |
| 193 | + // "text"|bar | |
| 194 | + // $foo->bar | |
| 195 | + $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' | |
| 196 | + . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; | |
| 197 | + | |
| 198 | + // matches valid parenthesised function parameters: | |
| 199 | + // | |
| 200 | + // "text" | |
| 201 | + // $foo, $bar, "text" | |
| 202 | + // $foo|bar, "foo"|bar, $foo->bar($foo)|bar | |
| 203 | + $this->_parenth_param_regexp = '(?:\((?:\w+|' | |
| 204 | + . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|' | |
| 205 | + . $this->_param_regexp . ')))*)?\))'; | |
| 206 | + | |
| 207 | + // matches valid function call: | |
| 208 | + // foo() | |
| 209 | + // foo_bar($foo) | |
| 210 | + // _foo_bar($foo,"bar") | |
| 211 | + // foo123($foo,$foo->bar(),"foo") | |
| 212 | + $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:' | |
| 213 | + . $this->_parenth_param_regexp . '))'; | |
| 214 | + } | |
| 215 | + | |
| 216 | + /** | |
| 217 | + * compile a resource | |
| 218 | + * | |
| 219 | + * sets $compiled_content to the compiled source | |
| 220 | + * @param string $resource_name | |
| 221 | + * @param string $source_content | |
| 222 | + * @param string $compiled_content | |
| 223 | + * @return true | |
| 224 | + */ | |
| 225 | + function _compile_file($resource_name, $source_content, &$compiled_content) | |
| 226 | + { | |
| 227 | + | |
| 228 | + if ($this->security) { | |
| 229 | + // do not allow php syntax to be executed unless specified | |
| 230 | + if ($this->php_handling == SMARTY_PHP_ALLOW && | |
| 231 | + !$this->security_settings['PHP_HANDLING']) { | |
| 232 | + $this->php_handling = SMARTY_PHP_PASSTHRU; | |
| 233 | + } | |
| 234 | + } | |
| 235 | + | |
| 236 | + $this->_load_filters(); | |
| 237 | + | |
| 238 | + $this->_current_file = $resource_name; | |
| 239 | + $this->_current_line_no = 1; | |
| 240 | + $ldq = preg_quote($this->left_delimiter, '~'); | |
| 241 | + $rdq = preg_quote($this->right_delimiter, '~'); | |
| 242 | + | |
| 243 | + // run template source through prefilter functions | |
| 244 | + if (count($this->_plugins['prefilter']) > 0) { | |
| 245 | + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { | |
| 246 | + if ($prefilter === false) continue; | |
| 247 | + if ($prefilter[3] || is_callable($prefilter[0])) { | |
| 248 | + $source_content = call_user_func_array($prefilter[0], | |
| 249 | + array($source_content, &$this)); | |
| 250 | + $this->_plugins['prefilter'][$filter_name][3] = true; | |
| 251 | + } else { | |
| 252 | + $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented"); | |
| 253 | + } | |
| 254 | + } | |
| 255 | + } | |
| 256 | + | |
| 257 | + /* fetch all special blocks */ | |
| 258 | + $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; | |
| 259 | + | |
| 260 | + preg_match_all($search, $source_content, $match, PREG_SET_ORDER); | |
| 261 | + $this->_folded_blocks = $match; | |
| 262 | + reset($this->_folded_blocks); | |
| 263 | + | |
| 264 | + /* replace special blocks by "{php}" */ | |
| 265 | + $source_content = preg_replace($search.'e', "'" | |
| 266 | + . $this->_quote_replace($this->left_delimiter) . 'php' | |
| 267 | + . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" | |
| 268 | + . $this->_quote_replace($this->right_delimiter) | |
| 269 | + . "'" | |
| 270 | + , $source_content); | |
| 271 | + | |
| 272 | + /* Gather all template tags. */ | |
| 273 | + preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); | |
| 274 | + $template_tags = $_match[1]; | |
| 275 | + /* Split content by template tags to obtain non-template content. */ | |
| 276 | + $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); | |
| 277 | + | |
| 278 | + /* loop through text blocks */ | |
| 279 | + for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { | |
| 280 | + /* match anything resembling php tags */ | |
| 281 | + if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { | |
| 282 | + /* replace tags with placeholders to prevent recursive replacements */ | |
| 283 | + $sp_match[1] = array_unique($sp_match[1]); | |
| 284 | + usort($sp_match[1], '_smarty_sort_length'); | |
| 285 | + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { | |
| 286 | + $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]); | |
| 287 | + } | |
| 288 | + /* process each one */ | |
| 289 | + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { | |
| 290 | + if ($this->php_handling == SMARTY_PHP_PASSTHRU) { | |
| 291 | + /* echo php contents */ | |
| 292 | + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?PHP echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]); | |
| 293 | + } else if ($this->php_handling == SMARTY_PHP_QUOTE) { | |
| 294 | + /* quote php tags */ | |
| 295 | + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]); | |
| 296 | + } else if ($this->php_handling == SMARTY_PHP_REMOVE) { | |
| 297 | + /* remove php tags */ | |
| 298 | + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); | |
| 299 | + } else { | |
| 300 | + /* SMARTY_PHP_ALLOW, but echo non php starting tags */ | |
| 301 | + $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?PHP echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]); | |
| 302 | + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); | |
| 303 | + } | |
| 304 | + } | |
| 305 | + } | |
| 306 | + } | |
| 307 | + | |
| 308 | + /* Compile the template tags into PHP code. */ | |
| 309 | + $compiled_tags = array(); | |
| 310 | + for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { | |
| 311 | + $this->_current_line_no += substr_count($text_blocks[$i], "\n"); | |
| 312 | + $compiled_tags[] = $this->_compile_tag($template_tags[$i]); | |
| 313 | + $this->_current_line_no += substr_count($template_tags[$i], "\n"); | |
| 314 | + } | |
| 315 | + if (count($this->_tag_stack)>0) { | |
| 316 | + list($_open_tag, $_line_no) = end($this->_tag_stack); | |
| 317 | + $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); | |
| 318 | + return; | |
| 319 | + } | |
| 320 | + | |
| 321 | + /* Reformat $text_blocks between 'strip' and '/strip' tags, | |
| 322 | + removing spaces, tabs and newlines. */ | |
| 323 | + $strip = false; | |
| 324 | + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { | |
| 325 | + if ($compiled_tags[$i] == '{strip}') { | |
| 326 | + $compiled_tags[$i] = ''; | |
| 327 | + $strip = true; | |
| 328 | + /* remove leading whitespaces */ | |
| 329 | + $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]); | |
| 330 | + } | |
| 331 | + if ($strip) { | |
| 332 | + /* strip all $text_blocks before the next '/strip' */ | |
| 333 | + for ($j = $i + 1; $j < $for_max; $j++) { | |
| 334 | + /* remove leading and trailing whitespaces of each line */ | |
| 335 | + $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); | |
| 336 | + if ($compiled_tags[$j] == '{/strip}') { | |
| 337 | + /* remove trailing whitespaces from the last text_block */ | |
| 338 | + $text_blocks[$j] = rtrim($text_blocks[$j]); | |
| 339 | + } | |
| 340 | + $text_blocks[$j] = "<?PHP echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>"; | |
| 341 | + if ($compiled_tags[$j] == '{/strip}') { | |
| 342 | + $compiled_tags[$j] = "\n"; /* slurped by php, but necessary | |
| 343 | + if a newline is following the closing strip-tag */ | |
| 344 | + $strip = false; | |
| 345 | + $i = $j; | |
| 346 | + break; | |
| 347 | + } | |
| 348 | + } | |
| 349 | + } | |
| 350 | + } | |
| 351 | + $compiled_content = ''; | |
| 352 | + | |
| 353 | + $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%'; | |
| 354 | + | |
| 355 | + /* Interleave the compiled contents and text blocks to get the final result. */ | |
| 356 | + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { | |
| 357 | + if ($compiled_tags[$i] == '') { | |
| 358 | + // tag result empty, remove first newline from following text block | |
| 359 | + $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]); | |
| 360 | + } | |
| 361 | + // replace legit PHP tags with placeholder | |
| 362 | + $text_blocks[$i] = str_replace('<?PHP ', $tag_guard, $text_blocks[$i]); | |
| 363 | + $compiled_tags[$i] = str_replace('<?PHP ', $tag_guard, $compiled_tags[$i]); | |
| 364 | + | |
| 365 | + $compiled_content .= $text_blocks[$i] . $compiled_tags[$i]; | |
| 366 | + } | |
| 367 | + $compiled_content .= str_replace('<?PHP ', $tag_guard, $text_blocks[$i]); | |
| 368 | + | |
| 369 | + // escape php tags created by interleaving | |
| 370 | + $compiled_content = str_replace('<?PHP ', "<?PHP echo '<?PHP ' ?>\n", $compiled_content); | |
| 371 | + $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?PHP echo 'language=php' ?>\n", $compiled_content); | |
| 372 | + | |
| 373 | + // recover legit tags | |
| 374 | + $compiled_content = str_replace($tag_guard, '<?PHP ', $compiled_content); | |
| 375 | + | |
| 376 | + // remove \n from the end of the file, if any | |
| 377 | + if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) { | |
| 378 | + $compiled_content = substr($compiled_content, 0, -1); | |
| 379 | + } | |
| 380 | + | |
| 381 | + if (!empty($this->_cache_serial)) { | |
| 382 | + $compiled_content = "<?PHP \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content; | |
| 383 | + } | |
| 384 | + | |
| 385 | + // run compiled template through postfilter functions | |
| 386 | + if (count($this->_plugins['postfilter']) > 0) { | |
| 387 | + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { | |
| 388 | + if ($postfilter === false) continue; | |
| 389 | + if ($postfilter[3] || is_callable($postfilter[0])) { | |
| 390 | + $compiled_content = call_user_func_array($postfilter[0], | |
| 391 | + array($compiled_content, &$this)); | |
| 392 | + $this->_plugins['postfilter'][$filter_name][3] = true; | |
| 393 | + } else { | |
| 394 | + $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented"); | |
| 395 | + } | |
| 396 | + } | |
| 397 | + } | |
| 398 | + | |
| 399 | + // put header at the top of the compiled template | |
| 400 | + $template_header = "<?PHP /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; | |
| 401 | + $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n"; | |
| 402 | + | |
| 403 | + /* Emit code to load needed plugins. */ | |
| 404 | + $this->_plugins_code = ''; | |
| 405 | + if (count($this->_plugin_info)) { | |
| 406 | + $_plugins_params = "array('plugins' => array("; | |
| 407 | + foreach ($this->_plugin_info as $plugin_type => $plugins) { | |
| 408 | + foreach ($plugins as $plugin_name => $plugin_info) { | |
| 409 | + $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], "; | |
| 410 | + $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),'; | |
| 411 | + } | |
| 412 | + } | |
| 413 | + $_plugins_params .= '))'; | |
| 414 | + $plugins_code = "<?PHP require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n"; | |
| 415 | + $template_header .= $plugins_code; | |
| 416 | + $this->_plugin_info = array(); | |
| 417 | + $this->_plugins_code = $plugins_code; | |
| 418 | + } | |
| 419 | + | |
| 420 | + if ($this->_init_smarty_vars) { | |
| 421 | + $template_header .= "<?PHP require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n"; | |
| 422 | + $this->_init_smarty_vars = false; | |
| 423 | + } | |
| 424 | + | |
| 425 | + $compiled_content = $template_header . $compiled_content; | |
| 426 | + return true; | |
| 427 | + } | |
| 428 | + | |
| 429 | + /** | |
| 430 | + * Compile a template tag | |
| 431 | + * | |
| 432 | + * @param string $template_tag | |
| 433 | + * @return string | |
| 434 | + */ | |
| 435 | + function _compile_tag($template_tag) | |
| 436 | + { | |
| 437 | + /* Matched comment. */ | |
| 438 | + if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*') | |
| 439 | + return ''; | |
| 440 | + | |
| 441 | + /* Split tag into two three parts: command, command modifiers and the arguments. */ | |
| 442 | + if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp | |
| 443 | + . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) | |
| 444 | + (?:\s+(.*))?$ | |
| 445 | + ~xs', $template_tag, $match)) { | |
| 446 | + $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); | |
| 447 | + } | |
| 448 | + | |
| 449 | + $tag_command = $match[1]; | |
| 450 | + $tag_modifier = isset($match[2]) ? $match[2] : null; | |
| 451 | + $tag_args = isset($match[3]) ? $match[3] : null; | |
| 452 | + | |
| 453 | + if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) { | |
| 454 | + /* tag name is a variable or object */ | |
| 455 | + $_return = $this->_parse_var_props($tag_command . $tag_modifier); | |
| 456 | + return "<?PHP echo $_return; ?>" . $this->_additional_newline; | |
| 457 | + } | |
| 458 | + | |
| 459 | + /* If the tag name is a registered object, we process it. */ | |
| 460 | + if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) { | |
| 461 | + return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier); | |
| 462 | + } | |
| 463 | + | |
| 464 | + switch ($tag_command) { | |
| 465 | + case 'include': | |
| 466 | + return $this->_compile_include_tag($tag_args); | |
| 467 | + | |
| 468 | + case 'include_php': | |
| 469 | + return $this->_compile_include_php_tag($tag_args); | |
| 470 | + | |
| 471 | + case 'if': | |
| 472 | + $this->_push_tag('if'); | |
| 473 | + return $this->_compile_if_tag($tag_args); | |
| 474 | + | |
| 475 | + case 'else': | |
| 476 | + list($_open_tag) = end($this->_tag_stack); | |
| 477 | + if ($_open_tag != 'if' && $_open_tag != 'elseif') | |
| 478 | + $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__); | |
| 479 | + else | |
| 480 | + $this->_push_tag('else'); | |
| 481 | + return '<?PHP else: ?>'; | |
| 482 | + | |
| 483 | + case 'elseif': | |
| 484 | + list($_open_tag) = end($this->_tag_stack); | |
| 485 | + if ($_open_tag != 'if' && $_open_tag != 'elseif') | |
| 486 | + $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__); | |
| 487 | + if ($_open_tag == 'if') | |
| 488 | + $this->_push_tag('elseif'); | |
| 489 | + return $this->_compile_if_tag($tag_args, true); | |
| 490 | + | |
| 491 | + case '/if': | |
| 492 | + $this->_pop_tag('if'); | |
| 493 | + return '<?PHP endif; ?>'; | |
| 494 | + | |
| 495 | + case 'capture': | |
| 496 | + return $this->_compile_capture_tag(true, $tag_args); | |
| 497 | + | |
| 498 | + case '/capture': | |
| 499 | + return $this->_compile_capture_tag(false); | |
| 500 | + | |
| 501 | + case 'ldelim': | |
| 502 | + return $this->left_delimiter; | |
| 503 | + | |
| 504 | + case 'rdelim': | |
| 505 | + return $this->right_delimiter; | |
| 506 | + | |
| 507 | + case 'section': | |
| 508 | + $this->_push_tag('section'); | |
| 509 | + return $this->_compile_section_start($tag_args); | |
| 510 | + | |
| 511 | + case 'sectionelse': | |
| 512 | + $this->_push_tag('sectionelse'); | |
| 513 | + return "<?PHP endfor; else: ?>"; | |
| 514 | + break; | |
| 515 | + | |
| 516 | + case '/section': | |
| 517 | + $_open_tag = $this->_pop_tag('section'); | |
| 518 | + if ($_open_tag == 'sectionelse') | |
| 519 | + return "<?PHP endif; ?>"; | |
| 520 | + else | |
| 521 | + return "<?PHP endfor; endif; ?>"; | |
| 522 | + | |
| 523 | + case 'foreach': | |
| 524 | + $this->_push_tag('foreach'); | |
| 525 | + return $this->_compile_foreach_start($tag_args); | |
| 526 | + break; | |
| 527 | + | |
| 528 | + case 'foreachelse': | |
| 529 | + $this->_push_tag('foreachelse'); | |
| 530 | + return "<?PHP endforeach; else: ?>"; | |
| 531 | + | |
| 532 | + case '/foreach': | |
| 533 | + $_open_tag = $this->_pop_tag('foreach'); | |
| 534 | + if ($_open_tag == 'foreachelse') | |
| 535 | + return "<?PHP endif; unset(\$_from); ?>"; | |
| 536 | + else | |
| 537 | + return "<?PHP endforeach; endif; unset(\$_from); ?>"; | |
| 538 | + break; | |
| 539 | + | |
| 540 | + case 'strip': | |
| 541 | + case '/strip': | |
| 542 | + if (substr($tag_command, 0, 1)=='/') { | |
| 543 | + $this->_pop_tag('strip'); | |
| 544 | + if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ | |
| 545 | + $this->_additional_newline = "\n"; | |
| 546 | + return '{' . $tag_command . '}'; | |
| 547 | + } | |
| 548 | + } else { | |
| 549 | + $this->_push_tag('strip'); | |
| 550 | + if ($this->_strip_depth++==0) { /* outermost opening {strip} */ | |
| 551 | + $this->_additional_newline = ""; | |
| 552 | + return '{' . $tag_command . '}'; | |
| 553 | + } | |
| 554 | + } | |
| 555 | + return ''; | |
| 556 | + | |
| 557 | + case 'php': | |
| 558 | + /* handle folded tags replaced by {php} */ | |
| 559 | + list(, $block) = each($this->_folded_blocks); | |
| 560 | + $this->_current_line_no += substr_count($block[0], "\n"); | |
| 561 | + /* the number of matched elements in the regexp in _compile_file() | |
| 562 | + determins the type of folded tag that was found */ | |
| 563 | + switch (count($block)) { | |
| 564 | + case 2: /* comment */ | |
| 565 | + return ''; | |
| 566 | + | |
| 567 | + case 3: /* literal */ | |
| 568 | + return "<?PHP echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline; | |
| 569 | + | |
| 570 | + case 4: /* php */ | |
| 571 | + if ($this->security && !$this->security_settings['PHP_TAGS']) { | |
| 572 | + $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); | |
| 573 | + return; | |
| 574 | + } | |
| 575 | + return '<?PHP ' . $block[3] .' ?>'; | |
| 576 | + } | |
| 577 | + break; | |
| 578 | + | |
| 579 | + case 'insert': | |
| 580 | + return $this->_compile_insert_tag($tag_args); | |
| 581 | + | |
| 582 | + default: | |
| 583 | + if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) { | |
| 584 | + return $output; | |
| 585 | + } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { | |
| 586 | + return $output; | |
| 587 | + } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { | |
| 588 | + return $output; | |
| 589 | + } else { | |
| 590 | + $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); | |
| 591 | + } | |
| 592 | + | |
| 593 | + } | |
| 594 | + } | |
| 595 | + | |
| 596 | + | |
| 597 | + /** | |
| 598 | + * compile the custom compiler tag | |
| 599 | + * | |
| 600 | + * sets $output to the compiled custom compiler tag | |
| 601 | + * @param string $tag_command | |
| 602 | + * @param string $tag_args | |
| 603 | + * @param string $output | |
| 604 | + * @return boolean | |
| 605 | + */ | |
| 606 | + function _compile_compiler_tag($tag_command, $tag_args, &$output) | |
| 607 | + { | |
| 608 | + $found = false; | |
| 609 | + $have_function = true; | |
| 610 | + | |
| 611 | + /* | |
| 612 | + * First we check if the compiler function has already been registered | |
| 613 | + * or loaded from a plugin file. | |
| 614 | + */ | |
| 615 | + if (isset($this->_plugins['compiler'][$tag_command])) { | |
| 616 | + $found = true; | |
| 617 | + $plugin_func = $this->_plugins['compiler'][$tag_command][0]; | |
| 618 | + if (!is_callable($plugin_func)) { | |
| 619 | + $message = "compiler function '$tag_command' is not implemented"; | |
| 620 | + $have_function = false; | |
| 621 | + } | |
| 622 | + } | |
| 623 | + /* | |
| 624 | + * Otherwise we need to load plugin file and look for the function | |
| 625 | + * inside it. | |
| 626 | + */ | |
| 627 | + else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) { | |
| 628 | + $found = true; | |
| 629 | + | |
| 630 | + include_once $plugin_file; | |
| 631 | + | |
| 632 | + $plugin_func = 'smarty_compiler_' . $tag_command; | |
| 633 | + if (!is_callable($plugin_func)) { | |
| 634 | + $message = "plugin function $plugin_func() not found in $plugin_file\n"; | |
| 635 | + $have_function = false; | |
| 636 | + } else { | |
| 637 | + $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true); | |
| 638 | + } | |
| 639 | + } | |
| 640 | + | |
| 641 | + /* | |
| 642 | + * True return value means that we either found a plugin or a | |
| 643 | + * dynamically registered function. False means that we didn't and the | |
| 644 | + * compiler should now emit code to load custom function plugin for this | |
| 645 | + * tag. | |
| 646 | + */ | |
| 647 | + if ($found) { | |
| 648 | + if ($have_function) { | |
| 649 | + $output = call_user_func_array($plugin_func, array($tag_args, &$this)); | |
| 650 | + if($output != '') { | |
| 651 | + $output = '<?PHP ' . $this->_push_cacheable_state('compiler', $tag_command) | |
| 652 | + . $output | |
| 653 | + . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>'; | |
| 654 | + } | |
| 655 | + } else { | |
| 656 | + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); | |
| 657 | + } | |
| 658 | + return true; | |
| 659 | + } else { | |
| 660 | + return false; | |
| 661 | + } | |
| 662 | + } | |
| 663 | + | |
| 664 | + | |
| 665 | + /** | |
| 666 | + * compile block function tag | |
| 667 | + * | |
| 668 | + * sets $output to compiled block function tag | |
| 669 | + * @param string $tag_command | |
| 670 | + * @param string $tag_args | |
| 671 | + * @param string $tag_modifier | |
| 672 | + * @param string $output | |
| 673 | + * @return boolean | |
| 674 | + */ | |
| 675 | + function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) | |
| 676 | + { | |
| 677 | + if (substr($tag_command, 0, 1) == '/') { | |
| 678 | + $start_tag = false; | |
| 679 | + $tag_command = substr($tag_command, 1); | |
| 680 | + } else | |
| 681 | + $start_tag = true; | |
| 682 | + | |
| 683 | + $found = false; | |
| 684 | + $have_function = true; | |
| 685 | + | |
| 686 | + /* | |
| 687 | + * First we check if the block function has already been registered | |
| 688 | + * or loaded from a plugin file. | |
| 689 | + */ | |
| 690 | + if (isset($this->_plugins['block'][$tag_command])) { | |
| 691 | + $found = true; | |
| 692 | + $plugin_func = $this->_plugins['block'][$tag_command][0]; | |
| 693 | + if (!is_callable($plugin_func)) { | |
| 694 | + $message = "block function '$tag_command' is not implemented"; | |
| 695 | + $have_function = false; | |
| 696 | + } | |
| 697 | + } | |
| 698 | + /* | |
| 699 | + * Otherwise we need to load plugin file and look for the function | |
| 700 | + * inside it. | |
| 701 | + */ | |
| 702 | + else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) { | |
| 703 | + $found = true; | |
| 704 | + | |
| 705 | + include_once $plugin_file; | |
| 706 | + | |
| 707 | + $plugin_func = 'smarty_block_' . $tag_command; | |
| 708 | + if (!function_exists($plugin_func)) { | |
| 709 | + $message = "plugin function $plugin_func() not found in $plugin_file\n"; | |
| 710 | + $have_function = false; | |
| 711 | + } else { | |
| 712 | + $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true); | |
| 713 | + | |
| 714 | + } | |
| 715 | + } | |
| 716 | + | |
| 717 | + if (!$found) { | |
| 718 | + return false; | |
| 719 | + } else if (!$have_function) { | |
| 720 | + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); | |
| 721 | + return true; | |
| 722 | + } | |
| 723 | + | |
| 724 | + /* | |
| 725 | + * Even though we've located the plugin function, compilation | |
| 726 | + * happens only once, so the plugin will still need to be loaded | |
| 727 | + * at runtime for future requests. | |
| 728 | + */ | |
| 729 | + $this->_add_plugin('block', $tag_command); | |
| 730 | + | |
| 731 | + if ($start_tag) | |
| 732 | + $this->_push_tag($tag_command); | |
| 733 | + else | |
| 734 | + $this->_pop_tag($tag_command); | |
| 735 | + | |
| 736 | + if ($start_tag) { | |
| 737 | + $output = '<?PHP ' . $this->_push_cacheable_state('block', $tag_command); | |
| 738 | + $attrs = $this->_parse_attrs($tag_args); | |
| 739 | + $_cache_attrs=''; | |
| 740 | + $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs); | |
| 741 | + $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; | |
| 742 | + $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);'; | |
| 743 | + $output .= 'while ($_block_repeat) { ob_start(); ?>'; | |
| 744 | + } else { | |
| 745 | + $output = '<?PHP $_block_content = ob_get_contents(); ob_end_clean(); '; | |
| 746 | + $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)'; | |
| 747 | + if ($tag_modifier != '') { | |
| 748 | + $this->_parse_modifiers($_out_tag_text, $tag_modifier); | |
| 749 | + } | |
| 750 | + $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } '; | |
| 751 | + $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>'; | |
| 752 | + } | |
| 753 | + | |
| 754 | + return true; | |
| 755 | + } | |
| 756 | + | |
| 757 | + | |
| 758 | + /** | |
| 759 | + * compile custom function tag | |
| 760 | + * | |
| 761 | + * @param string $tag_command | |
| 762 | + * @param string $tag_args | |
| 763 | + * @param string $tag_modifier | |
| 764 | + * @return string | |
| 765 | + */ | |
| 766 | + function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output) | |
| 767 | + { | |
| 768 | + $found = false; | |
| 769 | + $have_function = true; | |
| 770 | + | |
| 771 | + /* | |
| 772 | + * First we check if the custom function has already been registered | |
| 773 | + * or loaded from a plugin file. | |
| 774 | + */ | |
| 775 | + if (isset($this->_plugins['function'][$tag_command])) { | |
| 776 | + $found = true; | |
| 777 | + $plugin_func = $this->_plugins['function'][$tag_command][0]; | |
| 778 | + if (!is_callable($plugin_func)) { | |
| 779 | + $message = "custom function '$tag_command' is not implemented"; | |
| 780 | + $have_function = false; | |
| 781 | + } | |
| 782 | + } | |
| 783 | + /* | |
| 784 | + * Otherwise we need to load plugin file and look for the function | |
| 785 | + * inside it. | |
| 786 | + */ | |
| 787 | + else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) { | |
| 788 | + $found = true; | |
| 789 | + | |
| 790 | + include_once $plugin_file; | |
| 791 | + | |
| 792 | + $plugin_func = 'smarty_function_' . $tag_command; | |
| 793 | + if (!function_exists($plugin_func)) { | |
| 794 | + $message = "plugin function $plugin_func() not found in $plugin_file\n"; | |
| 795 | + $have_function = false; | |
| 796 | + } else { | |
| 797 | + $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true); | |
| 798 | + | |
| 799 | + } | |
| 800 | + } | |
| 801 | + | |
| 802 | + if (!$found) { | |
| 803 | + return false; | |
| 804 | + } else if (!$have_function) { | |
| 805 | + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); | |
| 806 | + return true; | |
| 807 | + } | |
| 808 | + | |
| 809 | + /* declare plugin to be loaded on display of the template that | |
| 810 | + we compile right now */ | |
| 811 | + $this->_add_plugin('function', $tag_command); | |
| 812 | + | |
| 813 | + $_cacheable_state = $this->_push_cacheable_state('function', $tag_command); | |
| 814 | + $attrs = $this->_parse_attrs($tag_args); | |
| 815 | + $_cache_attrs = ''; | |
| 816 | + $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs); | |
| 817 | + | |
| 818 | + $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; | |
| 819 | + if($tag_modifier != '') { | |
| 820 | + $this->_parse_modifiers($output, $tag_modifier); | |
| 821 | + } | |
| 822 | + | |
| 823 | + if($output != '') { | |
| 824 | + $output = '<?PHP ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';' | |
| 825 | + . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline; | |
| 826 | + } | |
| 827 | + | |
| 828 | + return true; | |
| 829 | + } | |
| 830 | + | |
| 831 | + /** | |
| 832 | + * compile a registered object tag | |
| 833 | + * | |
| 834 | + * @param string $tag_command | |
| 835 | + * @param array $attrs | |
| 836 | + * @param string $tag_modifier | |
| 837 | + * @return string | |
| 838 | + */ | |
| 839 | + function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) | |
| 840 | + { | |
| 841 | + if (substr($tag_command, 0, 1) == '/') { | |
| 842 | + $start_tag = false; | |
| 843 | + $tag_command = substr($tag_command, 1); | |
| 844 | + } else { | |
| 845 | + $start_tag = true; | |
| 846 | + } | |
| 847 | + | |
| 848 | + list($object, $obj_comp) = explode('->', $tag_command); | |
| 849 | + | |
| 850 | + $arg_list = array(); | |
| 851 | + if(count($attrs)) { | |
| 852 | + $_assign_var = false; | |
| 853 | + foreach ($attrs as $arg_name => $arg_value) { | |
| 854 | + if($arg_name == 'assign') { | |
| 855 | + $_assign_var = $arg_value; | |
| 856 | + unset($attrs['assign']); | |
| 857 | + continue; | |
| 858 | + } | |
| 859 | + if (is_bool($arg_value)) | |
| 860 | + $arg_value = $arg_value ? 'true' : 'false'; | |
| 861 | + $arg_list[] = "'$arg_name' => $arg_value"; | |
| 862 | + } | |
| 863 | + } | |
| 864 | + | |
| 865 | + if($this->_reg_objects[$object][2]) { | |
| 866 | + // smarty object argument format | |
| 867 | + $args = "array(".implode(',', (array)$arg_list)."), \$this"; | |
| 868 | + } else { | |
| 869 | + // traditional argument format | |
| 870 | + $args = implode(',', array_values($attrs)); | |
| 871 | + if (empty($args)) { | |
| 872 | + $args = ''; | |
| 873 | + } | |
| 874 | + } | |
| 875 | + | |
| 876 | + $prefix = ''; | |
| 877 | + $postfix = ''; | |
| 878 | + $newline = ''; | |
| 879 | + if(!is_object($this->_reg_objects[$object][0])) { | |
| 880 | + $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); | |
| 881 | + } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) { | |
| 882 | + $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); | |
| 883 | + } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) { | |
| 884 | + // method | |
| 885 | + if(in_array($obj_comp, $this->_reg_objects[$object][3])) { | |
| 886 | + // block method | |
| 887 | + if ($start_tag) { | |
| 888 | + $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; | |
| 889 | + $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); "; | |
| 890 | + $prefix .= "while (\$_block_repeat) { ob_start();"; | |
| 891 | + $return = null; | |
| 892 | + $postfix = ''; | |
| 893 | + } else { | |
| 894 | + $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;"; | |
| 895 | + $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)"; | |
| 896 | + $postfix = "} array_pop(\$this->_tag_stack);"; | |
| 897 | + } | |
| 898 | + } else { | |
| 899 | + // non-block method | |
| 900 | + $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)"; | |
| 901 | + } | |
| 902 | + } else { | |
| 903 | + // property | |
| 904 | + $return = "\$this->_reg_objects['$object'][0]->$obj_comp"; | |
| 905 | + } | |
| 906 | + | |
| 907 | + if($return != null) { | |
| 908 | + if($tag_modifier != '') { | |
| 909 | + $this->_parse_modifiers($return, $tag_modifier); | |
| 910 | + } | |
| 911 | + | |
| 912 | + if(!empty($_assign_var)) { | |
| 913 | + $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);"; | |
| 914 | + } else { | |
| 915 | + $output = 'echo ' . $return . ';'; | |
| 916 | + $newline = $this->_additional_newline; | |
| 917 | + } | |
| 918 | + } else { | |
| 919 | + $output = ''; | |
| 920 | + } | |
| 921 | + | |
| 922 | + return '<?PHP ' . $prefix . $output . $postfix . "?>" . $newline; | |
| 923 | + } | |
| 924 | + | |
| 925 | + /** | |
| 926 | + * Compile {insert ...} tag | |
| 927 | + * | |
| 928 | + * @param string $tag_args | |
| 929 | + * @return string | |
| 930 | + */ | |
| 931 | + function _compile_insert_tag($tag_args) | |
| 932 | + { | |
| 933 | + $attrs = $this->_parse_attrs($tag_args); | |
| 934 | + $name = $this->_dequote($attrs['name']); | |
| 935 | + | |
| 936 | + if (empty($name)) { | |
| 937 | + return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); | |
| 938 | + } | |
| 939 | + | |
| 940 | + if (!preg_match('~^\w+$~', $name)) { | |
| 941 | + return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__); | |
| 942 | + } | |
| 943 | + | |
| 944 | + if (!empty($attrs['script'])) { | |
| 945 | + $delayed_loading = true; | |
| 946 | + } else { | |
| 947 | + $delayed_loading = false; | |
| 948 | + } | |
| 949 | + | |
| 950 | + foreach ($attrs as $arg_name => $arg_value) { | |
| 951 | + if (is_bool($arg_value)) | |
| 952 | + $arg_value = $arg_value ? 'true' : 'false'; | |
| 953 | + $arg_list[] = "'$arg_name' => $arg_value"; | |
| 954 | + } | |
| 955 | + | |
| 956 | + $this->_add_plugin('insert', $name, $delayed_loading); | |
| 957 | + | |
| 958 | + $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))"; | |
| 959 | + | |
| 960 | + return "<?PHP require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline; | |
| 961 | + } | |
| 962 | + | |
| 963 | + /** | |
| 964 | + * Compile {include ...} tag | |
| 965 | + * | |
| 966 | + * @param string $tag_args | |
| 967 | + * @return string | |
| 968 | + */ | |
| 969 | + function _compile_include_tag($tag_args) | |
| 970 | + { | |
| 971 | + $attrs = $this->_parse_attrs($tag_args); | |
| 972 | + $arg_list = array(); | |
| 973 | + | |
| 974 | + if (empty($attrs['file'])) { | |
| 975 | + $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__); | |
| 976 | + } | |
| 977 | + | |
| 978 | + foreach ($attrs as $arg_name => $arg_value) { | |
| 979 | + if ($arg_name == 'file') { | |
| 980 | + $include_file = $arg_value; | |
| 981 | + continue; | |
| 982 | + } else if ($arg_name == 'assign') { | |
| 983 | + $assign_var = $arg_value; | |
| 984 | + continue; | |
| 985 | + } | |
| 986 | + if (is_bool($arg_value)) | |
| 987 | + $arg_value = $arg_value ? 'true' : 'false'; | |
| 988 | + $arg_list[] = "'$arg_name' => $arg_value"; | |
| 989 | + } | |
| 990 | + | |
| 991 | + $output = '<?PHP '; | |
| 992 | + | |
| 993 | + if (isset($assign_var)) { | |
| 994 | + $output .= "ob_start();\n"; | |
| 995 | + } | |
| 996 | + | |
| 997 | + $output .= | |
| 998 | + "\$_smarty_tpl_vars = \$this->_tpl_vars;\n"; | |
| 999 | + | |
| 1000 | + | |
| 1001 | + $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))"; | |
| 1002 | + $output .= "\$this->_smarty_include($_params);\n" . | |
| 1003 | + "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . | |
| 1004 | + "unset(\$_smarty_tpl_vars);\n"; | |
| 1005 | + | |
| 1006 | + if (isset($assign_var)) { | |
| 1007 | + $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n"; | |
| 1008 | + } | |
| 1009 | + | |
| 1010 | + $output .= ' ?>'; | |
| 1011 | + | |
| 1012 | + return $output; | |
| 1013 | + | |
| 1014 | + } | |
| 1015 | + | |
| 1016 | + /** | |
| 1017 | + * Compile {include ...} tag | |
| 1018 | + * | |
| 1019 | + * @param string $tag_args | |
| 1020 | + * @return string | |
| 1021 | + */ | |
| 1022 | + function _compile_include_php_tag($tag_args) | |
| 1023 | + { | |
| 1024 | + $attrs = $this->_parse_attrs($tag_args); | |
| 1025 | + | |
| 1026 | + if (empty($attrs['file'])) { | |
| 1027 | + $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__); | |
| 1028 | + } | |
| 1029 | + | |
| 1030 | + $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']); | |
| 1031 | + $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true'; | |
| 1032 | + | |
| 1033 | + $arg_list = array(); | |
| 1034 | + foreach($attrs as $arg_name => $arg_value) { | |
| 1035 | + if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') { | |
| 1036 | + if(is_bool($arg_value)) | |
| 1037 | + $arg_value = $arg_value ? 'true' : 'false'; | |
| 1038 | + $arg_list[] = "'$arg_name' => $arg_value"; | |
| 1039 | + } | |
| 1040 | + } | |
| 1041 | + | |
| 1042 | + $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))"; | |
| 1043 | + | |
| 1044 | + return "<?PHP require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline; | |
| 1045 | + } | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + /** | |
| 1049 | + * Compile {section ...} tag | |
| 1050 | + * | |
| 1051 | + * @param string $tag_args | |
| 1052 | + * @return string | |
| 1053 | + */ | |
| 1054 | + function _compile_section_start($tag_args) | |
| 1055 | + { | |
| 1056 | + $attrs = $this->_parse_attrs($tag_args); | |
| 1057 | + $arg_list = array(); | |
| 1058 | + | |
| 1059 | + $output = '<?PHP '; | |
| 1060 | + $section_name = $attrs['name']; | |
| 1061 | + if (empty($section_name)) { | |
| 1062 | + $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__); | |
| 1063 | + } | |
| 1064 | + | |
| 1065 | + $output .= "unset(\$this->_sections[$section_name]);\n"; | |
| 1066 | + $section_props = "\$this->_sections[$section_name]"; | |
| 1067 | + | |
| 1068 | + foreach ($attrs as $attr_name => $attr_value) { | |
| 1069 | + switch ($attr_name) { | |
| 1070 | + case 'loop': | |
| 1071 | + $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n"; | |
| 1072 | + break; | |
| 1073 | + | |
| 1074 | + case 'show': | |
| 1075 | + if (is_bool($attr_value)) | |
| 1076 | + $show_attr_value = $attr_value ? 'true' : 'false'; | |
| 1077 | + else | |
| 1078 | + $show_attr_value = "(bool)$attr_value"; | |
| 1079 | + $output .= "{$section_props}['show'] = $show_attr_value;\n"; | |
| 1080 | + break; | |
| 1081 | + | |
| 1082 | + case 'name': | |
| 1083 | + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; | |
| 1084 | + break; | |
| 1085 | + | |
| 1086 | + case 'max': | |
| 1087 | + case 'start': | |
| 1088 | + $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n"; | |
| 1089 | + break; | |
| 1090 | + | |
| 1091 | + case 'step': | |
| 1092 | + $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n"; | |
| 1093 | + break; | |
| 1094 | + | |
| 1095 | + default: | |
| 1096 | + $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__); | |
| 1097 | + break; | |
| 1098 | + } | |
| 1099 | + } | |
| 1100 | + | |
| 1101 | + if (!isset($attrs['show'])) | |
| 1102 | + $output .= "{$section_props}['show'] = true;\n"; | |
| 1103 | + | |
| 1104 | + if (!isset($attrs['loop'])) | |
| 1105 | + $output .= "{$section_props}['loop'] = 1;\n"; | |
| 1106 | + | |
| 1107 | + if (!isset($attrs['max'])) | |
| 1108 | + $output .= "{$section_props}['max'] = {$section_props}['loop'];\n"; | |
| 1109 | + else | |
| 1110 | + $output .= "if ({$section_props}['max'] < 0)\n" . | |
| 1111 | + " {$section_props}['max'] = {$section_props}['loop'];\n"; | |
| 1112 | + | |
| 1113 | + if (!isset($attrs['step'])) | |
| 1114 | + $output .= "{$section_props}['step'] = 1;\n"; | |
| 1115 | + | |
| 1116 | + if (!isset($attrs['start'])) | |
| 1117 | + $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n"; | |
| 1118 | + else { | |
| 1119 | + $output .= "if ({$section_props}['start'] < 0)\n" . | |
| 1120 | + " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . | |
| 1121 | + "else\n" . | |
| 1122 | + " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n"; | |
| 1123 | + } | |
| 1124 | + | |
| 1125 | + $output .= "if ({$section_props}['show']) {\n"; | |
| 1126 | + if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) { | |
| 1127 | + $output .= " {$section_props}['total'] = {$section_props}['loop'];\n"; | |
| 1128 | + } else { | |
| 1129 | + $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"; | |
| 1130 | + } | |
| 1131 | + $output .= " if ({$section_props}['total'] == 0)\n" . | |
| 1132 | + " {$section_props}['show'] = false;\n" . | |
| 1133 | + "} else\n" . | |
| 1134 | + " {$section_props}['total'] = 0;\n"; | |
| 1135 | + | |
| 1136 | + $output .= "if ({$section_props}['show']):\n"; | |
| 1137 | + $output .= " | |
| 1138 | + for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; | |
| 1139 | + {$section_props}['iteration'] <= {$section_props}['total']; | |
| 1140 | + {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; | |
| 1141 | + $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; | |
| 1142 | + $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; | |
| 1143 | + $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; | |
| 1144 | + $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; | |
| 1145 | + $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; | |
| 1146 | + | |
| 1147 | + $output .= "?>"; | |
| 1148 | + | |
| 1149 | + return $output; | |
| 1150 | + } | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + /** | |
| 1154 | + * Compile {foreach ...} tag. | |
| 1155 | + * | |
| 1156 | + * @param string $tag_args | |
| 1157 | + * @return string | |
| 1158 | + */ | |
| 1159 | + function _compile_foreach_start($tag_args) | |
| 1160 | + { | |
| 1161 | + $attrs = $this->_parse_attrs($tag_args); | |
| 1162 | + $arg_list = array(); | |
| 1163 | + | |
| 1164 | + if (empty($attrs['from'])) { | |
| 1165 | + return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); | |
| 1166 | + } | |
| 1167 | + $from = $attrs['from']; | |
| 1168 | + | |
| 1169 | + if (empty($attrs['item'])) { | |
| 1170 | + return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); | |
| 1171 | + } | |
| 1172 | + $item = $this->_dequote($attrs['item']); | |
| 1173 | + if (!preg_match('~^\w+$~', $item)) { | |
| 1174 | + return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); | |
| 1175 | + } | |
| 1176 | + | |
| 1177 | + if (isset($attrs['key'])) { | |
| 1178 | + $key = $this->_dequote($attrs['key']); | |
| 1179 | + if (!preg_match('~^\w+$~', $key)) { | |
| 1180 | + return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); | |
| 1181 | + } | |
| 1182 | + $key_part = "\$this->_tpl_vars['$key'] => "; | |
| 1183 | + } else { | |
| 1184 | + $key = null; | |
| 1185 | + $key_part = ''; | |
| 1186 | + } | |
| 1187 | + | |
| 1188 | + if (isset($attrs['name'])) { | |
| 1189 | + $name = $attrs['name']; | |
| 1190 | + } else { | |
| 1191 | + $name = null; | |
| 1192 | + } | |
| 1193 | + | |
| 1194 | + $output = '<?PHP '; | |
| 1195 | + $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }"; | |
| 1196 | + if (isset($name)) { | |
| 1197 | + $foreach_props = "\$this->_foreach[$name]"; | |
| 1198 | + $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n"; | |
| 1199 | + $output .= "if ({$foreach_props}['total'] > 0):\n"; | |
| 1200 | + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; | |
| 1201 | + $output .= " {$foreach_props}['iteration']++;\n"; | |
| 1202 | + } else { | |
| 1203 | + $output .= "if (count(\$_from)):\n"; | |
| 1204 | + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; | |
| 1205 | + } | |
| 1206 | + $output .= '?>'; | |
| 1207 | + | |
| 1208 | + return $output; | |
| 1209 | + } | |
| 1210 | + | |
| 1211 | + | |
| 1212 | + /** | |
| 1213 | + * Compile {capture} .. {/capture} tags | |
| 1214 | + * | |
| 1215 | + * @param boolean $start true if this is the {capture} tag | |
| 1216 | + * @param string $tag_args | |
| 1217 | + * @return string | |
| 1218 | + */ | |
| 1219 | + | |
| 1220 | + function _compile_capture_tag($start, $tag_args = '') | |
| 1221 | + { | |
| 1222 | + $attrs = $this->_parse_attrs($tag_args); | |
| 1223 | + | |
| 1224 | + if ($start) { | |
| 1225 | + $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'"; | |
| 1226 | + $assign = isset($attrs['assign']) ? $attrs['assign'] : null; | |
| 1227 | + $append = isset($attrs['append']) ? $attrs['append'] : null; | |
| 1228 | + | |
| 1229 | + $output = "<?PHP ob_start(); ?>"; | |
| 1230 | + $this->_capture_stack[] = array($buffer, $assign, $append); | |
| 1231 | + } else { | |
| 1232 | + list($buffer, $assign, $append) = array_pop($this->_capture_stack); | |
| 1233 | + $output = "<?PHP \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); "; | |
| 1234 | + if (isset($assign)) { | |
| 1235 | + $output .= " \$this->assign($assign, ob_get_contents());"; | |
| 1236 | + } | |
| 1237 | + if (isset($append)) { | |
| 1238 | + $output .= " \$this->append($append, ob_get_contents());"; | |
| 1239 | + } | |
| 1240 | + $output .= "ob_end_clean(); ?>"; | |
| 1241 | + } | |
| 1242 | + | |
| 1243 | + return $output; | |
| 1244 | + } | |
| 1245 | + | |
| 1246 | + /** | |
| 1247 | + * Compile {if ...} tag | |
| 1248 | + * | |
| 1249 | + * @param string $tag_args | |
| 1250 | + * @param boolean $elseif if true, uses elseif instead of if | |
| 1251 | + * @return string | |
| 1252 | + */ | |
| 1253 | + function _compile_if_tag($tag_args, $elseif = false) | |
| 1254 | + { | |
| 1255 | + | |
| 1256 | + /* Tokenize args for 'if' tag. */ | |
| 1257 | + preg_match_all('~(?> | |
| 1258 | + ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call | |
| 1259 | + ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string | |
| 1260 | + \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token | |
| 1261 | + \b\w+\b | # valid word token | |
| 1262 | + \S+ # anything else | |
| 1263 | + )~x', $tag_args, $match); | |
| 1264 | + | |
| 1265 | + $tokens = $match[0]; | |
| 1266 | + | |
| 1267 | + if(empty($tokens)) { | |
| 1268 | + $_error_msg = $elseif ? "'elseif'" : "'if'"; | |
| 1269 | + $_error_msg .= ' statement requires arguments'; | |
| 1270 | + $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); | |
| 1271 | + } | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + // make sure we have balanced parenthesis | |
| 1275 | + $token_count = array_count_values($tokens); | |
| 1276 | + if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { | |
| 1277 | + $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__); | |
| 1278 | + } | |
| 1279 | + | |
| 1280 | + $is_arg_stack = array(); | |
| 1281 | + | |
| 1282 | + for ($i = 0; $i < count($tokens); $i++) { | |
| 1283 | + | |
| 1284 | + $token = &$tokens[$i]; | |
| 1285 | + | |
| 1286 | + switch (strtolower($token)) { | |
| 1287 | + case '!': | |
| 1288 | + case '%': | |
| 1289 | + case '!==': | |
| 1290 | + case '==': | |
| 1291 | + case '===': | |
| 1292 | + case '>': | |
| 1293 | + case '<': | |
| 1294 | + case '!=': | |
| 1295 | + case '<>': | |
| 1296 | + case '<<': | |
| 1297 | + case '>>': | |
| 1298 | + case '<=': | |
| 1299 | + case '>=': | |
| 1300 | + case '&&': | |
| 1301 | + case '||': | |
| 1302 | + case '|': | |
| 1303 | + case '^': | |
| 1304 | + case '&': | |
| 1305 | + case '~': | |
| 1306 | + case ')': | |
| 1307 | + case ',': | |
| 1308 | + case '+': | |
| 1309 | + case '-': | |
| 1310 | + case '*': | |
| 1311 | + case '/': | |
| 1312 | + case '@': | |
| 1313 | + break; | |
| 1314 | + | |
| 1315 | + case 'eq': | |
| 1316 | + $token = '=='; | |
| 1317 | + break; | |
| 1318 | + | |
| 1319 | + case 'ne': | |
| 1320 | + case 'neq': | |
| 1321 | + $token = '!='; | |
| 1322 | + break; | |
| 1323 | + | |
| 1324 | + case 'lt': | |
| 1325 | + $token = '<'; | |
| 1326 | + break; | |
| 1327 | + | |
| 1328 | + case 'le': | |
| 1329 | + case 'lte': | |
| 1330 | + $token = '<='; | |
| 1331 | + break; | |
| 1332 | + | |
| 1333 | + case 'gt': | |
| 1334 | + $token = '>'; | |
| 1335 | + break; | |
| 1336 | + | |
| 1337 | + case 'ge': | |
| 1338 | + case 'gte': | |
| 1339 | + $token = '>='; | |
| 1340 | + break; | |
| 1341 | + | |
| 1342 | + case 'and': | |
| 1343 | + $token = '&&'; | |
| 1344 | + break; | |
| 1345 | + | |
| 1346 | + case 'or': | |
| 1347 | + $token = '||'; | |
| 1348 | + break; | |
| 1349 | + | |
| 1350 | + case 'not': | |
| 1351 | + $token = '!'; | |
| 1352 | + break; | |
| 1353 | + | |
| 1354 | + case 'mod': | |
| 1355 | + $token = '%'; | |
| 1356 | + break; | |
| 1357 | + | |
| 1358 | + case '(': | |
| 1359 | + array_push($is_arg_stack, $i); | |
| 1360 | + break; | |
| 1361 | + | |
| 1362 | + case 'is': | |
| 1363 | + /* If last token was a ')', we operate on the parenthesized | |
| 1364 | + expression. The start of the expression is on the stack. | |
| 1365 | + Otherwise, we operate on the last encountered token. */ | |
| 1366 | + if ($tokens[$i-1] == ')') { | |
| 1367 | + $is_arg_start = array_pop($is_arg_stack); | |
| 1368 | + if ($is_arg_start != 0) { | |
| 1369 | + if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) { | |
| 1370 | + $is_arg_start--; | |
| 1371 | + } | |
| 1372 | + } | |
| 1373 | + } else | |
| 1374 | + $is_arg_start = $i-1; | |
| 1375 | + /* Construct the argument for 'is' expression, so it knows | |
| 1376 | + what to operate on. */ | |
| 1377 | + $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); | |
| 1378 | + | |
| 1379 | + /* Pass all tokens from next one until the end to the | |
| 1380 | + 'is' expression parsing function. The function will | |
| 1381 | + return modified tokens, where the first one is the result | |
| 1382 | + of the 'is' expression and the rest are the tokens it | |
| 1383 | + didn't touch. */ | |
| 1384 | + $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); | |
| 1385 | + | |
| 1386 | + /* Replace the old tokens with the new ones. */ | |
| 1387 | + array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); | |
| 1388 | + | |
| 1389 | + /* Adjust argument start so that it won't change from the | |
| 1390 | + current position for the next iteration. */ | |
| 1391 | + $i = $is_arg_start; | |
| 1392 | + break; | |
| 1393 | + | |
| 1394 | + default: | |
| 1395 | + if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) { | |
| 1396 | + // function call | |
| 1397 | + if($this->security && | |
| 1398 | + !in_array($token, $this->security_settings['IF_FUNCS'])) { | |
| 1399 | + $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); | |
| 1400 | + } | |
| 1401 | + } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { | |
| 1402 | + // variable function call | |
| 1403 | + $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); | |
| 1404 | + } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { | |
| 1405 | + // object or variable | |
| 1406 | + $token = $this->_parse_var_props($token); | |
| 1407 | + } elseif(is_numeric($token)) { | |
| 1408 | + // number, skip it | |
| 1409 | + } else { | |
| 1410 | + $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__); | |
| 1411 | + } | |
| 1412 | + break; | |
| 1413 | + } | |
| 1414 | + } | |
| 1415 | + | |
| 1416 | + if ($elseif) | |
| 1417 | + return '<?PHP elseif ('.implode(' ', $tokens).'): ?>'; | |
| 1418 | + else | |
| 1419 | + return '<?PHP if ('.implode(' ', $tokens).'): ?>'; | |
| 1420 | + } | |
| 1421 | + | |
| 1422 | + | |
| 1423 | + function _compile_arg_list($type, $name, $attrs, &$cache_code) { | |
| 1424 | + $arg_list = array(); | |
| 1425 | + | |
| 1426 | + if (isset($type) && isset($name) | |
| 1427 | + && isset($this->_plugins[$type]) | |
| 1428 | + && isset($this->_plugins[$type][$name]) | |
| 1429 | + && empty($this->_plugins[$type][$name][4]) | |
| 1430 | + && is_array($this->_plugins[$type][$name][5]) | |
| 1431 | + ) { | |
| 1432 | + /* we have a list of parameters that should be cached */ | |
| 1433 | + $_cache_attrs = $this->_plugins[$type][$name][5]; | |
| 1434 | + $_count = $this->_cache_attrs_count++; | |
| 1435 | + $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');"; | |
| 1436 | + | |
| 1437 | + } else { | |
| 1438 | + /* no parameters are cached */ | |
| 1439 | + $_cache_attrs = null; | |
| 1440 | + } | |
| 1441 | + | |
| 1442 | + foreach ($attrs as $arg_name => $arg_value) { | |
| 1443 | + if (is_bool($arg_value)) | |
| 1444 | + $arg_value = $arg_value ? 'true' : 'false'; | |
| 1445 | + if (is_null($arg_value)) | |
| 1446 | + $arg_value = 'null'; | |
| 1447 | + if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) { | |
| 1448 | + $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)"; | |
| 1449 | + } else { | |
| 1450 | + $arg_list[] = "'$arg_name' => $arg_value"; | |
| 1451 | + } | |
| 1452 | + } | |
| 1453 | + return $arg_list; | |
| 1454 | + } | |
| 1455 | + | |
| 1456 | + /** | |
| 1457 | + * Parse is expression | |
| 1458 | + * | |
| 1459 | + * @param string $is_arg | |
| 1460 | + * @param array $tokens | |
| 1461 | + * @return array | |
| 1462 | + */ | |
| 1463 | + function _parse_is_expr($is_arg, $tokens) | |
| 1464 | + { | |
| 1465 | + $expr_end = 0; | |
| 1466 | + $negate_expr = false; | |
| 1467 | + | |
| 1468 | + if (($first_token = array_shift($tokens)) == 'not') { | |
| 1469 | + $negate_expr = true; | |
| 1470 | + $expr_type = array_shift($tokens); | |
| 1471 | + } else | |
| 1472 | + $expr_type = $first_token; | |
| 1473 | + | |
| 1474 | + switch ($expr_type) { | |
| 1475 | + case 'even': | |
| 1476 | + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { | |
| 1477 | + $expr_end++; | |
| 1478 | + $expr_arg = $tokens[$expr_end++]; | |
| 1479 | + $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; | |
| 1480 | + } else | |
| 1481 | + $expr = "!(1 & $is_arg)"; | |
| 1482 | + break; | |
| 1483 | + | |
| 1484 | + case 'odd': | |
| 1485 | + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { | |
| 1486 | + $expr_end++; | |
| 1487 | + $expr_arg = $tokens[$expr_end++]; | |
| 1488 | + $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; | |
| 1489 | + } else | |
| 1490 | + $expr = "(1 & $is_arg)"; | |
| 1491 | + break; | |
| 1492 | + | |
| 1493 | + case 'div': | |
| 1494 | + if (@$tokens[$expr_end] == 'by') { | |
| 1495 | + $expr_end++; | |
| 1496 | + $expr_arg = $tokens[$expr_end++]; | |
| 1497 | + $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")"; | |
| 1498 | + } else { | |
| 1499 | + $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__); | |
| 1500 | + } | |
| 1501 | + break; | |
| 1502 | + | |
| 1503 | + default: | |
| 1504 | + $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__); | |
| 1505 | + break; | |
| 1506 | + } | |
| 1507 | + | |
| 1508 | + if ($negate_expr) { | |
| 1509 | + $expr = "!($expr)"; | |
| 1510 | + } | |
| 1511 | + | |
| 1512 | + array_splice($tokens, 0, $expr_end, $expr); | |
| 1513 | + | |
| 1514 | + return $tokens; | |
| 1515 | + } | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + /** | |
| 1519 | + * Parse attribute string | |
| 1520 | + * | |
| 1521 | + * @param string $tag_args | |
| 1522 | + * @return array | |
| 1523 | + */ | |
| 1524 | + function _parse_attrs($tag_args) | |
| 1525 | + { | |
| 1526 | + | |
| 1527 | + /* Tokenize tag attributes. */ | |
| 1528 | + preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) | |
| 1529 | + )+ | | |
| 1530 | + [=] | |
| 1531 | + ~x', $tag_args, $match); | |
| 1532 | + $tokens = $match[0]; | |
| 1533 | + | |
| 1534 | + $attrs = array(); | |
| 1535 | + /* Parse state: | |
| 1536 | + 0 - expecting attribute name | |
| 1537 | + 1 - expecting '=' | |
| 1538 | + 2 - expecting attribute value (not '=') */ | |
| 1539 | + $state = 0; | |
| 1540 | + | |
| 1541 | + foreach ($tokens as $token) { | |
| 1542 | + switch ($state) { | |
| 1543 | + case 0: | |
| 1544 | + /* If the token is a valid identifier, we set attribute name | |
| 1545 | + and go to state 1. */ | |
| 1546 | + if (preg_match('~^\w+$~', $token)) { | |
| 1547 | + $attr_name = $token; | |
| 1548 | + $state = 1; | |
| 1549 | + } else | |
| 1550 | + $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__); | |
| 1551 | + break; | |
| 1552 | + | |
| 1553 | + case 1: | |
| 1554 | + /* If the token is '=', then we go to state 2. */ | |
| 1555 | + if ($token == '=') { | |
| 1556 | + $state = 2; | |
| 1557 | + } else | |
| 1558 | + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); | |
| 1559 | + break; | |
| 1560 | + | |
| 1561 | + case 2: | |
| 1562 | + /* If token is not '=', we set the attribute value and go to | |
| 1563 | + state 0. */ | |
| 1564 | + if ($token != '=') { | |
| 1565 | + /* We booleanize the token if it's a non-quoted possible | |
| 1566 | + boolean value. */ | |
| 1567 | + if (preg_match('~^(on|yes|true)$~', $token)) { | |
| 1568 | + $token = 'true'; | |
| 1569 | + } else if (preg_match('~^(off|no|false)$~', $token)) { | |
| 1570 | + $token = 'false'; | |
| 1571 | + } else if ($token == 'null') { | |
| 1572 | + $token = 'null'; | |
| 1573 | + } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) { | |
| 1574 | + /* treat integer literally */ | |
| 1575 | + } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) { | |
| 1576 | + /* treat as a string, double-quote it escaping quotes */ | |
| 1577 | + $token = '"'.addslashes($token).'"'; | |
| 1578 | + } | |
| 1579 | + | |
| 1580 | + $attrs[$attr_name] = $token; | |
| 1581 | + $state = 0; | |
| 1582 | + } else | |
| 1583 | + $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); | |
| 1584 | + break; | |
| 1585 | + } | |
| 1586 | + $last_token = $token; | |
| 1587 | + } | |
| 1588 | + | |
| 1589 | + if($state != 0) { | |
| 1590 | + if($state == 1) { | |
| 1591 | + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); | |
| 1592 | + } else { | |
| 1593 | + $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__); | |
| 1594 | + } | |
| 1595 | + } | |
| 1596 | + | |
| 1597 | + $this->_parse_vars_props($attrs); | |
| 1598 | + | |
| 1599 | + return $attrs; | |
| 1600 | + } | |
| 1601 | + | |
| 1602 | + /** | |
| 1603 | + * compile multiple variables and section properties tokens into | |
| 1604 | + * PHP code | |
| 1605 | + * | |
| 1606 | + * @param array $tokens | |
| 1607 | + */ | |
| 1608 | + function _parse_vars_props(&$tokens) | |
| 1609 | + { | |
| 1610 | + foreach($tokens as $key => $val) { | |
| 1611 | + $tokens[$key] = $this->_parse_var_props($val); | |
| 1612 | + } | |
| 1613 | + } | |
| 1614 | + | |
| 1615 | + /** | |
| 1616 | + * compile single variable and section properties token into | |
| 1617 | + * PHP code | |
| 1618 | + * | |
| 1619 | + * @param string $val | |
| 1620 | + * @param string $tag_attrs | |
| 1621 | + * @return string | |
| 1622 | + */ | |
| 1623 | + function _parse_var_props($val) | |
| 1624 | + { | |
| 1625 | + $val = trim($val); | |
| 1626 | + | |
| 1627 | + if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) { | |
| 1628 | + // $ variable or object | |
| 1629 | + $return = $this->_parse_var($match[1]); | |
| 1630 | + $modifiers = $match[2]; | |
| 1631 | + if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) { | |
| 1632 | + $_default_mod_string = implode('|',(array)$this->default_modifiers); | |
| 1633 | + $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers; | |
| 1634 | + } | |
| 1635 | + $this->_parse_modifiers($return, $modifiers); | |
| 1636 | + return $return; | |
| 1637 | + } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { | |
| 1638 | + // double quoted text | |
| 1639 | + preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); | |
| 1640 | + $return = $this->_expand_quoted_text($match[1]); | |
| 1641 | + if($match[2] != '') { | |
| 1642 | + $this->_parse_modifiers($return, $match[2]); | |
| 1643 | + } | |
| 1644 | + return $return; | |
| 1645 | + } | |
| 1646 | + elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { | |
| 1647 | + // numerical constant | |
| 1648 | + preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); | |
| 1649 | + if($match[2] != '') { | |
| 1650 | + $this->_parse_modifiers($match[1], $match[2]); | |
| 1651 | + return $match[1]; | |
| 1652 | + } | |
| 1653 | + } | |
| 1654 | + elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { | |
| 1655 | + // single quoted text | |
| 1656 | + preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); | |
| 1657 | + if($match[2] != '') { | |
| 1658 | + $this->_parse_modifiers($match[1], $match[2]); | |
| 1659 | + return $match[1]; | |
| 1660 | + } | |
| 1661 | + } | |
| 1662 | + elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { | |
| 1663 | + // config var | |
| 1664 | + return $this->_parse_conf_var($val); | |
| 1665 | + } | |
| 1666 | + elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { | |
| 1667 | + // section var | |
| 1668 | + return $this->_parse_section_prop($val); | |
| 1669 | + } | |
| 1670 | + elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { | |
| 1671 | + // literal string | |
| 1672 | + return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"'); | |
| 1673 | + } | |
| 1674 | + return $val; | |
| 1675 | + } | |
| 1676 | + | |
| 1677 | + /** | |
| 1678 | + * expand quoted text with embedded variables | |
| 1679 | + * | |
| 1680 | + * @param string $var_expr | |
| 1681 | + * @return string | |
| 1682 | + */ | |
| 1683 | + function _expand_quoted_text($var_expr) | |
| 1684 | + { | |
| 1685 | + // if contains unescaped $, expand it | |
| 1686 | + if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) { | |
| 1687 | + $_match = $_match[0]; | |
| 1688 | + $_replace = array(); | |
| 1689 | + foreach($_match as $_var) { | |
| 1690 | + $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."'; | |
| 1691 | + } | |
| 1692 | + $var_expr = strtr($var_expr, $_replace); | |
| 1693 | + $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr); | |
| 1694 | + } else { | |
| 1695 | + $_return = $var_expr; | |
| 1696 | + } | |
| 1697 | + // replace double quoted literal string with single quotes | |
| 1698 | + $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return); | |
| 1699 | + return $_return; | |
| 1700 | + } | |
| 1701 | + | |
| 1702 | + /** | |
| 1703 | + * parse variable expression into PHP code | |
| 1704 | + * | |
| 1705 | + * @param string $var_expr | |
| 1706 | + * @param string $output | |
| 1707 | + * @return string | |
| 1708 | + */ | |
| 1709 | + function _parse_var($var_expr) | |
| 1710 | + { | |
| 1711 | + $_has_math = false; | |
| 1712 | + $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); | |
| 1713 | + | |
| 1714 | + if(count($_math_vars) > 1) { | |
| 1715 | + $_first_var = ""; | |
| 1716 | + $_complete_var = ""; | |
| 1717 | + $_output = ""; | |
| 1718 | + // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter) | |
| 1719 | + foreach($_math_vars as $_k => $_math_var) { | |
| 1720 | + $_math_var = $_math_vars[$_k]; | |
| 1721 | + | |
| 1722 | + if(!empty($_math_var) || is_numeric($_math_var)) { | |
| 1723 | + // hit a math operator, so process the stuff which came before it | |
| 1724 | + if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) { | |
| 1725 | + $_has_math = true; | |
| 1726 | + if(!empty($_complete_var) || is_numeric($_complete_var)) { | |
| 1727 | + $_output .= $this->_parse_var($_complete_var); | |
| 1728 | + } | |
| 1729 | + | |
| 1730 | + // just output the math operator to php | |
| 1731 | + $_output .= $_math_var; | |
| 1732 | + | |
| 1733 | + if(empty($_first_var)) | |
| 1734 | + $_first_var = $_complete_var; | |
| 1735 | + | |
| 1736 | + $_complete_var = ""; | |
| 1737 | + } else { | |
| 1738 | + $_complete_var .= $_math_var; | |
| 1739 | + } | |
| 1740 | + } | |
| 1741 | + } | |
| 1742 | + if($_has_math) { | |
| 1743 | + if(!empty($_complete_var) || is_numeric($_complete_var)) | |
| 1744 | + $_output .= $this->_parse_var($_complete_var); | |
| 1745 | + | |
| 1746 | + // get the modifiers working (only the last var from math + modifier is left) | |
| 1747 | + $var_expr = $_complete_var; | |
| 1748 | + } | |
| 1749 | + } | |
| 1750 | + | |
| 1751 | + // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit) | |
| 1752 | + if(is_numeric(substr($var_expr, 0, 1))) | |
| 1753 | + $_var_ref = $var_expr; | |
| 1754 | + else | |
| 1755 | + $_var_ref = substr($var_expr, 1); | |
| 1756 | + | |
| 1757 | + if(!$_has_math) { | |
| 1758 | + | |
| 1759 | + // get [foo] and .foo and ->foo and (...) pieces | |
| 1760 | + preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); | |
| 1761 | + | |
| 1762 | + $_indexes = $match[0]; | |
| 1763 | + $_var_name = array_shift($_indexes); | |
| 1764 | + | |
| 1765 | + /* Handle $smarty.* variable references as a special case. */ | |
| 1766 | + if ($_var_name == 'smarty') { | |
| 1767 | + /* | |
| 1768 | + * If the reference could be compiled, use the compiled output; | |
| 1769 | + * otherwise, fall back on the $smarty variable generated at | |
| 1770 | + * run-time. | |
| 1771 | + */ | |
| 1772 | + if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) { | |
| 1773 | + $_output = $smarty_ref; | |
| 1774 | + } else { | |
| 1775 | + $_var_name = substr(array_shift($_indexes), 1); | |
| 1776 | + $_output = "\$this->_smarty_vars['$_var_name']"; | |
| 1777 | + } | |
| 1778 | + } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) { | |
| 1779 | + // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers | |
| 1780 | + if(count($_indexes) > 0) | |
| 1781 | + { | |
| 1782 | + $_var_name .= implode("", $_indexes); | |
| 1783 | + $_indexes = array(); | |
| 1784 | + } | |
| 1785 | + $_output = $_var_name; | |
| 1786 | + } else { | |
| 1787 | + $_output = "\$this->_tpl_vars['$_var_name']"; | |
| 1788 | + } | |
| 1789 | + | |
| 1790 | + foreach ($_indexes as $_index) { | |
| 1791 | + if (substr($_index, 0, 1) == '[') { | |
| 1792 | + $_index = substr($_index, 1, -1); | |
| 1793 | + if (is_numeric($_index)) { | |
| 1794 | + $_output .= "[$_index]"; | |
| 1795 | + } elseif (substr($_index, 0, 1) == '$') { | |
| 1796 | + if (strpos($_index, '.') !== false) { | |
| 1797 | + $_output .= '[' . $this->_parse_var($_index) . ']'; | |
| 1798 | + } else { | |
| 1799 | + $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]"; | |
| 1800 | + } | |
| 1801 | + } else { | |
| 1802 | + $_var_parts = explode('.', $_index); | |
| 1803 | + $_var_section = $_var_parts[0]; | |
| 1804 | + $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; | |
| 1805 | + $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; | |
| 1806 | + } | |
| 1807 | + } else if (substr($_index, 0, 1) == '.') { | |
| 1808 | + if (substr($_index, 1, 1) == '$') | |
| 1809 | + $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; | |
| 1810 | + else | |
| 1811 | + $_output .= "['" . substr($_index, 1) . "']"; | |
| 1812 | + } else if (substr($_index,0,2) == '->') { | |
| 1813 | + if(substr($_index,2,2) == '__') { | |
| 1814 | + $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); | |
| 1815 | + } elseif($this->security && substr($_index, 2, 1) == '_') { | |
| 1816 | + $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); | |
| 1817 | + } elseif (substr($_index, 2, 1) == '$') { | |
| 1818 | + if ($this->security) { | |
| 1819 | + $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); | |
| 1820 | + } else { | |
| 1821 | + $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}'; | |
| 1822 | + } | |
| 1823 | + } else { | |
| 1824 | + $_output .= $_index; | |
| 1825 | + } | |
| 1826 | + } elseif (substr($_index, 0, 1) == '(') { | |
| 1827 | + $_index = $this->_parse_parenth_args($_index); | |
| 1828 | + $_output .= $_index; | |
| 1829 | + } else { | |
| 1830 | + $_output .= $_index; | |
| 1831 | + } | |
| 1832 | + } | |
| 1833 | + } | |
| 1834 | + | |
| 1835 | + return $_output; | |
| 1836 | + } | |
| 1837 | + | |
| 1838 | + /** | |
| 1839 | + * parse arguments in function call parenthesis | |
| 1840 | + * | |
| 1841 | + * @param string $parenth_args | |
| 1842 | + * @return string | |
| 1843 | + */ | |
| 1844 | + function _parse_parenth_args($parenth_args) | |
| 1845 | + { | |
| 1846 | + preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match); | |
| 1847 | + $orig_vals = $match = $match[0]; | |
| 1848 | + $this->_parse_vars_props($match); | |
| 1849 | + $replace = array(); | |
| 1850 | + for ($i = 0, $count = count($match); $i < $count; $i++) { | |
| 1851 | + $replace[$orig_vals[$i]] = $match[$i]; | |
| 1852 | + } | |
| 1853 | + return strtr($parenth_args, $replace); | |
| 1854 | + } | |
| 1855 | + | |
| 1856 | + /** | |
| 1857 | + * parse configuration variable expression into PHP code | |
| 1858 | + * | |
| 1859 | + * @param string $conf_var_expr | |
| 1860 | + */ | |
| 1861 | + function _parse_conf_var($conf_var_expr) | |
| 1862 | + { | |
| 1863 | + $parts = explode('|', $conf_var_expr, 2); | |
| 1864 | + $var_ref = $parts[0]; | |
| 1865 | + $modifiers = isset($parts[1]) ? $parts[1] : ''; | |
| 1866 | + | |
| 1867 | + $var_name = substr($var_ref, 1, -1); | |
| 1868 | + | |
| 1869 | + $output = "\$this->_config[0]['vars']['$var_name']"; | |
| 1870 | + | |
| 1871 | + $this->_parse_modifiers($output, $modifiers); | |
| 1872 | + | |
| 1873 | + return $output; | |
| 1874 | + } | |
| 1875 | + | |
| 1876 | + /** | |
| 1877 | + * parse section property expression into PHP code | |
| 1878 | + * | |
| 1879 | + * @param string $section_prop_expr | |
| 1880 | + * @return string | |
| 1881 | + */ | |
| 1882 | + function _parse_section_prop($section_prop_expr) | |
| 1883 | + { | |
| 1884 | + $parts = explode('|', $section_prop_expr, 2); | |
| 1885 | + $var_ref = $parts[0]; | |
| 1886 | + $modifiers = isset($parts[1]) ? $parts[1] : ''; | |
| 1887 | + | |
| 1888 | + preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); | |
| 1889 | + $section_name = $match[1]; | |
| 1890 | + $prop_name = $match[2]; | |
| 1891 | + | |
| 1892 | + $output = "\$this->_sections['$section_name']['$prop_name']"; | |
| 1893 | + | |
| 1894 | + $this->_parse_modifiers($output, $modifiers); | |
| 1895 | + | |
| 1896 | + return $output; | |
| 1897 | + } | |
| 1898 | + | |
| 1899 | + | |
| 1900 | + /** | |
| 1901 | + * parse modifier chain into PHP code | |
| 1902 | + * | |
| 1903 | + * sets $output to parsed modified chain | |
| 1904 | + * @param string $output | |
| 1905 | + * @param string $modifier_string | |
| 1906 | + */ | |
| 1907 | + function _parse_modifiers(&$output, $modifier_string) | |
| 1908 | + { | |
| 1909 | + preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match); | |
| 1910 | + list(, $_modifiers, $modifier_arg_strings) = $_match; | |
| 1911 | + | |
| 1912 | + for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) { | |
| 1913 | + $_modifier_name = $_modifiers[$_i]; | |
| 1914 | + | |
| 1915 | + if($_modifier_name == 'smarty') { | |
| 1916 | + // skip smarty modifier | |
| 1917 | + continue; | |
| 1918 | + } | |
| 1919 | + | |
| 1920 | + preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match); | |
| 1921 | + $_modifier_args = $_match[1]; | |
| 1922 | + | |
| 1923 | + if (substr($_modifier_name, 0, 1) == '@') { | |
| 1924 | + $_map_array = false; | |
| 1925 | + $_modifier_name = substr($_modifier_name, 1); | |
| 1926 | + } else { | |
| 1927 | + $_map_array = true; | |
| 1928 | + } | |
| 1929 | + | |
| 1930 | + if (empty($this->_plugins['modifier'][$_modifier_name]) | |
| 1931 | + && !$this->_get_plugin_filepath('modifier', $_modifier_name) | |
| 1932 | + && function_exists($_modifier_name)) { | |
| 1933 | + if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) { | |
| 1934 | + $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); | |
| 1935 | + } else { | |
| 1936 | + $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false); | |
| 1937 | + } | |
| 1938 | + } | |
| 1939 | + $this->_add_plugin('modifier', $_modifier_name); | |
| 1940 | + | |
| 1941 | + $this->_parse_vars_props($_modifier_args); | |
| 1942 | + | |
| 1943 | + if($_modifier_name == 'default') { | |
| 1944 | + // supress notifications of default modifier vars and args | |
| 1945 | + if(substr($output, 0, 1) == '$') { | |
| 1946 | + $output = '@' . $output; | |
| 1947 | + } | |
| 1948 | + if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') { | |
| 1949 | + $_modifier_args[0] = '@' . $_modifier_args[0]; | |
| 1950 | + } | |
| 1951 | + } | |
| 1952 | + if (count($_modifier_args) > 0) | |
| 1953 | + $_modifier_args = ', '.implode(', ', $_modifier_args); | |
| 1954 | + else | |
| 1955 | + $_modifier_args = ''; | |
| 1956 | + | |
| 1957 | + if ($_map_array) { | |
| 1958 | + $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))"; | |
| 1959 | + | |
| 1960 | + } else { | |
| 1961 | + | |
| 1962 | + $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)"; | |
| 1963 | + | |
| 1964 | + } | |
| 1965 | + } | |
| 1966 | + } | |
| 1967 | + | |
| 1968 | + | |
| 1969 | + /** | |
| 1970 | + * add plugin | |
| 1971 | + * | |
| 1972 | + * @param string $type | |
| 1973 | + * @param string $name | |
| 1974 | + * @param boolean? $delayed_loading | |
| 1975 | + */ | |
| 1976 | + function _add_plugin($type, $name, $delayed_loading = null) | |
| 1977 | + { | |
| 1978 | + if (!isset($this->_plugin_info[$type])) { | |
| 1979 | + $this->_plugin_info[$type] = array(); | |
| 1980 | + } | |
| 1981 | + if (!isset($this->_plugin_info[$type][$name])) { | |
| 1982 | + $this->_plugin_info[$type][$name] = array($this->_current_file, | |
| 1983 | + $this->_current_line_no, | |
| 1984 | + $delayed_loading); | |
| 1985 | + } | |
| 1986 | + } | |
| 1987 | + | |
| 1988 | + | |
| 1989 | + /** | |
| 1990 | + * Compiles references of type $smarty.foo | |
| 1991 | + * | |
| 1992 | + * @param string $indexes | |
| 1993 | + * @return string | |
| 1994 | + */ | |
| 1995 | + function _compile_smarty_ref(&$indexes) | |
| 1996 | + { | |
| 1997 | + /* Extract the reference name. */ | |
| 1998 | + $_ref = substr($indexes[0], 1); | |
| 1999 | + foreach($indexes as $_index_no=>$_index) { | |
| 2000 | + if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) { | |
| 2001 | + $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); | |
| 2002 | + } | |
| 2003 | + } | |
| 2004 | + | |
| 2005 | + switch ($_ref) { | |
| 2006 | + case 'now': | |
| 2007 | + $compiled_ref = 'time()'; | |
| 2008 | + $_max_index = 1; | |
| 2009 | + break; | |
| 2010 | + | |
| 2011 | + case 'foreach': | |
| 2012 | + array_shift($indexes); | |
| 2013 | + $_var = $this->_parse_var_props(substr($indexes[0], 1)); | |
| 2014 | + $_propname = substr($indexes[1], 1); | |
| 2015 | + $_max_index = 1; | |
| 2016 | + switch ($_propname) { | |
| 2017 | + case 'index': | |
| 2018 | + array_shift($indexes); | |
| 2019 | + $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; | |
| 2020 | + break; | |
| 2021 | + | |
| 2022 | + case 'first': | |
| 2023 | + array_shift($indexes); | |
| 2024 | + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; | |
| 2025 | + break; | |
| 2026 | + | |
| 2027 | + case 'last': | |
| 2028 | + array_shift($indexes); | |
| 2029 | + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; | |
| 2030 | + break; | |
| 2031 | + | |
| 2032 | + case 'show': | |
| 2033 | + array_shift($indexes); | |
| 2034 | + $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; | |
| 2035 | + break; | |
| 2036 | + | |
| 2037 | + default: | |
| 2038 | + unset($_max_index); | |
| 2039 | + $compiled_ref = "\$this->_foreach[$_var]"; | |
| 2040 | + } | |
| 2041 | + break; | |
| 2042 | + | |
| 2043 | + case 'section': | |
| 2044 | + array_shift($indexes); | |
| 2045 | + $_var = $this->_parse_var_props(substr($indexes[0], 1)); | |
| 2046 | + $compiled_ref = "\$this->_sections[$_var]"; | |
| 2047 | + break; | |
| 2048 | + | |
| 2049 | + case 'get': | |
| 2050 | + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { | |
| 2051 | + $this->_syntax_error("(secure mode) super global access not permitted", | |
| 2052 | + E_USER_WARNING, __FILE__, __LINE__); | |
| 2053 | + return; | |
| 2054 | + } | |
| 2055 | + $compiled_ref = "\$_GET"; | |
| 2056 | + break; | |
| 2057 | + | |
| 2058 | + case 'post': | |
| 2059 | + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { | |
| 2060 | + $this->_syntax_error("(secure mode) super global access not permitted", | |
| 2061 | + E_USER_WARNING, __FILE__, __LINE__); | |
| 2062 | + return; | |
| 2063 | + } | |
| 2064 | + $compiled_ref = "\$_POST"; | |
| 2065 | + break; | |
| 2066 | + | |
| 2067 | + case 'cookies': | |
| 2068 | + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { | |
| 2069 | + $this->_syntax_error("(secure mode) super global access not permitted", | |
| 2070 | + E_USER_WARNING, __FILE__, __LINE__); | |
| 2071 | + return; | |
| 2072 | + } | |
| 2073 | + $compiled_ref = "\$_COOKIE"; | |
| 2074 | + break; | |
| 2075 | + | |
| 2076 | + case 'env': | |
| 2077 | + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { | |
| 2078 | + $this->_syntax_error("(secure mode) super global access not permitted", | |
| 2079 | + E_USER_WARNING, __FILE__, __LINE__); | |
| 2080 | + return; | |
| 2081 | + } | |
| 2082 | + $compiled_ref = "\$_ENV"; | |
| 2083 | + break; | |
| 2084 | + | |
| 2085 | + case 'server': | |
| 2086 | + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { | |
| 2087 | + $this->_syntax_error("(secure mode) super global access not permitted", | |
| 2088 | + E_USER_WARNING, __FILE__, __LINE__); | |
| 2089 | + return; | |
| 2090 | + } | |
| 2091 | + $compiled_ref = "\$_SERVER"; | |
| 2092 | + break; | |
| 2093 | + | |
| 2094 | + case 'session': | |
| 2095 | + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { | |
| 2096 | + $this->_syntax_error("(secure mode) super global access not permitted", | |
| 2097 | + E_USER_WARNING, __FILE__, __LINE__); | |
| 2098 | + return; | |
| 2099 | + } | |
| 2100 | + $compiled_ref = "\$_SESSION"; | |
| 2101 | + break; | |
| 2102 | + | |
| 2103 | + /* | |
| 2104 | + * These cases are handled either at run-time or elsewhere in the | |
| 2105 | + * compiler. | |
| 2106 | + */ | |
| 2107 | + case 'request': | |
| 2108 | + if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { | |
| 2109 | + $this->_syntax_error("(secure mode) super global access not permitted", | |
| 2110 | + E_USER_WARNING, __FILE__, __LINE__); | |
| 2111 | + return; | |
| 2112 | + } | |
| 2113 | + if ($this->request_use_auto_globals) { | |
| 2114 | + $compiled_ref = "\$_REQUEST"; | |
| 2115 | + break; | |
| 2116 | + } else { | |
| 2117 | + $this->_init_smarty_vars = true; | |
| 2118 | + } | |
| 2119 | + return null; | |
| 2120 | + | |
| 2121 | + case 'capture': | |
| 2122 | + return null; | |
| 2123 | + | |
| 2124 | + case 'template': | |
| 2125 | + $compiled_ref = "'$this->_current_file'"; | |
| 2126 | + $_max_index = 1; | |
| 2127 | + break; | |
| 2128 | + | |
| 2129 | + case 'version': | |
| 2130 | + $compiled_ref = "'$this->_version'"; | |
| 2131 | + $_max_index = 1; | |
| 2132 | + break; | |
| 2133 | + | |
| 2134 | + case 'const': | |
| 2135 | + if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) { | |
| 2136 | + $this->_syntax_error("(secure mode) constants not permitted", | |
| 2137 | + E_USER_WARNING, __FILE__, __LINE__); | |
| 2138 | + return; | |
| 2139 | + } | |
| 2140 | + array_shift($indexes); | |
| 2141 | + if (preg_match('!^\.\w+$!', $indexes[0])) { | |
| 2142 | + $compiled_ref = '@' . substr($indexes[0], 1); | |
| 2143 | + } else { | |
| 2144 | + $_val = $this->_parse_var_props(substr($indexes[0], 1)); | |
| 2145 | + $compiled_ref = '@constant(' . $_val . ')'; | |
| 2146 | + } | |
| 2147 | + $_max_index = 1; | |
| 2148 | + break; | |
| 2149 | + | |
| 2150 | + case 'config': | |
| 2151 | + $compiled_ref = "\$this->_config[0]['vars']"; | |
| 2152 | + $_max_index = 3; | |
| 2153 | + break; | |
| 2154 | + | |
| 2155 | + case 'ldelim': | |
| 2156 | + $compiled_ref = "'$this->left_delimiter'"; | |
| 2157 | + break; | |
| 2158 | + | |
| 2159 | + case 'rdelim': | |
| 2160 | + $compiled_ref = "'$this->right_delimiter'"; | |
| 2161 | + break; | |
| 2162 | + | |
| 2163 | + default: | |
| 2164 | + $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); | |
| 2165 | + break; | |
| 2166 | + } | |
| 2167 | + | |
| 2168 | + if (isset($_max_index) && count($indexes) > $_max_index) { | |
| 2169 | + $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); | |
| 2170 | + } | |
| 2171 | + | |
| 2172 | + array_shift($indexes); | |
| 2173 | + return $compiled_ref; | |
| 2174 | + } | |
| 2175 | + | |
| 2176 | + /** | |
| 2177 | + * compiles call to plugin of type $type with name $name | |
| 2178 | + * returns a string containing the function-name or method call | |
| 2179 | + * without the paramter-list that would have follow to make the | |
| 2180 | + * call valid php-syntax | |
| 2181 | + * | |
| 2182 | + * @param string $type | |
| 2183 | + * @param string $name | |
| 2184 | + * @return string | |
| 2185 | + */ | |
| 2186 | + function _compile_plugin_call($type, $name) { | |
| 2187 | + if (isset($this->_plugins[$type][$name])) { | |
| 2188 | + /* plugin loaded */ | |
| 2189 | + if (is_array($this->_plugins[$type][$name][0])) { | |
| 2190 | + return ((is_object($this->_plugins[$type][$name][0][0])) ? | |
| 2191 | + "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */ | |
| 2192 | + : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */ | |
| 2193 | + ). $this->_plugins[$type][$name][0][1]; | |
| 2194 | + | |
| 2195 | + } else { | |
| 2196 | + /* function callback */ | |
| 2197 | + return $this->_plugins[$type][$name][0]; | |
| 2198 | + | |
| 2199 | + } | |
| 2200 | + } else { | |
| 2201 | + /* plugin not loaded -> auto-loadable-plugin */ | |
| 2202 | + return 'smarty_'.$type.'_'.$name; | |
| 2203 | + | |
| 2204 | + } | |
| 2205 | + } | |
| 2206 | + | |
| 2207 | + /** | |
| 2208 | + * load pre- and post-filters | |
| 2209 | + */ | |
| 2210 | + function _load_filters() | |
| 2211 | + { | |
| 2212 | + if (count($this->_plugins['prefilter']) > 0) { | |
| 2213 | + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { | |
| 2214 | + if ($prefilter === false) { | |
| 2215 | + unset($this->_plugins['prefilter'][$filter_name]); | |
| 2216 | + $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false))); | |
| 2217 | + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); | |
| 2218 | + smarty_core_load_plugins($_params, $this); | |
| 2219 | + } | |
| 2220 | + } | |
| 2221 | + } | |
| 2222 | + if (count($this->_plugins['postfilter']) > 0) { | |
| 2223 | + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { | |
| 2224 | + if ($postfilter === false) { | |
| 2225 | + unset($this->_plugins['postfilter'][$filter_name]); | |
| 2226 | + $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false))); | |
| 2227 | + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); | |
| 2228 | + smarty_core_load_plugins($_params, $this); | |
| 2229 | + } | |
| 2230 | + } | |
| 2231 | + } | |
| 2232 | + } | |
| 2233 | + | |
| 2234 | + | |
| 2235 | + /** | |
| 2236 | + * Quote subpattern references | |
| 2237 | + * | |
| 2238 | + * @param string $string | |
| 2239 | + * @return string | |
| 2240 | + */ | |
| 2241 | + function _quote_replace($string) | |
| 2242 | + { | |
| 2243 | + return strtr($string, array('\\' => '\\\\', '$' => '\\$')); | |
| 2244 | + } | |
| 2245 | + | |
| 2246 | + /** | |
| 2247 | + * display Smarty syntax error | |
| 2248 | + * | |
| 2249 | + * @param string $error_msg | |
| 2250 | + * @param integer $error_type | |
| 2251 | + * @param string $file | |
| 2252 | + * @param integer $line | |
| 2253 | + */ | |
| 2254 | + function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) | |
| 2255 | + { | |
| 2256 | + $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type); | |
| 2257 | + } | |
| 2258 | + | |
| 2259 | + | |
| 2260 | + /** | |
| 2261 | + * check if the compilation changes from cacheable to | |
| 2262 | + * non-cacheable state with the beginning of the current | |
| 2263 | + * plugin. return php-code to reflect the transition. | |
| 2264 | + * @return string | |
| 2265 | + */ | |
| 2266 | + function _push_cacheable_state($type, $name) { | |
| 2267 | + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; | |
| 2268 | + if ($_cacheable | |
| 2269 | + || 0<$this->_cacheable_state++) return ''; | |
| 2270 | + if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); | |
| 2271 | + $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:' | |
| 2272 | + . $this->_cache_serial . '#' . $this->_nocache_count | |
| 2273 | + . '}\'; endif;'; | |
| 2274 | + return $_ret; | |
| 2275 | + } | |
| 2276 | + | |
| 2277 | + | |
| 2278 | + /** | |
| 2279 | + * check if the compilation changes from non-cacheable to | |
| 2280 | + * cacheable state with the end of the current plugin return | |
| 2281 | + * php-code to reflect the transition. | |
| 2282 | + * @return string | |
| 2283 | + */ | |
| 2284 | + function _pop_cacheable_state($type, $name) { | |
| 2285 | + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; | |
| 2286 | + if ($_cacheable | |
| 2287 | + || --$this->_cacheable_state>0) return ''; | |
| 2288 | + return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:' | |
| 2289 | + . $this->_cache_serial . '#' . ($this->_nocache_count++) | |
| 2290 | + . '}\'; endif;'; | |
| 2291 | + } | |
| 2292 | + | |
| 2293 | + | |
| 2294 | + /** | |
| 2295 | + * push opening tag-name, file-name and line-number on the tag-stack | |
| 2296 | + * @param string the opening tag's name | |
| 2297 | + */ | |
| 2298 | + function _push_tag($open_tag) | |
| 2299 | + { | |
| 2300 | + array_push($this->_tag_stack, array($open_tag, $this->_current_line_no)); | |
| 2301 | + } | |
| 2302 | + | |
| 2303 | + /** | |
| 2304 | + * pop closing tag-name | |
| 2305 | + * raise an error if this stack-top doesn't match with the closing tag | |
| 2306 | + * @param string the closing tag's name | |
| 2307 | + * @return string the opening tag's name | |
| 2308 | + */ | |
| 2309 | + function _pop_tag($close_tag) | |
| 2310 | + { | |
| 2311 | + $message = ''; | |
| 2312 | + if (count($this->_tag_stack)>0) { | |
| 2313 | + list($_open_tag, $_line_no) = array_pop($this->_tag_stack); | |
| 2314 | + if ($close_tag == $_open_tag) { | |
| 2315 | + return $_open_tag; | |
| 2316 | + } | |
| 2317 | + if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) { | |
| 2318 | + return $this->_pop_tag($close_tag); | |
| 2319 | + } | |
| 2320 | + if ($close_tag == 'section' && $_open_tag == 'sectionelse') { | |
| 2321 | + $this->_pop_tag($close_tag); | |
| 2322 | + return $_open_tag; | |
| 2323 | + } | |
| 2324 | + if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') { | |
| 2325 | + $this->_pop_tag($close_tag); | |
| 2326 | + return $_open_tag; | |
| 2327 | + } | |
| 2328 | + if ($_open_tag == 'else' || $_open_tag == 'elseif') { | |
| 2329 | + $_open_tag = 'if'; | |
| 2330 | + } elseif ($_open_tag == 'sectionelse') { | |
| 2331 | + $_open_tag = 'section'; | |
| 2332 | + } elseif ($_open_tag == 'foreachelse') { | |
| 2333 | + $_open_tag = 'foreach'; | |
| 2334 | + } | |
| 2335 | + $message = " expected {/$_open_tag} (opened line $_line_no)."; | |
| 2336 | + } | |
| 2337 | + $this->_syntax_error("mismatched tag {/$close_tag}.$message", | |
| 2338 | + E_USER_ERROR, __FILE__, __LINE__); | |
| 2339 | + } | |
| 2340 | + | |
| 2341 | +} | |
| 2342 | + | |
| 2343 | +/** | |
| 2344 | + * compare to values by their string length | |
| 2345 | + * | |
| 2346 | + * @access private | |
| 2347 | + * @param string $a | |
| 2348 | + * @param string $b | |
| 2349 | + * @return 0|-1|1 | |
| 2350 | + */ | |
| 2351 | +function _smarty_sort_length($a, $b) | |
| 2352 | +{ | |
| 2353 | + if($a == $b) | |
| 2354 | + return 0; | |
| 2355 | + | |
| 2356 | + if(strlen($a) == strlen($b)) | |
| 2357 | + return ($a > $b) ? -1 : 1; | |
| 2358 | + | |
| 2359 | + return (strlen($a) > strlen($b)) ? -1 : 1; | |
| 2360 | +} | |
| 2361 | + | |
| 2362 | + | |
| 2363 | +/* vim: set et: */ | |
| 2364 | + | |
| 2365 | +?> | ... | ... |
Smarty/debug.tpl
0 → 100644
| 1 | +{* Smarty *} | |
| 2 | +{* debug.tpl, last updated version 2.1.0 *} | |
| 3 | +{assign_debug_info} | |
| 4 | +{capture assign=debug_output} | |
| 5 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | |
| 6 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> | |
| 7 | +<head> | |
| 8 | + <title>Smarty Debug Console</title> | |
| 9 | +{literal} | |
| 10 | +<style type="text/css"> | |
| 11 | +/* <![CDATA[ */ | |
| 12 | +body, h1, h2, td, th, p { | |
| 13 | + font-family: sans-serif; | |
| 14 | + font-weight: normal; | |
| 15 | + font-size: 0.9em; | |
| 16 | + margin: 1px; | |
| 17 | + padding: 0; | |
| 18 | +} | |
| 19 | + | |
| 20 | +h1 { | |
| 21 | + margin: 0; | |
| 22 | + text-align: left; | |
| 23 | + padding: 2px; | |
| 24 | + background-color: #f0c040; | |
| 25 | + color: black; | |
| 26 | + font-weight: bold; | |
| 27 | + font-size: 1.2em; | |
| 28 | + } | |
| 29 | + | |
| 30 | +h2 { | |
| 31 | + background-color: #9B410E; | |
| 32 | + color: white; | |
| 33 | + text-align: left; | |
| 34 | + font-weight: bold; | |
| 35 | + padding: 2px; | |
| 36 | + border-top: 1px solid black; | |
| 37 | +} | |
| 38 | + | |
| 39 | +body { | |
| 40 | + background: black; | |
| 41 | +} | |
| 42 | + | |
| 43 | +p, table, div { | |
| 44 | + background: #f0ead8; | |
| 45 | +} | |
| 46 | + | |
| 47 | +p { | |
| 48 | + margin: 0; | |
| 49 | + font-style: italic; | |
| 50 | + text-align: center; | |
| 51 | +} | |
| 52 | + | |
| 53 | +table { | |
| 54 | + width: 100%; | |
| 55 | +} | |
| 56 | + | |
| 57 | +th, td { | |
| 58 | + font-family: monospace; | |
| 59 | + vertical-align: top; | |
| 60 | + text-align: left; | |
| 61 | + width: 50%; | |
| 62 | +} | |
| 63 | + | |
| 64 | +td { | |
| 65 | + color: green; | |
| 66 | +} | |
| 67 | + | |
| 68 | +.odd { | |
| 69 | + background-color: #eeeeee; | |
| 70 | +} | |
| 71 | + | |
| 72 | +.even { | |
| 73 | + background-color: #fafafa; | |
| 74 | +} | |
| 75 | + | |
| 76 | +.exectime { | |
| 77 | + font-size: 0.8em; | |
| 78 | + font-style: italic; | |
| 79 | +} | |
| 80 | + | |
| 81 | +#table_assigned_vars th { | |
| 82 | + color: blue; | |
| 83 | +} | |
| 84 | + | |
| 85 | +#table_config_vars th { | |
| 86 | + color: maroon; | |
| 87 | +} | |
| 88 | +/* ]]> */ | |
| 89 | +</style> | |
| 90 | +{/literal} | |
| 91 | +</head> | |
| 92 | +<body> | |
| 93 | + | |
| 94 | +<h1>Smarty Debug Console</h1> | |
| 95 | + | |
| 96 | +<h2>included templates & config files (load time in seconds)</h2> | |
| 97 | + | |
| 98 | +<div> | |
| 99 | +{section name=templates loop=$_debug_tpls} | |
| 100 | + {section name=indent loop=$_debug_tpls[templates].depth} {/section} | |
| 101 | + <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}> | |
| 102 | + {$_debug_tpls[templates].filename|escape:html}</font> | |
| 103 | + {if isset($_debug_tpls[templates].exec_time)} | |
| 104 | + <span class="exectime"> | |
| 105 | + ({$_debug_tpls[templates].exec_time|string_format:"%.5f"}) | |
| 106 | + {if %templates.index% eq 0}(total){/if} | |
| 107 | + </span> | |
| 108 | + {/if} | |
| 109 | + <br /> | |
| 110 | +{sectionelse} | |
| 111 | + <p>no templates included</p> | |
| 112 | +{/section} | |
| 113 | +</div> | |
| 114 | + | |
| 115 | +<h2>assigned template variables</h2> | |
| 116 | + | |
| 117 | +<table id="table_assigned_vars"> | |
| 118 | + {section name=vars loop=$_debug_keys} | |
| 119 | + <tr class="{cycle values="odd,even"}"> | |
| 120 | + <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th> | |
| 121 | + <td>{$_debug_vals[vars]|@debug_print_var}</td></tr> | |
| 122 | + {sectionelse} | |
| 123 | + <tr><td><p>no template variables assigned</p></td></tr> | |
| 124 | + {/section} | |
| 125 | +</table> | |
| 126 | + | |
| 127 | +<h2>assigned config file variables (outer template scope)</h2> | |
| 128 | + | |
| 129 | +<table id="table_config_vars"> | |
| 130 | + {section name=config_vars loop=$_debug_config_keys} | |
| 131 | + <tr class="{cycle values="odd,even"}"> | |
| 132 | + <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th> | |
| 133 | + <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr> | |
| 134 | + {sectionelse} | |
| 135 | + <tr><td><p>no config vars assigned</p></td></tr> | |
| 136 | + {/section} | |
| 137 | +</table> | |
| 138 | +</body> | |
| 139 | +</html> | |
| 140 | +{/capture} | |
| 141 | +{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"} | |
| 142 | + {$debug_output} | |
| 143 | +{else} | |
| 144 | +<script type="text/javascript"> | |
| 145 | +// <![CDATA[ | |
| 146 | + if ( self.name == '' ) {ldelim} | |
| 147 | + var title = 'Console'; | |
| 148 | + {rdelim} | |
| 149 | + else {ldelim} | |
| 150 | + var title = 'Console_' + self.name; | |
| 151 | + {rdelim} | |
| 152 | + _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes"); | |
| 153 | + _smarty_console.document.write('{$debug_output|escape:'javascript'}'); | |
| 154 | + _smarty_console.document.close(); | |
| 155 | +// ]]> | |
| 156 | +</script> | |
| 157 | +{/if} | |
| \ No newline at end of file | ... | ... |
Please
register
or
login
to post a comment