1 | <?php |
---|
2 | /** |
---|
3 | * Smarty Internal Plugin Resource Extends |
---|
4 | * |
---|
5 | * @package Smarty |
---|
6 | * @subpackage TemplateResources |
---|
7 | * @author Uwe Tews |
---|
8 | * @author Rodney Rehm |
---|
9 | */ |
---|
10 | |
---|
11 | /** |
---|
12 | * Smarty Internal Plugin Resource Extends |
---|
13 | * |
---|
14 | * Implements the file system as resource for Smarty which {extend}s a chain of template files templates |
---|
15 | * |
---|
16 | * @package Smarty |
---|
17 | * @subpackage TemplateResources |
---|
18 | */ |
---|
19 | class Smarty_Internal_Resource_Extends extends Smarty_Resource { |
---|
20 | |
---|
21 | /** |
---|
22 | * mbstring.overload flag |
---|
23 | * |
---|
24 | * @var int |
---|
25 | */ |
---|
26 | public $mbstring_overload = 0; |
---|
27 | |
---|
28 | /** |
---|
29 | * populate Source Object with meta data from Resource |
---|
30 | * |
---|
31 | * @param Smarty_Template_Source $source source object |
---|
32 | * @param Smarty_Internal_Template $_template template object |
---|
33 | */ |
---|
34 | public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) |
---|
35 | { |
---|
36 | $uid = ''; |
---|
37 | $sources = array(); |
---|
38 | $components = explode('|', $source->name); |
---|
39 | $exists = true; |
---|
40 | foreach ($components as $component) { |
---|
41 | $s = Smarty_Resource::source(null, $source->smarty, $component); |
---|
42 | if ($s->type == 'php') { |
---|
43 | throw new SmartyException("Resource type {$s->type} cannot be used with the extends resource type"); |
---|
44 | } |
---|
45 | $sources[$s->uid] = $s; |
---|
46 | $uid .= $s->filepath; |
---|
47 | if ($_template && $_template->smarty->compile_check) { |
---|
48 | $exists = $exists && $s->exists; |
---|
49 | } |
---|
50 | } |
---|
51 | $source->components = $sources; |
---|
52 | $source->filepath = $s->filepath; |
---|
53 | $source->uid = sha1($uid); |
---|
54 | if ($_template && $_template->smarty->compile_check) { |
---|
55 | $source->timestamp = $s->timestamp; |
---|
56 | $source->exists = $exists; |
---|
57 | } |
---|
58 | // need the template at getContent() |
---|
59 | $source->template = $_template; |
---|
60 | } |
---|
61 | |
---|
62 | /** |
---|
63 | * populate Source Object with timestamp and exists from Resource |
---|
64 | * |
---|
65 | * @param Smarty_Template_Source $source source object |
---|
66 | */ |
---|
67 | public function populateTimestamp(Smarty_Template_Source $source) |
---|
68 | { |
---|
69 | $source->exists = true; |
---|
70 | foreach ($source->components as $s) { |
---|
71 | $source->exists = $source->exists && $s->exists; |
---|
72 | } |
---|
73 | $source->timestamp = $s->timestamp; |
---|
74 | } |
---|
75 | |
---|
76 | /** |
---|
77 | * Load template's source from files into current template object |
---|
78 | * |
---|
79 | * @param Smarty_Template_Source $source source object |
---|
80 | * @return string template source |
---|
81 | * @throws SmartyException if source cannot be loaded |
---|
82 | */ |
---|
83 | public function getContent(Smarty_Template_Source $source) |
---|
84 | { |
---|
85 | if (!$source->exists) { |
---|
86 | throw new SmartyException("Unable to read template {$source->type} '{$source->name}'"); |
---|
87 | } |
---|
88 | |
---|
89 | $this->mbstring_overload = ini_get('mbstring.func_overload') & 2; |
---|
90 | $_rdl = preg_quote($source->smarty->right_delimiter); |
---|
91 | $_ldl = preg_quote($source->smarty->left_delimiter); |
---|
92 | if (!$source->smarty->auto_literal) { |
---|
93 | $al = '\s*'; |
---|
94 | } else { |
---|
95 | $al = ''; |
---|
96 | } |
---|
97 | $_components = array_reverse($source->components); |
---|
98 | $_first = reset($_components); |
---|
99 | $_last = end($_components); |
---|
100 | |
---|
101 | foreach ($_components as $_component) { |
---|
102 | // register dependency |
---|
103 | if ($_component != $_first) { |
---|
104 | $source->template->properties['file_dependency'][$_component->uid] = array($_component->filepath, $_component->timestamp, $_component->type); |
---|
105 | } |
---|
106 | |
---|
107 | // read content |
---|
108 | $source->filepath = $_component->filepath; |
---|
109 | $_content = $_component->content; |
---|
110 | |
---|
111 | // extend sources |
---|
112 | if ($_component != $_last) { |
---|
113 | if (preg_match_all("!({$_ldl}{$al}block\s(.+?)\s*{$_rdl})!", $_content, $_open) != |
---|
114 | preg_match_all("!({$_ldl}{$al}/block\s*{$_rdl})!", $_content, $_close)) { |
---|
115 | throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'"); |
---|
116 | } |
---|
117 | preg_match_all("!{$_ldl}{$al}block\s(.+?)\s*{$_rdl}|{$_ldl}{$al}/block\s*{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE); |
---|
118 | $_result_count = count($_result[0]); |
---|
119 | $_start = 0; |
---|
120 | while ($_start+1 < $_result_count) { |
---|
121 | $_end = 0; |
---|
122 | $_level = 1; |
---|
123 | if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($source->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($source->smarty->left_delimiter)+1)) == $source->smarty->left_delimiter.'*') { |
---|
124 | $_start++; |
---|
125 | continue; |
---|
126 | } |
---|
127 | while ($_level != 0) { |
---|
128 | $_end++; |
---|
129 | if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($source->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($source->smarty->left_delimiter)+1)) == $source->smarty->left_delimiter.'*') { |
---|
130 | continue; |
---|
131 | } |
---|
132 | if (!strpos($_result[0][$_start + $_end][0], '/')) { |
---|
133 | $_level++; |
---|
134 | } else { |
---|
135 | $_level--; |
---|
136 | } |
---|
137 | } |
---|
138 | $_block_content = str_replace($source->smarty->left_delimiter . '$smarty.block.parent' . $source->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%', |
---|
139 | ($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])))); |
---|
140 | Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $source->template, $_component->filepath); |
---|
141 | $_start = $_start + $_end + 1; |
---|
142 | } |
---|
143 | } else { |
---|
144 | return $_content; |
---|
145 | } |
---|
146 | } |
---|
147 | } |
---|
148 | |
---|
149 | /** |
---|
150 | * Determine basename for compiled filename |
---|
151 | * |
---|
152 | * @param Smarty_Template_Source $source source object |
---|
153 | * @return string resource's basename |
---|
154 | */ |
---|
155 | public function getBasename(Smarty_Template_Source $source) |
---|
156 | { |
---|
157 | return str_replace(':', '.', basename($source->filepath)); |
---|
158 | } |
---|
159 | |
---|
160 | } |
---|
161 | |
---|
162 | ?> |
---|