Initial repo created
[timetracker.git] / WEB-INF / lib / smarty / sysplugins / smarty_internal_compilebase.php
1 <?php
2
3 /**
4  * Smarty Internal Plugin CompileBase
5  * 
6  * @package Smarty
7  * @subpackage Compiler
8  * @author Uwe Tews 
9  */
10
11 /**
12  * This class does extend all internal compile plugins
13  */
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');
20
21
22     /**
23      * This function checks if the attributes passed are valid
24      * 
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 
28      * as valid
29      * 
30      * @param array $attributes attributes applied to the tag
31      * @return array of mapped attributes for further processing
32      */
33     function _get_attributes ($attributes)
34     {
35         $_indexed_attr = array(); 
36         // loop over attributes
37         foreach ($attributes as $key => $mixed) {
38             // shorthand ?
39             if (!is_array($mixed)) {
40                 // option flag ?
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;
46                 } else {
47                     // too many shorthands
48                     $this->compiler->trigger_template_error('too many shorthand attributes', $this->compiler->lex->taglineno);
49                 } 
50                 // named attribute
51             } else {
52                 $kv = each($mixed); 
53                 // option flag?
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;
60                         } else {
61                             $_indexed_attr[$kv['key']] = false;
62                         } 
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;
66                         } else {
67                             $_indexed_attr[$kv['key']] = false;
68                         } 
69                     } else {
70                         $this->compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", $this->compiler->lex->taglineno);
71                     } 
72                     // must be named attribute
73                 } else {
74                         reset($mixed);
75                     $_indexed_attr[key($mixed)] = $mixed[key($mixed)];
76                 } 
77             } 
78         } 
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);
83             } 
84         } 
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);
91                 } 
92             } 
93         } 
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;
98             } 
99         } 
100
101         return $_indexed_attr;
102     } 
103
104     /**
105      * Push opening tag name on stack
106      * 
107      * Optionally additional data can be saved on stack
108      * 
109      * @param string $open_tag the opening tag's name
110      * @param anytype $data optional data which shall be saved on stack
111      */
112     function _open_tag($open_tag, $data = null)
113     {
114         array_push($this->compiler->_tag_stack, array($open_tag, $data));
115     } 
116
117     /**
118      * Pop closing tag
119      * 
120      * Raise an error if this stack-top doesn't match with expected opening tags
121      * 
122      * @param array $ |string $expected_tag the expected opening tag names
123      * @return anytype the opening tag's name or saved data
124      */
125     function _close_tag($expected_tag)
126     {
127         if (count($this->compiler->_tag_stack) > 0) {
128             // get stacked info
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
134                     return $_open_tag;
135                 } else {
136                     // return restored data
137                     return $_data;
138                 } 
139             } 
140             // wrong nesting of tags
141             $this->compiler->trigger_template_error("unclosed {" . $_open_tag . "} tag");
142             return;
143         } 
144         // wrong nesting of tags
145         $this->compiler->trigger_template_error("unexpected closing tag", $this->compiler->lex->taglineno);
146         return;
147     } 
148
149
150 ?>