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