You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

smarty_internal_compilebase.php 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. /**
  3. * Smarty Internal Plugin CompileBase
  4. *
  5. * @package Smarty
  6. * @subpackage Compiler
  7. * @author Uwe Tews
  8. */
  9. /**
  10. * This class does extend all internal compile plugins
  11. *
  12. * @package Smarty
  13. * @subpackage Compiler
  14. */
  15. abstract class Smarty_Internal_CompileBase
  16. {
  17. /**
  18. * Array of names of required attribute required by tag
  19. *
  20. * @var array
  21. */
  22. public $required_attributes = array();
  23. /**
  24. * Array of names of optional attribute required by tag
  25. * use array('_any') if there is no restriction of attributes names
  26. *
  27. * @var array
  28. */
  29. public $optional_attributes = array();
  30. /**
  31. * Shorttag attribute order defined by its names
  32. *
  33. * @var array
  34. */
  35. public $shorttag_order = array();
  36. /**
  37. * Array of names of valid option flags
  38. *
  39. * @var array
  40. */
  41. public $option_flags = array('nocache');
  42. /**
  43. * This function checks if the attributes passed are valid
  44. * The attributes passed for the tag to compile are checked against the list of required and
  45. * optional attributes. Required attributes must be present. Optional attributes are check against
  46. * the corresponding list. The keyword '_any' specifies that any attribute will be accepted
  47. * as valid
  48. *
  49. * @param object $compiler compiler object
  50. * @param array $attributes attributes applied to the tag
  51. *
  52. * @return array of mapped attributes for further processing
  53. */
  54. public function getAttributes($compiler, $attributes)
  55. {
  56. $_indexed_attr = array();
  57. // loop over attributes
  58. foreach ($attributes as $key => $mixed) {
  59. // shorthand ?
  60. if (!is_array($mixed)) {
  61. // option flag ?
  62. if (in_array(trim($mixed, '\'"'), $this->option_flags)) {
  63. $_indexed_attr[trim($mixed, '\'"')] = true;
  64. // shorthand attribute ?
  65. } elseif (isset($this->shorttag_order[$key])) {
  66. $_indexed_attr[$this->shorttag_order[$key]] = $mixed;
  67. } else {
  68. // too many shorthands
  69. $compiler->trigger_template_error('too many shorthand attributes', null, true);
  70. }
  71. // named attribute
  72. } else {
  73. $kv = each($mixed);
  74. // option flag?
  75. if (in_array($kv['key'], $this->option_flags)) {
  76. if (is_bool($kv['value'])) {
  77. $_indexed_attr[$kv['key']] = $kv['value'];
  78. } elseif (is_string($kv['value']) && in_array(trim($kv['value'], '\'"'), array('true', 'false'))) {
  79. if (trim($kv['value']) == 'true') {
  80. $_indexed_attr[$kv['key']] = true;
  81. } else {
  82. $_indexed_attr[$kv['key']] = false;
  83. }
  84. } elseif (is_numeric($kv['value']) && in_array($kv['value'], array(0, 1))) {
  85. if ($kv['value'] == 1) {
  86. $_indexed_attr[$kv['key']] = true;
  87. } else {
  88. $_indexed_attr[$kv['key']] = false;
  89. }
  90. } else {
  91. $compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", null, true);
  92. }
  93. // must be named attribute
  94. } else {
  95. reset($mixed);
  96. $_indexed_attr[key($mixed)] = $mixed[key($mixed)];
  97. }
  98. }
  99. }
  100. // check if all required attributes present
  101. foreach ($this->required_attributes as $attr) {
  102. if (!array_key_exists($attr, $_indexed_attr)) {
  103. $compiler->trigger_template_error("missing \"" . $attr . "\" attribute", null, true);
  104. }
  105. }
  106. // check for not allowed attributes
  107. if ($this->optional_attributes != array('_any')) {
  108. $tmp_array = array_merge($this->required_attributes, $this->optional_attributes, $this->option_flags);
  109. foreach ($_indexed_attr as $key => $dummy) {
  110. if (!in_array($key, $tmp_array) && $key !== 0) {
  111. $compiler->trigger_template_error("unexpected \"" . $key . "\" attribute", null, true);
  112. }
  113. }
  114. }
  115. // default 'false' for all option flags not set
  116. foreach ($this->option_flags as $flag) {
  117. if (!isset($_indexed_attr[$flag])) {
  118. $_indexed_attr[$flag] = false;
  119. }
  120. }
  121. return $_indexed_attr;
  122. }
  123. /**
  124. * Push opening tag name on stack
  125. * Optionally additional data can be saved on stack
  126. *
  127. * @param object $compiler compiler object
  128. * @param string $openTag the opening tag's name
  129. * @param mixed $data optional data saved
  130. */
  131. public function openTag($compiler, $openTag, $data = null)
  132. {
  133. array_push($compiler->_tag_stack, array($openTag, $data));
  134. }
  135. /**
  136. * Pop closing tag
  137. * Raise an error if this stack-top doesn't match with expected opening tags
  138. *
  139. * @param object $compiler compiler object
  140. * @param array|string $expectedTag the expected opening tag names
  141. *
  142. * @return mixed any type the opening tag's name or saved data
  143. */
  144. public function closeTag($compiler, $expectedTag)
  145. {
  146. if (count($compiler->_tag_stack) > 0) {
  147. // get stacked info
  148. list($_openTag, $_data) = array_pop($compiler->_tag_stack);
  149. // open tag must match with the expected ones
  150. if (in_array($_openTag, (array) $expectedTag)) {
  151. if (is_null($_data)) {
  152. // return opening tag
  153. return $_openTag;
  154. } else {
  155. // return restored data
  156. return $_data;
  157. }
  158. }
  159. // wrong nesting of tags
  160. $compiler->trigger_template_error("unclosed {$compiler->smarty->left_delimiter}" . $_openTag .
  161. "{$compiler->smarty->right_delimiter} tag");
  162. return;
  163. }
  164. // wrong nesting of tags
  165. $compiler->trigger_template_error("unexpected closing tag", null, true);
  166. return;
  167. }
  168. }