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