1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: 13: 14: 15: 16: 17:
18: class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
19: {
20:
21: const parent = '____SMARTY_BLOCK_PARENT____';
22: 23: 24: 25: 26: 27:
28: public $required_attributes = array('name');
29:
30: 31: 32: 33: 34: 35:
36: public $shorttag_order = array('name');
37:
38: 39: 40: 41: 42: 43:
44: public $option_flags = array('hide', 'append', 'prepend', 'nocache');
45:
46: 47: 48: 49: 50: 51:
52: public $optional_attributes = array('internal_file', 'internal_uid', 'internal_line');
53: 54: 55: 56: 57:
58: public static $nested_block_names = array();
59:
60: 61: 62: 63: 64:
65: public static $block_data = array();
66:
67: 68: 69: 70: 71: 72: 73: 74:
75: public function compile($args, $compiler)
76: {
77:
78: $_attr = $this->getAttributes($compiler, $args);
79: $_name = trim($_attr['name'], "\"'");
80:
81:
82: if (isset($compiler->template->block_data[$_name]) && $compiler->template->block_data[$_name]['mode'] == 'replace') {
83: $_attr['append'] = false;
84: $_attr['prepend'] = false;
85: }
86:
87:
88: if ($compiler->inheritance_child) {
89: array_unshift(self::$nested_block_names, $_name);
90:
91: self::$block_data[$_name]['source'] =
92: "{$compiler->smarty->left_delimiter}private_child_block name={$_attr['name']} file='{$compiler->template->source->filepath}' type='{$compiler->template->source->type}' resource='{$compiler->template->template_resource}'" .
93: " uid='{$compiler->template->source->uid}' line={$compiler->lex->line}";
94: if ($_attr['nocache']) {
95: self::$block_data[$_name]['source'] .= ' nocache';
96: }
97: self::$block_data[$_name]['source'] .= $compiler->smarty->right_delimiter;
98:
99: $save = array($_attr, $compiler->inheritance);
100: $this->openTag($compiler, 'block', $save);
101:
102: $compiler->inheritance = true;
103: $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
104: $compiler->has_code = false;
105: return;
106: }
107:
108: if ($_attr['nocache'] == true) {
109: $compiler->tag_nocache = true;
110: }
111: $save = array($_attr, $compiler->inheritance, $compiler->parser->current_buffer, $compiler->nocache);
112: $this->openTag($compiler, 'block', $save);
113: $compiler->inheritance = true;
114: $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
115:
116: $compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
117: $compiler->has_code = false;
118:
119: return true;
120: }
121:
122: 123: 124: 125: 126: 127: 128: 129:
130: static function compileChildBlock($compiler, $_name = null)
131: {
132: if ($compiler->inheritance_child) {
133: $name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
134: if (isset($compiler->template->block_data[$name1])) {
135:
136: Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= $compiler->template->block_data[$name1]['source'];
137: Smarty_Internal_Compile_Block::$block_data[$name1]['child'] = true;
138: }
139: $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
140: $compiler->has_code = false;
141: return;
142: }
143:
144: if ($_name == null) {
145: $stack_count = count($compiler->_tag_stack);
146: while (--$stack_count >= 0) {
147: if ($compiler->_tag_stack[$stack_count][0] == 'block') {
148: $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
149: break;
150: }
151: }
152: }
153: if ($_name == null) {
154: $compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ', $compiler->lex->taglineno);
155: }
156:
157: if (!isset($compiler->template->block_data[$_name]['source'])) {
158: $compiler->popTrace();
159: return '';
160: }
161:
162: $compiler->template->block_data[$_name]['compiled'] = true;
163: $_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
164: $compiler->template->compile_id, $compiler->template->caching, $compiler->template->cache_lifetime);
165: if ($compiler->smarty->debugging) {
166: Smarty_Internal_Debug::ignore($_tpl);
167: }
168: $_tpl->tpl_vars = $compiler->template->tpl_vars;
169: $_tpl->variable_filters = $compiler->template->variable_filters;
170: $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
171: $_tpl->allow_relative_path = true;
172: $_tpl->compiler->inheritance = true;
173: $_tpl->compiler->suppressHeader = true;
174: $_tpl->compiler->suppressFilter = true;
175: $_tpl->compiler->suppressTemplatePropertyHeader = true;
176: $_tpl->compiler->suppressMergedTemplates = true;
177: $nocache = $compiler->nocache || $compiler->tag_nocache;
178: if (strpos($compiler->template->block_data[$_name]['source'], self::parent) !== false) {
179: $_output = str_replace(self::parent, $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl, $nocache));
180: } elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
181: $_output = $_tpl->compiler->compileTemplate($_tpl, $nocache) . $compiler->parser->current_buffer->to_smarty_php();
182: } elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
183: $_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl, $nocache);
184: } elseif (!empty($compiler->template->block_data[$_name])) {
185: $_output = $_tpl->compiler->compileTemplate($_tpl, $nocache);
186: }
187: $compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
188: $compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
189: $compiler->merged_templates = array_merge($compiler->merged_templates, $_tpl->compiler->merged_templates);
190: $compiler->template->variable_filters = $_tpl->variable_filters;
191: if ($_tpl->has_nocache_code) {
192: $compiler->template->has_nocache_code = true;
193: }
194: foreach ($_tpl->required_plugins as $key => $tmp1) {
195: if ($compiler->nocache && $compiler->template->caching) {
196: $code = 'nocache';
197: } else {
198: $code = $key;
199: }
200: foreach ($tmp1 as $name => $tmp) {
201: foreach ($tmp as $type => $data) {
202: $compiler->template->required_plugins[$code][$name][$type] = $data;
203: }
204: }
205: }
206: unset($_tpl);
207: $compiler->has_code = true;
208: return $_output;
209: }
210:
211: 212: 213: 214: 215: 216: 217: 218:
219: static function compileParentBlock($compiler, $_name = null)
220: {
221:
222: if ($_name == null) {
223: $stack_count = count($compiler->_tag_stack);
224: while (--$stack_count >= 0) {
225: if ($compiler->_tag_stack[$stack_count][0] == 'block') {
226: $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
227: break;
228: }
229: }
230: }
231: if ($_name == null) {
232: $compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ', $compiler->lex->taglineno);
233: }
234: if (empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
235: $compiler->trigger_template_error(' illegal {$smarty.block.parent} in parent template ', $compiler->lex->taglineno);
236: }
237: Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= Smarty_Internal_Compile_Block::parent;
238: $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
239: $compiler->has_code = false;
240: return;
241: }
242:
243: 244: 245: 246: 247: 248: 249:
250: static function blockSource($compiler, $source)
251: {
252: Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= $source;
253: }
254: }
255:
256: 257: 258: 259: 260: 261:
262: class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
263: {
264: 265: 266: 267: 268: 269: 270: 271:
272: public function compile($args, $compiler)
273: {
274: $compiler->has_code = true;
275:
276: $_attr = $this->getAttributes($compiler, $args);
277: $saved_data = $this->closeTag($compiler, array('block'));
278: $_name = trim($saved_data[0]['name'], "\"'");
279:
280: $compiler->inheritance = $saved_data[1];
281:
282: if ($compiler->inheritance_child) {
283: $name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
284: Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= "{$compiler->smarty->left_delimiter}/private_child_block{$compiler->smarty->right_delimiter}";
285: array_shift(Smarty_Internal_Compile_Block::$nested_block_names);
286: if (!empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
287: $name2 = Smarty_Internal_Compile_Block::$nested_block_names[0];
288: if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
289: if (isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child']) || !isset($compiler->template->block_data[$name1])) {
290: Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
291: } else {
292: if ($compiler->template->block_data[$name1]['mode'] == 'append') {
293: Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
294: } elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
295: Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'] . Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
296: } else {
297: Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'];
298: }
299: }
300: }
301: unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
302: $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
303: } else {
304: if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
305: if (isset($compiler->template->block_data[$name1]) && !isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child'])) {
306: if (strpos($compiler->template->block_data[$name1]['source'], Smarty_Internal_Compile_Block::parent) !== false) {
307: $compiler->template->block_data[$name1]['source'] =
308: str_replace(Smarty_Internal_Compile_Block::parent, Smarty_Internal_Compile_Block::$block_data[$name1]['source'], $compiler->template->block_data[$name1]['source']);
309: } elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
310: $compiler->template->block_data[$name1]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
311: } elseif ($compiler->template->block_data[$name1]['mode'] == 'append') {
312: $compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
313: }
314: } else {
315: $compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
316: }
317: $compiler->template->block_data[$name1]['mode'] = 'replace';
318: if ($saved_data[0]['append']) {
319: $compiler->template->block_data[$name1]['mode'] = 'append';
320: }
321: if ($saved_data[0]['prepend']) {
322: $compiler->template->block_data[$name1]['mode'] = 'prepend';
323: }
324: }
325: unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
326: $compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
327: }
328: $compiler->has_code = false;
329: return;
330: }
331: if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
332: $_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
333: } else {
334: if ($saved_data[0]['hide'] && !isset($compiler->template->block_data[$_name]['source'])) {
335: $_output = '';
336: } else {
337: $_output = $compiler->parser->current_buffer->to_smarty_php();
338: }
339: }
340: unset($compiler->template->block_data[$_name]['compiled']);
341:
342: $compiler->parser->current_buffer = $saved_data[2];
343: if ($compiler->nocache) {
344: $compiler->tag_nocache = true;
345: }
346: $compiler->nocache = $saved_data[3];
347:
348: $compiler->suppressNocacheProcessing = true;
349:
350: return $_output;
351: }
352: }
353:
354: 355: 356: 357: 358: 359:
360: class Smarty_Internal_Compile_Private_Child_Block extends Smarty_Internal_CompileBase
361: {
362:
363: 364: 365: 366: 367: 368:
369: public $required_attributes = array('name', 'file', 'uid', 'line', 'type', 'resource');
370:
371: 372: 373: 374: 375: 376: 377: 378:
379: public function compile($args, $compiler)
380: {
381:
382: $_attr = $this->getAttributes($compiler, $args);
383:
384:
385: if (trim($_attr['type'], "'") == 'file') {
386: $compiler->template->template_resource = 'file:' . realpath(trim($_attr['file'], "'"));
387: } else {
388: $compiler->template->template_resource = trim($_attr['resource'], "'");
389: }
390:
391: unset ($compiler->template->source);
392: $exists = $compiler->template->source->exists;
393:
394:
395: if ($_attr['nocache'] == true) {
396: $compiler->tag_nocache = true;
397: }
398: $save = array($_attr, $compiler->nocache);
399:
400:
401: $compiler->pushTrace(trim($_attr['file'], "\"'"), trim($_attr['uid'], "\"'"), $_attr['line'] - $compiler->lex->line);
402:
403: $this->openTag($compiler, 'private_child_block', $save);
404:
405: $compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
406: $compiler->has_code = false;
407:
408: return true;
409: }
410: }
411:
412: 413: 414: 415: 416: 417:
418: class Smarty_Internal_Compile_Private_Child_Blockclose extends Smarty_Internal_CompileBase
419: {
420:
421: 422: 423: 424: 425: 426: 427: 428:
429: public function compile($args, $compiler)
430: {
431:
432: $_attr = $this->getAttributes($compiler, $args);
433:
434: $saved_data = $this->closeTag($compiler, array('private_child_block'));
435:
436:
437: $compiler->popTrace();
438:
439: $compiler->nocache = $saved_data[1];
440: $compiler->has_code = false;
441:
442: return true;
443: }
444: }
445: