4 * Smarty Internal Plugin CompileBase
12 * This class does extend all internal compile plugins
14 // abstract class Smarty_Internal_CompileBase implements TagCompilerInterface
15 class Smarty_Internal_CompileBase {
16 public $required_attributes = array();
17 public $optional_attributes = array();
18 public $shorttag_order = array();
19 public $option_flags = array('nocache');
23 * This function checks if the attributes passed are valid
25 * The attributes passed for the tag to compile are checked against the list of required and
26 * optional attributes. Required attributes must be present. Optional attributes are check against
27 * against the corresponding list. The keyword '_any' specifies that any attribute will be accepted
30 * @param array $attributes attributes applied to the tag
31 * @return array of mapped attributes for further processing
33 function _get_attributes ($attributes)
35 $_indexed_attr = array();
36 // loop over attributes
37 foreach ($attributes as $key => $mixed) {
39 if (!is_array($mixed)) {
41 if (in_array(trim($mixed, '\'"'), $this->option_flags)) {
42 $_indexed_attr[trim($mixed, '\'"')] = true;
43 // shorthand attribute ?
44 } else if (isset($this->shorttag_order[$key])) {
45 $_indexed_attr[$this->shorttag_order[$key]] = $mixed;
47 // too many shorthands
48 $this->compiler->trigger_template_error('too many shorthand attributes', $this->compiler->lex->taglineno);
54 if (in_array($kv['key'], $this->option_flags)) {
55 if (is_bool($kv['value'])) {
56 $_indexed_attr[$kv['key']] = $kv['value'];
57 } else if (is_string($kv['value']) && in_array(trim($kv['value'], '\'"'), array('true', 'false'))) {
58 if (trim($kv['value']) == 'true') {
59 $_indexed_attr[$kv['key']] = true;
61 $_indexed_attr[$kv['key']] = false;
63 } else if (is_numeric($kv['value']) && in_array($kv['value'], array(0, 1))) {
64 if ($kv['value'] == 1) {
65 $_indexed_attr[$kv['key']] = true;
67 $_indexed_attr[$kv['key']] = false;
70 $this->compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", $this->compiler->lex->taglineno);
72 // must be named attribute
75 $_indexed_attr[key($mixed)] = $mixed[key($mixed)];
79 // check if all required attributes present
80 foreach ($this->required_attributes as $attr) {
81 if (!array_key_exists($attr, $_indexed_attr)) {
82 $this->compiler->trigger_template_error("missing \"" . $attr . "\" attribute", $this->compiler->lex->taglineno);
85 // check for unallowed attributes
86 if ($this->optional_attributes != array('_any')) {
87 $tmp_array = array_merge($this->required_attributes, $this->optional_attributes, $this->option_flags);
88 foreach ($_indexed_attr as $key => $dummy) {
89 if (!in_array($key, $tmp_array) && $key !== 0) {
90 $this->compiler->trigger_template_error("unexpected \"" . $key . "\" attribute", $this->compiler->lex->taglineno);
94 // default 'false' for all option flags not set
95 foreach ($this->option_flags as $flag) {
96 if (!isset($_indexed_attr[$flag])) {
97 $_indexed_attr[$flag] = false;
101 return $_indexed_attr;
105 * Push opening tag name on stack
107 * Optionally additional data can be saved on stack
109 * @param string $open_tag the opening tag's name
110 * @param anytype $data optional data which shall be saved on stack
112 function _open_tag($open_tag, $data = null)
114 array_push($this->compiler->_tag_stack, array($open_tag, $data));
120 * Raise an error if this stack-top doesn't match with expected opening tags
122 * @param array $ |string $expected_tag the expected opening tag names
123 * @return anytype the opening tag's name or saved data
125 function _close_tag($expected_tag)
127 if (count($this->compiler->_tag_stack) > 0) {
129 list($_open_tag, $_data) = array_pop($this->compiler->_tag_stack);
130 // open tag must match with the expected ones
131 if (in_array($_open_tag, (array)$expected_tag)) {
132 if (is_null($_data)) {
133 // return opening tag
136 // return restored data
140 // wrong nesting of tags
141 $this->compiler->trigger_template_error("unclosed {" . $_open_tag . "} tag");
144 // wrong nesting of tags
145 $this->compiler->trigger_template_error("unexpected closing tag", $this->compiler->lex->taglineno);