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 */
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 {
21 /**
22 * populate Source Object with meta data from Resource
23 *
24 * @param Smarty_Template_Source $source source object
25 * @param Smarty_Internal_Template $_template template object
26 */
27 public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
28 {
29 $uid = '';
30 $sources = array();
31 $components = explode('|', $source->name);
32 $exists = true;
33 foreach ($components as $component) {
34 $s = Smarty_Resource::source(null, $source->smarty, $component);
35 if ($s->type == 'php') {
36 throw new SmartyException("Resource type {$s->type} cannot be used with the extends resource type");
37 }
38 $sources[$s->uid] = $s;
39 $uid .= $s->filepath;
40 if ($_template && $_template->smarty->compile_check) {
41 $exists == $exists && $s->exists;
42 }
43 }
44 $source->components = $sources;
45 $source->filepath = $s->filepath;
46 $source->uid = sha1($uid);
47 if ($_template && $_template->smarty->compile_check) {
48 $source->timestamp = $s->timestamp;
49 $source->exists = $exists;
50 }
51 // need the template at getContent()
52 $source->template = $_template;
53 }
55 /**
56 * populate Source Object with timestamp and exists from Resource
57 *
58 * @param Smarty_Template_Source $source source object
59 */
60 public function populateTimestamp(Smarty_Template_Source $source)
61 {
62 $source->exists = true;
63 foreach ($source->components as $s) {
64 $source->exists == $source->exists && $s->exists;
65 }
66 $source->timestamp = $s->timestamp;
67 }
69 /**
70 * Load template's source from files into current template object
71 *
72 * @param Smarty_Template_Source $source source object
73 * @return string template source
74 * @throws SmartyException if source cannot be loaded
75 */
76 public function getContent(Smarty_Template_Source $source)
77 {
78 if (!$source->exists) {
79 throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
80 }
82 $_rdl = preg_quote($source->smarty->right_delimiter);
83 $_ldl = preg_quote($source->smarty->left_delimiter);
84 $_components = array_reverse($source->components);
85 $_first = reset($_components);
86 $_last = end($_components);
88 foreach ($_components as $_component) {
89 // register dependency
90 if ($_component != $_first) {
91 $source->template->properties['file_dependency'][$_component->uid] = array($_component->filepath, $_component->timestamp, $_component->type);
92 }
94 // read content
95 $source->filepath = $_component->filepath;
96 $_content = $_component->content;
98 // extend sources
99 if ($_component != $_last) {
100 if (preg_match_all("!({$_ldl}block\s(.+?){$_rdl})!", $_content, $_open) !=
101 preg_match_all("!({$_ldl}/block{$_rdl})!", $_content, $_close)) {
102 throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'");
103 }
104 preg_match_all("!{$_ldl}block\s(.+?){$_rdl}|{$_ldl}/block{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
105 $_result_count = count($_result[0]);
106 $_start = 0;
107 while ($_start+1 < $_result_count) {
108 $_end = 0;
109 $_level = 1;
110 if (substr($_result[0][$_start][0],0,strlen($source->smarty->left_delimiter)+1) == $source->smarty->left_delimiter.'*') {
111 $_start++;
112 continue;
113 }
114 while ($_level != 0) {
115 $_end++;
116 if (substr($_result[0][$_start + $_end][0],0,strlen($source->smarty->left_delimiter)+1) == $source->smarty->left_delimiter.'*') {
117 continue;
118 }
119 if (!strpos($_result[0][$_start + $_end][0], '/')) {
120 $_level++;
121 } else {
122 $_level--;
123 }
124 }
125 $_block_content = str_replace($source->smarty->left_delimiter . '$smarty.block.parent' . $source->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%', 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])));
126 Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $source->template, $_component->filepath);
127 $_start = $_start + $_end + 1;
128 }
129 } else {
130 return $_content;
131 }
132 }
133 }
135 /**
136 * Determine basename for compiled filename
137 *
138 * @param Smarty_Template_Source $source source object
139 * @return string resource's basename
140 */
141 public function getBasename(Smarty_Template_Source $source)
142 {
143 return str_replace(':', '.', basename($source->filepath));
144 }
146 }
148 ?>