added new object support without new template syntax

This commit is contained in:
mohrt
2003-01-17 23:54:29 +00:00
parent 6eafc9f600
commit 3177db30d6
5 changed files with 163 additions and 93 deletions

2
NEWS
View File

@@ -1,3 +1,4 @@
- added support for object method access (Monte)
- fixed bug with directories named '0' (Frank Bauer, Monte) - fixed bug with directories named '0' (Frank Bauer, Monte)
- add javascript parameter to escape modifier (Monte) - add javascript parameter to escape modifier (Monte)
- added correct line numbers to syntax error messages - added correct line numbers to syntax error messages
@@ -9,7 +10,6 @@
- can now pass modifiers to static content (Monte) - can now pass modifiers to static content (Monte)
- fix up regex code in compiler, more flexible and - fix up regex code in compiler, more flexible and
maintainable (Monte) maintainable (Monte)
- added support for object method access (Monte)
- added day_value_format to html_select_date (Marcus - added day_value_format to html_select_date (Marcus
Bointon, Monte) Bointon, Monte)
- assigned variables are no longer in global - assigned variables are no longer in global

View File

@@ -191,8 +191,9 @@ class Smarty
var $_smarty_debug_id = 'SMARTY_DEBUG'; // text in URL to enable debug mode var $_smarty_debug_id = 'SMARTY_DEBUG'; // text in URL to enable debug mode
var $_smarty_debug_info = array(); // debugging information for debug console var $_smarty_debug_info = array(); // debugging information for debug console
var $_cache_info = array(); // info that makes up a cache file var $_cache_info = array(); // info that makes up a cache file
var $_file_perms = 0644; // default file permissions var $_file_perms = 0644; // default file permissions
var $_dir_perms = 0771; // default dir permissions var $_dir_perms = 0771; // default dir permissions
var $_object_wrapper = false; // default object params structure
var $_plugins = array( // table keeping track of plugins var $_plugins = array( // table keeping track of plugins
'modifier' => array(), 'modifier' => array(),
'function' => array(), 'function' => array(),

View File

@@ -64,8 +64,6 @@ class Smarty_Compiler extends Smarty {
var $_parenth_param_regexp = null; var $_parenth_param_regexp = null;
var $_func_call_regexp = null; var $_func_call_regexp = null;
var $_obj_call_regexp = null; var $_obj_call_regexp = null;
/*======================================================================*\ /*======================================================================*\
Function: Smarty_Compiler() Function: Smarty_Compiler()
@@ -165,7 +163,7 @@ class Smarty_Compiler extends Smarty {
// #foo#|bar // #foo#|bar
// "text" // "text"
// "text"|bar // "text"|bar
// $foo->bar() // $foo->bar
$this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
. $this->_var_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; . $this->_var_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
@@ -367,14 +365,18 @@ class Smarty_Compiler extends Smarty {
} }
$tag_command = $match[1]; $tag_command = $match[1];
$tag_modifier = isset($match[2]) ? $match[2] : ''; $tag_modifier = isset($match[2]) ? $match[2] : null;
$tag_args = isset($match[3]) ? $match[3] : ''; $tag_args = isset($match[3]) ? $match[3] : null;
/* If the tag name is not a function, we process it. */ /* If the tag name is not a function, we process it. */
if (!preg_match('!^\/?' . $this->_func_regexp . '$!', $tag_command)) { if (!preg_match('!^\/?' . $this->_func_regexp . '$!', $tag_command)) {
$return = $this->_parse_var_props($tag_command . $tag_modifier); $_tag_attrs = $this->_parse_attrs($tag_args);
return "<?php echo $return; ?>\n"; $return = $this->_parse_var_props($tag_command . $tag_modifier, $_tag_attrs);
if(isset($_tag_attrs['assign'])) {
return "<?php \$this->assign('" . $this->_dequote($_tag_attrs['assign']) . "', $return ); ?>\n";
} else {
return "<?php echo $return; ?>\n";
}
} }
switch ($tag_command) { switch ($tag_command) {
@@ -1212,7 +1214,7 @@ class Smarty_Compiler extends Smarty {
if ($token == '=') { if ($token == '=') {
$state = 2; $state = 2;
} else } else
$this->_syntax_error("expecting '=' after attribute name", E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
break; break;
case 2: case 2:
@@ -1237,8 +1239,17 @@ class Smarty_Compiler extends Smarty {
$this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
break; break;
} }
$last_token = $token;
} }
if($state != 0) {
if($state == 1) {
$this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
} else {
$this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
}
}
$this->_parse_vars_props($attrs); $this->_parse_vars_props($attrs);
return $attrs; return $attrs;
@@ -1261,14 +1272,14 @@ class Smarty_Compiler extends Smarty {
Purpose: compile single variable and section properties token into Purpose: compile single variable and section properties token into
PHP code PHP code
\*======================================================================*/ \*======================================================================*/
function _parse_var_props($val) function _parse_var_props($val, $tag_attrs = null)
{ {
$val = trim($val); $val = trim($val);
if(preg_match('!^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(?:' . $this->_mod_regexp . '*)$!', $val)) { if(preg_match('!^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(?:' . $this->_mod_regexp . '*)$!', $val)) {
// $ variable or object // $ variable or object
return $this->_parse_var($val); return $this->_parse_var($val, $tag_attrs);
} }
elseif(preg_match('!^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) { elseif(preg_match('!^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {
// double quoted text // double quoted text
@@ -1325,9 +1336,9 @@ class Smarty_Compiler extends Smarty {
Function: _parse_var Function: _parse_var
Purpose: parse variable expression into PHP code Purpose: parse variable expression into PHP code
\*======================================================================*/ \*======================================================================*/
function _parse_var($var_expr) function _parse_var($var_expr, $tag_attrs = null)
{ {
preg_match('!(' . $this->_obj_call_regexp . '|' . $this->_var_regexp . ')(' . $this->_mod_regexp . '*)$!', $var_expr, $match); preg_match('!(' . $this->_obj_call_regexp . '|' . $this->_var_regexp . ')(' . $this->_mod_regexp . '*)$!', $var_expr, $match);
$var_ref = substr($match[1],1); $var_ref = substr($match[1],1);
@@ -1360,9 +1371,8 @@ class Smarty_Compiler extends Smarty {
} else { } else {
$output = "\$this->_tpl_vars['$var_name']"; $output = "\$this->_tpl_vars['$var_name']";
} }
foreach ($indexes as $index) { foreach ($indexes as $index) {
if ($index{0} == '[') { if ($index{0} == '[') {
$index = substr($index, 1, -1); $index = substr($index, 1, -1);
if (is_numeric($index)) { if (is_numeric($index)) {
@@ -1376,18 +1386,58 @@ class Smarty_Compiler extends Smarty {
$output .= "[\$this->_sections['$section']['$section_prop']]"; $output .= "[\$this->_sections['$section']['$section_prop']]";
} }
} else if ($index{0} == '.') { } else if ($index{0} == '.') {
if ($index{1} == '$') // figure out if reference to array or object
if ($index{1} == '$') {
// array reference
$output .= "[\$this->_tpl_vars['" . substr($index, 2) . "']]"; $output .= "[\$this->_tpl_vars['" . substr($index, 2) . "']]";
else } else if (!preg_match('!^\w+$!', substr($index, 1))) {
// array reference
$output .= "['" . substr($index, 1) . "']"; $output .= "['" . substr($index, 1) . "']";
} else {
if(eval("return is_object($output);")) {
// is object
if($this->security && substr($index, 1, 1) == '_') {
$this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
}
if(eval("return method_exists($output,'" . substr($index,1) . "');")) {
// object method reference
// parse parameters
if(isset($tag_attrs)) {
if(isset($tag_attrs['wrapper'])) {
$_object_wrapper = $tag_attrs['wrapper'];
unset($tag_attrs['wrapper']);
} else {
$_object_wrapper = $this->_object_wrapper;
}
if(isset($tag_attrs['assign'])) {
unset($tag_attrs['assign']);
}
if(!$_object_wrapper) {
// pass args as associative array
$index .= '(array(' . implode(',' , $tag_attrs) . '), $this)';
} else {
// pass args as separate parameters
$index .= '(' . implode(',' , array_values($tag_attrs)) . ')';
}
} else {
// no args for method
$index .= '()';
}
$output .= '->' . substr($index, 1);
} else {
// object property reference
$output .= "->" . substr($index, 1);
}
} else {
// array reference
$output .= "['" . substr($index, 1) . "']";
}
}
} else if (substr($index,0,2) == '->') { } else if (substr($index,0,2) == '->') {
if($this->security && substr($index,2,1) == '_') { // object property reference syntax (deprecated)
if($this->security && strstr($index, '->_')) {
$this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
} else { } else {
// parse each parameter to the object
if(preg_match('!(?:\->\w+)+(?:(' . $this->_parenth_param_regexp . '))?!', $index, $match)) {
$index = str_replace($match[1], $this->_parse_parenth_args($match[1]), $index);
}
$output .= $index; $output .= $index;
} }
} else { } else {
@@ -1401,25 +1451,9 @@ class Smarty_Compiler extends Smarty {
} }
$this->_parse_modifiers($output, $modifiers); $this->_parse_modifiers($output, $modifiers);
return $output; return $output;
} }
/*======================================================================*\
Function: _parse_parenth_args
Purpose: parse arguments in function call parenthesis
\*======================================================================*/
function _parse_parenth_args($parenth_args)
{
preg_match_all('!' . $this->_param_regexp . '!',$parenth_args, $match);
$match = $match[0];
rsort($match);
reset($match);
$orig_vals = $match;
$this->_parse_vars_props($match);
return str_replace($orig_vals, $match, $parenth_args);
}
/*======================================================================*\ /*======================================================================*\
Function: _parse_conf_var Function: _parse_conf_var

View File

@@ -191,8 +191,9 @@ class Smarty
var $_smarty_debug_id = 'SMARTY_DEBUG'; // text in URL to enable debug mode var $_smarty_debug_id = 'SMARTY_DEBUG'; // text in URL to enable debug mode
var $_smarty_debug_info = array(); // debugging information for debug console var $_smarty_debug_info = array(); // debugging information for debug console
var $_cache_info = array(); // info that makes up a cache file var $_cache_info = array(); // info that makes up a cache file
var $_file_perms = 0644; // default file permissions var $_file_perms = 0644; // default file permissions
var $_dir_perms = 0771; // default dir permissions var $_dir_perms = 0771; // default dir permissions
var $_object_wrapper = false; // default object params structure
var $_plugins = array( // table keeping track of plugins var $_plugins = array( // table keeping track of plugins
'modifier' => array(), 'modifier' => array(),
'function' => array(), 'function' => array(),

View File

@@ -64,8 +64,6 @@ class Smarty_Compiler extends Smarty {
var $_parenth_param_regexp = null; var $_parenth_param_regexp = null;
var $_func_call_regexp = null; var $_func_call_regexp = null;
var $_obj_call_regexp = null; var $_obj_call_regexp = null;
/*======================================================================*\ /*======================================================================*\
Function: Smarty_Compiler() Function: Smarty_Compiler()
@@ -165,7 +163,7 @@ class Smarty_Compiler extends Smarty {
// #foo#|bar // #foo#|bar
// "text" // "text"
// "text"|bar // "text"|bar
// $foo->bar() // $foo->bar
$this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
. $this->_var_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; . $this->_var_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
@@ -367,14 +365,18 @@ class Smarty_Compiler extends Smarty {
} }
$tag_command = $match[1]; $tag_command = $match[1];
$tag_modifier = isset($match[2]) ? $match[2] : ''; $tag_modifier = isset($match[2]) ? $match[2] : null;
$tag_args = isset($match[3]) ? $match[3] : ''; $tag_args = isset($match[3]) ? $match[3] : null;
/* If the tag name is not a function, we process it. */ /* If the tag name is not a function, we process it. */
if (!preg_match('!^\/?' . $this->_func_regexp . '$!', $tag_command)) { if (!preg_match('!^\/?' . $this->_func_regexp . '$!', $tag_command)) {
$return = $this->_parse_var_props($tag_command . $tag_modifier); $_tag_attrs = $this->_parse_attrs($tag_args);
return "<?php echo $return; ?>\n"; $return = $this->_parse_var_props($tag_command . $tag_modifier, $_tag_attrs);
if(isset($_tag_attrs['assign'])) {
return "<?php \$this->assign('" . $this->_dequote($_tag_attrs['assign']) . "', $return ); ?>\n";
} else {
return "<?php echo $return; ?>\n";
}
} }
switch ($tag_command) { switch ($tag_command) {
@@ -1212,7 +1214,7 @@ class Smarty_Compiler extends Smarty {
if ($token == '=') { if ($token == '=') {
$state = 2; $state = 2;
} else } else
$this->_syntax_error("expecting '=' after attribute name", E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
break; break;
case 2: case 2:
@@ -1237,8 +1239,17 @@ class Smarty_Compiler extends Smarty {
$this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
break; break;
} }
$last_token = $token;
} }
if($state != 0) {
if($state == 1) {
$this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
} else {
$this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
}
}
$this->_parse_vars_props($attrs); $this->_parse_vars_props($attrs);
return $attrs; return $attrs;
@@ -1261,14 +1272,14 @@ class Smarty_Compiler extends Smarty {
Purpose: compile single variable and section properties token into Purpose: compile single variable and section properties token into
PHP code PHP code
\*======================================================================*/ \*======================================================================*/
function _parse_var_props($val) function _parse_var_props($val, $tag_attrs = null)
{ {
$val = trim($val); $val = trim($val);
if(preg_match('!^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(?:' . $this->_mod_regexp . '*)$!', $val)) { if(preg_match('!^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(?:' . $this->_mod_regexp . '*)$!', $val)) {
// $ variable or object // $ variable or object
return $this->_parse_var($val); return $this->_parse_var($val, $tag_attrs);
} }
elseif(preg_match('!^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) { elseif(preg_match('!^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {
// double quoted text // double quoted text
@@ -1325,9 +1336,9 @@ class Smarty_Compiler extends Smarty {
Function: _parse_var Function: _parse_var
Purpose: parse variable expression into PHP code Purpose: parse variable expression into PHP code
\*======================================================================*/ \*======================================================================*/
function _parse_var($var_expr) function _parse_var($var_expr, $tag_attrs = null)
{ {
preg_match('!(' . $this->_obj_call_regexp . '|' . $this->_var_regexp . ')(' . $this->_mod_regexp . '*)$!', $var_expr, $match); preg_match('!(' . $this->_obj_call_regexp . '|' . $this->_var_regexp . ')(' . $this->_mod_regexp . '*)$!', $var_expr, $match);
$var_ref = substr($match[1],1); $var_ref = substr($match[1],1);
@@ -1360,9 +1371,8 @@ class Smarty_Compiler extends Smarty {
} else { } else {
$output = "\$this->_tpl_vars['$var_name']"; $output = "\$this->_tpl_vars['$var_name']";
} }
foreach ($indexes as $index) { foreach ($indexes as $index) {
if ($index{0} == '[') { if ($index{0} == '[') {
$index = substr($index, 1, -1); $index = substr($index, 1, -1);
if (is_numeric($index)) { if (is_numeric($index)) {
@@ -1376,18 +1386,58 @@ class Smarty_Compiler extends Smarty {
$output .= "[\$this->_sections['$section']['$section_prop']]"; $output .= "[\$this->_sections['$section']['$section_prop']]";
} }
} else if ($index{0} == '.') { } else if ($index{0} == '.') {
if ($index{1} == '$') // figure out if reference to array or object
if ($index{1} == '$') {
// array reference
$output .= "[\$this->_tpl_vars['" . substr($index, 2) . "']]"; $output .= "[\$this->_tpl_vars['" . substr($index, 2) . "']]";
else } else if (!preg_match('!^\w+$!', substr($index, 1))) {
// array reference
$output .= "['" . substr($index, 1) . "']"; $output .= "['" . substr($index, 1) . "']";
} else {
if(eval("return is_object($output);")) {
// is object
if($this->security && substr($index, 1, 1) == '_') {
$this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
}
if(eval("return method_exists($output,'" . substr($index,1) . "');")) {
// object method reference
// parse parameters
if(isset($tag_attrs)) {
if(isset($tag_attrs['wrapper'])) {
$_object_wrapper = $tag_attrs['wrapper'];
unset($tag_attrs['wrapper']);
} else {
$_object_wrapper = $this->_object_wrapper;
}
if(isset($tag_attrs['assign'])) {
unset($tag_attrs['assign']);
}
if(!$_object_wrapper) {
// pass args as associative array
$index .= '(array(' . implode(',' , $tag_attrs) . '), $this)';
} else {
// pass args as separate parameters
$index .= '(' . implode(',' , array_values($tag_attrs)) . ')';
}
} else {
// no args for method
$index .= '()';
}
$output .= '->' . substr($index, 1);
} else {
// object property reference
$output .= "->" . substr($index, 1);
}
} else {
// array reference
$output .= "['" . substr($index, 1) . "']";
}
}
} else if (substr($index,0,2) == '->') { } else if (substr($index,0,2) == '->') {
if($this->security && substr($index,2,1) == '_') { // object property reference syntax (deprecated)
if($this->security && strstr($index, '->_')) {
$this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
} else { } else {
// parse each parameter to the object
if(preg_match('!(?:\->\w+)+(?:(' . $this->_parenth_param_regexp . '))?!', $index, $match)) {
$index = str_replace($match[1], $this->_parse_parenth_args($match[1]), $index);
}
$output .= $index; $output .= $index;
} }
} else { } else {
@@ -1401,25 +1451,9 @@ class Smarty_Compiler extends Smarty {
} }
$this->_parse_modifiers($output, $modifiers); $this->_parse_modifiers($output, $modifiers);
return $output; return $output;
} }
/*======================================================================*\
Function: _parse_parenth_args
Purpose: parse arguments in function call parenthesis
\*======================================================================*/
function _parse_parenth_args($parenth_args)
{
preg_match_all('!' . $this->_param_regexp . '!',$parenth_args, $match);
$match = $match[0];
rsort($match);
reset($match);
$orig_vals = $match;
$this->_parse_vars_props($match);
return str_replace($orig_vals, $match, $parenth_args);
}
/*======================================================================*\ /*======================================================================*\
Function: _parse_conf_var Function: _parse_conf_var