3 * This file is part of Smarty.
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
12 * Smarty Internal Plugin Compile Block Class
14 * @author Uwe Tews <uwe.tews@googlemail.com>
16 class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inheritance
19 * Attribute definition: Overwrites base class.
22 * @see Smarty_Internal_CompileBase
24 public $required_attributes = array('name');
27 * Attribute definition: Overwrites base class.
30 * @see Smarty_Internal_CompileBase
32 public $shorttag_order = array('name');
35 * Attribute definition: Overwrites base class.
38 * @see Smarty_Internal_CompileBase
40 public $option_flags = array('hide', 'nocache');
43 * Attribute definition: Overwrites base class.
46 * @see Smarty_Internal_CompileBase
48 public $optional_attributes = array('assign');
51 * Saved compiler object
53 * @var Smarty_Internal_TemplateCompilerBase
55 public $compiler = null;
58 * Compiles code for the {block} tag
60 * @param array $args array with attributes from parser
61 * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
62 * @param array $parameter array with compilation parameter
66 public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
68 if (!isset($compiler->_cache[ 'blockNesting' ])) {
69 $compiler->_cache[ 'blockNesting' ] = 0;
71 if ($compiler->_cache[ 'blockNesting' ] == 0) {
72 // make sure that inheritance gets initialized in template code
73 $this->registerInit($compiler);
74 $this->option_flags = array('hide', 'nocache', 'append', 'prepend');
76 $this->option_flags = array('hide', 'nocache');
78 // check and get attributes
79 $_attr = $this->getAttributes($compiler, $args);
80 $compiler->_cache[ 'blockNesting' ] ++;
81 $_className = 'Block_' . preg_replace('![^\w]+!', '_', uniqid(rand(), true));
82 $compiler->_cache[ 'blockName' ][ $compiler->_cache[ 'blockNesting' ] ] = $_attr[ 'name' ];
83 $compiler->_cache[ 'blockClass' ][ $compiler->_cache[ 'blockNesting' ] ] = $_className;
84 $compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ] = array();
85 $compiler->_cache[ 'blockParams' ][ 1 ][ 'subBlocks' ][ trim($_attr[ 'name' ], '"\'') ][] = $_className;
86 $this->openTag($compiler, 'block', array($_attr, $compiler->nocache, $compiler->parser->current_buffer,
87 $compiler->template->compiled->has_nocache_code,
88 $compiler->template->caching));
89 // must whole block be nocache ?
90 if ($compiler->tag_nocache) {
93 $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
94 // $compiler->suppressNocacheProcessing = true;
95 if ($_attr[ 'nocache' ] === true) {
96 //$compiler->trigger_template_error('nocache option not allowed', $compiler->parser->lex->taglineno);
98 $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
99 $compiler->template->compiled->has_nocache_code = false;
100 $compiler->suppressNocacheProcessing = true;
105 * Smarty Internal Plugin Compile BlockClose Class
108 class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_Inheritance
111 * Compiles code for the {/block} tag
113 * @param array $args array with attributes from parser
114 * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
115 * @param array $parameter array with compilation parameter
119 public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
121 list($_attr, $_nocache, $_buffer, $_has_nocache_code, $_caching) = $this->closeTag($compiler, array('block'));
122 // init block parameter
123 $_block = $compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ];
124 unset($compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ]);
125 $_name = $_attr[ 'name' ];
126 $_assign = isset($_attr[ 'assign' ]) ? $_attr[ 'assign' ] : null;
127 unset($_attr[ 'assign' ], $_attr[ 'name' ]);
128 foreach ($_attr as $name => $stat) {
129 if ((is_bool($stat) && $stat !== false) || (!is_bool($stat) && $stat != 'false')) {
130 $_block[ $name ] = 'true';
133 $_className = $compiler->_cache[ 'blockClass' ][ $compiler->_cache[ 'blockNesting' ] ];
134 // get compiled block code
135 $_functionCode = $compiler->parser->current_buffer;
136 // setup buffer for template function code
137 $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
140 $output .= "/* {block {$_name}} */\n";
141 $output .= "class {$_className} extends Smarty_Internal_Block\n";
143 foreach ($_block as $property => $value) {
144 $output .= "public \${$property} = " . var_export($value,true) .";\n";
146 $output .= "public function callBlock(Smarty_Internal_Template \$_smarty_tpl) {\n";
147 //$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
148 if ($compiler->template->compiled->has_nocache_code) {
149 $output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n";
151 if (isset($_assign)) {
152 $output .= "ob_start();\n";
155 $compiler->parser->current_buffer->append_subtree($compiler->parser,
156 new Smarty_Internal_ParseTree_Tag($compiler->parser,
158 $compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
160 if (isset($_assign)) {
161 $output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n";
165 $output .= "/* {/block {$_name}} */\n\n";
167 $compiler->parser->current_buffer->append_subtree($compiler->parser,
168 new Smarty_Internal_ParseTree_Tag($compiler->parser,
170 $compiler->blockOrFunctionCode .= $f = $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
171 $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
172 // nocache plugins must be copied
173 if (!empty($compiler->template->compiled->required_plugins[ 'nocache' ])) {
174 foreach ($compiler->template->compiled->required_plugins[ 'nocache' ] as $plugin => $tmp) {
175 foreach ($tmp as $type => $data) {
176 $compiler->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin ][ $type ] =
182 // restore old status
183 $compiler->template->compiled->has_nocache_code = $_has_nocache_code;
184 $compiler->tag_nocache = $compiler->nocache;
185 $compiler->nocache = $_nocache;
186 $compiler->parser->current_buffer = $_buffer;
187 $output = "<?php \n";
188 if ($compiler->_cache[ 'blockNesting' ] == 1) {
189 $output .= "\$_smarty_tpl->inheritance->instanceBlock(\$_smarty_tpl, '$_className', $_name);\n";
191 $output .= "\$_smarty_tpl->inheritance->instanceBlock(\$_smarty_tpl, '$_className', $_name, \$this->tplIndex);\n";
194 $compiler->_cache[ 'blockNesting' ] --;
195 if ($compiler->_cache[ 'blockNesting' ] == 0) {
196 unset($compiler->_cache[ 'blockNesting' ]);
198 $compiler->has_code = true;
199 $compiler->suppressNocacheProcessing = true;