Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

smarty_internal_compile_private_php.php 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /**
  3. * Smarty Internal Plugin Compile PHP Expression
  4. * Compiles any tag which will output an expression or variable
  5. *
  6. * @package Smarty
  7. * @subpackage Compiler
  8. * @author Uwe Tews
  9. */
  10. /**
  11. * Smarty Internal Plugin Compile PHP Expression Class
  12. *
  13. * @package Smarty
  14. * @subpackage Compiler
  15. */
  16. class Smarty_Internal_Compile_Private_Php extends Smarty_Internal_CompileBase
  17. {
  18. /**
  19. * Attribute definition: Overwrites base class.
  20. *
  21. * @var array
  22. * @see Smarty_Internal_CompileBase
  23. */
  24. public $required_attributes = array('code', 'type');
  25. /**
  26. * Compiles code for generating output from any expression
  27. *
  28. * @param array $args array with attributes from parser
  29. * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
  30. * @param array $parameter array with compilation parameter
  31. *
  32. * @return string
  33. * @throws \SmartyException
  34. */
  35. public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
  36. {
  37. // check and get attributes
  38. $_attr = $this->getAttributes($compiler, $args);
  39. $compiler->has_code = false;
  40. if ($_attr[ 'type' ] === 'xml') {
  41. $compiler->tag_nocache = true;
  42. $output = addcslashes($_attr[ 'code' ], "'\\");
  43. $compiler->parser->current_buffer->append_subtree($compiler->parser,
  44. new Smarty_Internal_ParseTree_Tag($compiler->parser,
  45. $compiler->processNocacheCode("<?php echo '{$output}';?>",
  46. true)));
  47. return '';
  48. }
  49. if ($_attr[ 'type' ] !== 'tag') {
  50. if ($compiler->php_handling === Smarty::PHP_REMOVE) {
  51. return '';
  52. } elseif ($compiler->php_handling === Smarty::PHP_QUOTE) {
  53. $output =
  54. preg_replace_callback('#(<\?(?:php|=)?)|(<%)|(<script\s+language\s*=\s*["\']?\s*php\s*["\']?\s*>)|(\?>)|(%>)|(<\/script>)#i',
  55. array($this, 'quote'), $_attr[ 'code' ]);
  56. $compiler->parser->current_buffer->append_subtree($compiler->parser,
  57. new Smarty_Internal_ParseTree_Text($output));
  58. return '';
  59. } elseif ($compiler->php_handling === Smarty::PHP_PASSTHRU || $_attr[ 'type' ] === 'unmatched') {
  60. $compiler->tag_nocache = true;
  61. $output = addcslashes($_attr[ 'code' ], "'\\");
  62. $compiler->parser->current_buffer->append_subtree($compiler->parser,
  63. new Smarty_Internal_ParseTree_Tag($compiler->parser,
  64. $compiler->processNocacheCode("<?php echo '{$output}';?>",
  65. true)));
  66. return '';
  67. } elseif ($compiler->php_handling === Smarty::PHP_ALLOW) {
  68. if (!($compiler->smarty instanceof SmartyBC)) {
  69. $compiler->trigger_template_error('$smarty->php_handling PHP_ALLOW not allowed. Use SmartyBC to enable it',
  70. null, true);
  71. }
  72. $compiler->has_code = true;
  73. return $_attr[ 'code' ];
  74. } else {
  75. $compiler->trigger_template_error('Illegal $smarty->php_handling value', null, true);
  76. }
  77. } else {
  78. $compiler->has_code = true;
  79. if (!($compiler->smarty instanceof SmartyBC)) {
  80. $compiler->trigger_template_error('{php}{/php} tags not allowed. Use SmartyBC to enable them', null,
  81. true);
  82. }
  83. $ldel = preg_quote($compiler->smarty->left_delimiter, '#');
  84. $rdel = preg_quote($compiler->smarty->right_delimiter, '#');
  85. preg_match("#^({$ldel}php\\s*)((.)*?)({$rdel})#", $_attr[ 'code' ], $match);
  86. if (!empty($match[ 2 ])) {
  87. if ('nocache' === trim($match[ 2 ])) {
  88. $compiler->tag_nocache = true;
  89. } else {
  90. $compiler->trigger_template_error("illegal value of option flag '{$match[2]}'", null, true);
  91. }
  92. }
  93. return preg_replace(array("#^{$ldel}\\s*php\\s*(.)*?{$rdel}#", "#{$ldel}\\s*/\\s*php\\s*{$rdel}$#"),
  94. array('<?php ', '?>'), $_attr[ 'code' ]);
  95. }
  96. }
  97. /**
  98. * Lexer code for PHP tags
  99. *
  100. * This code has been moved from lexer here fo easier debugging and maintenance
  101. *
  102. * @param Smarty_Internal_Templatelexer $lex
  103. *
  104. * @throws \SmartyCompilerException
  105. */
  106. public function parsePhp(Smarty_Internal_Templatelexer $lex)
  107. {
  108. $lex->token = Smarty_Internal_Templateparser::TP_PHP;
  109. $close = 0;
  110. $lex->taglineno = $lex->line;
  111. $closeTag = '?>';
  112. if (strpos($lex->value, '<?xml') === 0) {
  113. $lex->is_xml = true;
  114. $lex->phpType = 'xml';
  115. return;
  116. } elseif (strpos($lex->value, '<?') === 0) {
  117. $lex->phpType = 'php';
  118. } elseif (strpos($lex->value, '<%') === 0) {
  119. $lex->phpType = 'asp';
  120. $closeTag = '%>';
  121. } elseif (strpos($lex->value, '%>') === 0) {
  122. $lex->phpType = 'unmatched';
  123. } elseif (strpos($lex->value, '?>') === 0) {
  124. if ($lex->is_xml) {
  125. $lex->is_xml = false;
  126. $lex->phpType = 'xml';
  127. return;
  128. }
  129. $lex->phpType = 'unmatched';
  130. } elseif (strpos($lex->value, '<s') === 0) {
  131. $lex->phpType = 'script';
  132. $closeTag = '</script>';
  133. } elseif (strpos($lex->value, $lex->smarty->left_delimiter) === 0) {
  134. if ($lex->isAutoLiteral()) {
  135. $lex->token = Smarty_Internal_Templateparser::TP_TEXT;
  136. return;
  137. }
  138. $closeTag = "{$lex->smarty->left_delimiter}/php{$lex->smarty->right_delimiter}";
  139. if ($lex->value === $closeTag) {
  140. $lex->compiler->trigger_template_error("unexpected closing tag '{$closeTag}'");
  141. }
  142. $lex->phpType = 'tag';
  143. }
  144. if ($lex->phpType === 'unmatched') {
  145. return;
  146. }
  147. if (($lex->phpType === 'php' || $lex->phpType === 'asp') &&
  148. ($lex->compiler->php_handling === Smarty::PHP_PASSTHRU || $lex->compiler->php_handling === Smarty::PHP_QUOTE)
  149. ) {
  150. return;
  151. }
  152. $start = $lex->counter + strlen($lex->value);
  153. $body = true;
  154. if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
  155. $close = $match[ 0 ][ 1 ];
  156. } else {
  157. $lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
  158. }
  159. while ($body) {
  160. if (preg_match('~([/][*])|([/][/][^\n]*)|(\'[^\'\\\\]*(?:\\.[^\'\\\\]*)*\')|("[^"\\\\]*(?:\\.[^"\\\\]*)*")~',
  161. $lex->data, $match, PREG_OFFSET_CAPTURE, $start)) {
  162. $value = $match[ 0 ][ 0 ];
  163. $from = $pos = $match[ 0 ][ 1 ];
  164. if ($pos > $close) {
  165. $body = false;
  166. } else {
  167. $start = $pos + strlen($value);
  168. $phpCommentStart = $value === '/*';
  169. if ($phpCommentStart) {
  170. $phpCommentEnd = preg_match('~([*][/])~', $lex->data, $match, PREG_OFFSET_CAPTURE, $start);
  171. if ($phpCommentEnd) {
  172. $pos2 = $match[ 0 ][ 1 ];
  173. $start = $pos2 + strlen($match[ 0 ][ 0 ]);
  174. }
  175. }
  176. while ($close > $pos && $close < $start) {
  177. if (preg_match('~' . preg_quote($closeTag, '~') . '~i', $lex->data, $match, PREG_OFFSET_CAPTURE,
  178. $from)) {
  179. $close = $match[ 0 ][ 1 ];
  180. $from = $close + strlen($match[ 0 ][ 0 ]);
  181. } else {
  182. $lex->compiler->trigger_template_error("missing closing tag '{$closeTag}'");
  183. }
  184. }
  185. if ($phpCommentStart && (!$phpCommentEnd || $pos2 > $close)) {
  186. $lex->taglineno = $lex->line + substr_count(substr($lex->data, $lex->counter, $start), "\n");
  187. $lex->compiler->trigger_template_error("missing PHP comment closing tag '*/'");
  188. }
  189. }
  190. } else {
  191. $body = false;
  192. }
  193. }
  194. $lex->value = substr($lex->data, $lex->counter, $close + strlen($closeTag) - $lex->counter);
  195. }
  196. /*
  197. * Call back function for $php_handling = PHP_QUOTE
  198. *
  199. */
  200. /**
  201. * @param $match
  202. *
  203. * @return string
  204. */
  205. private function quote($match)
  206. {
  207. return htmlspecialchars($match[ 0 ], ENT_QUOTES);
  208. }
  209. }