|
1 <?php |
|
2 |
|
3 /** |
|
4 * Smarty Internal Plugin Compile extend |
|
5 * |
|
6 * Compiles the {extends} tag |
|
7 * |
|
8 * @package Smarty |
|
9 * @subpackage Compiler |
|
10 * @author Uwe Tews |
|
11 */ |
|
12 |
|
13 /** |
|
14 * Smarty Internal Plugin Compile extend Class |
|
15 * |
|
16 * @package Smarty |
|
17 * @subpackage Compiler |
|
18 */ |
|
19 class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase { |
|
20 |
|
21 /** |
|
22 * Attribute definition: Overwrites base class. |
|
23 * |
|
24 * @var array |
|
25 * @see Smarty_Internal_CompileBase |
|
26 */ |
|
27 public $required_attributes = array('file'); |
|
28 /** |
|
29 * Attribute definition: Overwrites base class. |
|
30 * |
|
31 * @var array |
|
32 * @see Smarty_Internal_CompileBase |
|
33 */ |
|
34 public $shorttag_order = array('file'); |
|
35 /** |
|
36 * mbstring.overload flag |
|
37 * |
|
38 * @var int |
|
39 */ |
|
40 public $mbstring_overload = 0; |
|
41 |
|
42 /** |
|
43 * Compiles code for the {extends} tag |
|
44 * |
|
45 * @param array $args array with attributes from parser |
|
46 * @param object $compiler compiler object |
|
47 * @return string compiled code |
|
48 */ |
|
49 public function compile($args, $compiler) |
|
50 { |
|
51 static $_is_stringy = array('string' => true, 'eval' => true); |
|
52 $this->_rdl = preg_quote($compiler->smarty->right_delimiter); |
|
53 $this->_ldl = preg_quote($compiler->smarty->left_delimiter); |
|
54 if (!$compiler->smarty->auto_literal) { |
|
55 $al = '\s*'; |
|
56 } else { |
|
57 $al = ''; |
|
58 } |
|
59 $filepath = $compiler->template->source->filepath; |
|
60 $this->mbstring_overload = ini_get('mbstring.func_overload') & 2; |
|
61 // check and get attributes |
|
62 $_attr = $this->getAttributes($compiler, $args); |
|
63 if ($_attr['nocache'] === true) { |
|
64 $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno); |
|
65 } |
|
66 |
|
67 $_smarty_tpl = $compiler->template; |
|
68 $include_file = null; |
|
69 if (strpos($_attr['file'], '$_tmp') !== false) { |
|
70 $compiler->trigger_template_error('illegal value for file attribute', $compiler->lex->taglineno); |
|
71 } |
|
72 eval('$include_file = ' . $_attr['file'] . ';'); |
|
73 // create template object |
|
74 $_template = new $compiler->smarty->template_class($include_file, $compiler->smarty, $compiler->template); |
|
75 // save file dependency |
|
76 if (isset($_is_stringy[$_template->source->type])) { |
|
77 $template_sha1 = sha1($include_file); |
|
78 } else { |
|
79 $template_sha1 = sha1($_template->source->filepath); |
|
80 } |
|
81 if (isset($compiler->template->properties['file_dependency'][$template_sha1])) { |
|
82 $compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1); |
|
83 } |
|
84 $compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type); |
|
85 $_content = ($this->mbstring_overload ? mb_substr($compiler->template->source->content, $compiler->lex->counter - 1, 20000000, 'latin1') : substr($compiler->template->source->content, $compiler->lex->counter - 1)); |
|
86 if (preg_match_all("!({$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl})!", $_content, $s) != |
|
87 preg_match_all("!({$this->_ldl}{$al}/block\s*{$this->_rdl})!", $_content, $c)) { |
|
88 $compiler->trigger_template_error('unmatched {block} {/block} pairs'); |
|
89 } |
|
90 preg_match_all("!{$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl}|{$this->_ldl}{$al}/block\s*{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE); |
|
91 $_result_count = count($_result[0]); |
|
92 $_start = 0; |
|
93 while ($_start+1 < $_result_count) { |
|
94 $_end = 0; |
|
95 $_level = 1; |
|
96 if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') { |
|
97 $_start++; |
|
98 continue; |
|
99 } |
|
100 while ($_level != 0) { |
|
101 $_end++; |
|
102 if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') { |
|
103 continue; |
|
104 } |
|
105 if (!strpos($_result[0][$_start + $_end][0], '/')) { |
|
106 $_level++; |
|
107 } else { |
|
108 $_level--; |
|
109 } |
|
110 } |
|
111 $_block_content = str_replace($compiler->smarty->left_delimiter . '$smarty.block.parent' . $compiler->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%', |
|
112 ($this->mbstring_overload ? mb_substr($_content, $_result[0][$_start][1] + mb_strlen($_result[0][$_start][0], 'latin1'), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + mb_strlen($_result[0][$_start][0], 'latin1'), 'latin1') : substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])))); |
|
113 Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $compiler->template, $filepath); |
|
114 $_start = $_start + $_end + 1; |
|
115 } |
|
116 if ($_template->source->type == 'extends') { |
|
117 $_template->block_data = $compiler->template->block_data; |
|
118 } |
|
119 $compiler->template->source->content = $_template->source->content; |
|
120 if ($_template->source->type == 'extends') { |
|
121 $compiler->template->block_data = $_template->block_data; |
|
122 foreach ($_template->source->components as $key => $component) { |
|
123 $compiler->template->properties['file_dependency'][$key] = array($component->filepath, $component->timestamp, $component->type); |
|
124 } |
|
125 } |
|
126 $compiler->template->source->filepath = $_template->source->filepath; |
|
127 $compiler->abort_and_recompile = true; |
|
128 return ''; |
|
129 } |
|
130 |
|
131 } |
|
132 |
|
133 ?> |