smarty_internal_compile_block.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. /*
  3. * This file is part of Smarty.
  4. *
  5. * (c) 2015 Uwe Tews
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. /**
  11. * Smarty Internal Plugin Compile Block Class
  12. *
  13. * @author Uwe Tews <uwe.tews@googlemail.com>
  14. */
  15. class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inheritance
  16. {
  17. /**
  18. * Attribute definition: Overwrites base class.
  19. *
  20. * @var array
  21. * @see Smarty_Internal_CompileBase
  22. */
  23. public $required_attributes = array('name');
  24. /**
  25. * Attribute definition: Overwrites base class.
  26. *
  27. * @var array
  28. * @see Smarty_Internal_CompileBase
  29. */
  30. public $shorttag_order = array('name');
  31. /**
  32. * Attribute definition: Overwrites base class.
  33. *
  34. * @var array
  35. * @see Smarty_Internal_CompileBase
  36. */
  37. public $option_flags = array('hide', 'nocache');
  38. /**
  39. * Attribute definition: Overwrites base class.
  40. *
  41. * @var array
  42. * @see Smarty_Internal_CompileBase
  43. */
  44. public $optional_attributes = array('assign');
  45. /**
  46. * Saved compiler object
  47. *
  48. * @var Smarty_Internal_TemplateCompilerBase
  49. */
  50. public $compiler = null;
  51. /**
  52. * Compiles code for the {block} tag
  53. *
  54. * @param array $args array with attributes from parser
  55. * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
  56. * @param array $parameter array with compilation parameter
  57. *
  58. * @return bool true
  59. */
  60. public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
  61. {
  62. if (!isset($compiler->_cache[ 'blockNesting' ])) {
  63. $compiler->_cache[ 'blockNesting' ] = 0;
  64. }
  65. if ($compiler->_cache[ 'blockNesting' ] == 0) {
  66. // make sure that inheritance gets initialized in template code
  67. $this->registerInit($compiler);
  68. $this->option_flags = array('hide', 'nocache', 'append', 'prepend');
  69. } else {
  70. $this->option_flags = array('hide', 'nocache');
  71. }
  72. // check and get attributes
  73. $_attr = $this->getAttributes($compiler, $args);
  74. $compiler->_cache[ 'blockNesting' ] ++;
  75. $_className = 'Block_' . preg_replace('![^\w]+!', '_', uniqid(rand(), true));
  76. $compiler->_cache[ 'blockName' ][ $compiler->_cache[ 'blockNesting' ] ] = $_attr[ 'name' ];
  77. $compiler->_cache[ 'blockClass' ][ $compiler->_cache[ 'blockNesting' ] ] = $_className;
  78. $compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ] = array();
  79. $compiler->_cache[ 'blockParams' ][ 1 ][ 'subBlocks' ][ trim($_attr[ 'name' ], '"\'') ][] = $_className;
  80. $this->openTag($compiler, 'block', array($_attr, $compiler->nocache, $compiler->parser->current_buffer,
  81. $compiler->template->compiled->has_nocache_code,
  82. $compiler->template->caching));
  83. // must whole block be nocache ?
  84. if ($compiler->tag_nocache) {
  85. $i = 0;
  86. }
  87. $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
  88. // $compiler->suppressNocacheProcessing = true;
  89. if ($_attr[ 'nocache' ] === true) {
  90. //$compiler->trigger_template_error('nocache option not allowed', $compiler->parser->lex->taglineno);
  91. }
  92. $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
  93. $compiler->template->compiled->has_nocache_code = false;
  94. $compiler->suppressNocacheProcessing = true;
  95. }
  96. }
  97. /**
  98. * Smarty Internal Plugin Compile BlockClose Class
  99. *
  100. */
  101. class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_Inheritance
  102. {
  103. /**
  104. * Compiles code for the {/block} tag
  105. *
  106. * @param array $args array with attributes from parser
  107. * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
  108. * @param array $parameter array with compilation parameter
  109. *
  110. * @return bool true
  111. */
  112. public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
  113. {
  114. list($_attr, $_nocache, $_buffer, $_has_nocache_code, $_caching) = $this->closeTag($compiler, array('block'));
  115. // init block parameter
  116. $_block = $compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ];
  117. unset($compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ]);
  118. $_name = $_attr[ 'name' ];
  119. $_assign = isset($_attr[ 'assign' ]) ? $_attr[ 'assign' ] : null;
  120. unset($_attr[ 'assign' ], $_attr[ 'name' ]);
  121. foreach ($_attr as $name => $stat) {
  122. if ((is_bool($stat) && $stat !== false) || (!is_bool($stat) && $stat != 'false')) {
  123. $_block[ $name ] = 'true';
  124. }
  125. }
  126. $_className = $compiler->_cache[ 'blockClass' ][ $compiler->_cache[ 'blockNesting' ] ];
  127. // get compiled block code
  128. $_functionCode = $compiler->parser->current_buffer;
  129. // setup buffer for template function code
  130. $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
  131. $output = "<?php\n";
  132. $output .= "/* {block {$_name}} */\n";
  133. $output .= "class {$_className} extends Smarty_Internal_Block\n";
  134. $output .= "{\n";
  135. foreach ($_block as $property => $value) {
  136. $output .= "public \${$property} = " . var_export($value,true) .";\n";
  137. }
  138. $output .= "public function callBlock(Smarty_Internal_Template \$_smarty_tpl) {\n";
  139. //$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
  140. if ($compiler->template->compiled->has_nocache_code) {
  141. $output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n";
  142. }
  143. if (isset($_assign)) {
  144. $output .= "ob_start();\n";
  145. }
  146. $output .= "?>\n";
  147. $compiler->parser->current_buffer->append_subtree($compiler->parser,
  148. new Smarty_Internal_ParseTree_Tag($compiler->parser,
  149. $output));
  150. $compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
  151. $output = "<?php\n";
  152. if (isset($_assign)) {
  153. $output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n";
  154. }
  155. $output .= "}\n";
  156. $output .= "}\n";
  157. $output .= "/* {/block {$_name}} */\n\n";
  158. $output .= "?>\n";
  159. $compiler->parser->current_buffer->append_subtree($compiler->parser,
  160. new Smarty_Internal_ParseTree_Tag($compiler->parser,
  161. $output));
  162. $compiler->blockOrFunctionCode .= $f = $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
  163. $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
  164. // nocache plugins must be copied
  165. if (!empty($compiler->template->compiled->required_plugins[ 'nocache' ])) {
  166. foreach ($compiler->template->compiled->required_plugins[ 'nocache' ] as $plugin => $tmp) {
  167. foreach ($tmp as $type => $data) {
  168. $compiler->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin ][ $type ] =
  169. $data;
  170. }
  171. }
  172. }
  173. // restore old status
  174. $compiler->template->compiled->has_nocache_code = $_has_nocache_code;
  175. $compiler->tag_nocache = $compiler->nocache;
  176. $compiler->nocache = $_nocache;
  177. $compiler->parser->current_buffer = $_buffer;
  178. $output = "<?php \n";
  179. if ($compiler->_cache[ 'blockNesting' ] == 1) {
  180. $output .= "\$_smarty_tpl->inheritance->instanceBlock(\$_smarty_tpl, '$_className', $_name);\n";
  181. } else {
  182. $output .= "\$_smarty_tpl->inheritance->instanceBlock(\$_smarty_tpl, '$_className', $_name, \$this->tplIndex);\n";
  183. }
  184. $output .= "?>\n";
  185. $compiler->_cache[ 'blockNesting' ] --;
  186. if ($compiler->_cache[ 'blockNesting' ] == 0) {
  187. unset($compiler->_cache[ 'blockNesting' ]);
  188. }
  189. $compiler->has_code = true;
  190. $compiler->suppressNocacheProcessing = true;
  191. return $output;
  192. }
  193. }