Clarifications, questions, proposals
[squirrelmail.git] / class / template / template.class.php
1 <?php
2
3 /**
4 * Copyright 2003, Paul James
5 *
6 * This file contains some methods from the Smarty templating engine version
7 * 2.5.0 by Monte Ohrt <monte@ispi.net> and Andrei Zmievski <andrei@php.net>.
8 *
9 * The SquirrelMail (Foowd) template implementation.
10 * Derived from the foowd template implementation and adapted
11 * for squirrelmail
12 * @copyright &copy; 2005-2006 The SquirrelMail Project Team
13 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
14 * @version $Id$
15 * @package squirrelmail
16 */
17
18 /**
19 * The SquirrelMail (Foowd) template class.
20 *
21 * Basic template class for capturing values and pluging them into a template.
22 * This class uses a similar API to Smarty.
23 *
24 * @author Paul James
25 * @author Monte Ohrt <monte at ispi.net>
26 * @author Andrei Zmievski <andrei at php.net>
27 * @package squirrelmail
28 */
29 class Template
30 {
31 /**
32 * The templates values array
33 *
34 * @var array
35 */
36 var $values = array();
37
38 /**
39 * The template directory to use
40 *
41 * @var string
42 */
43 var $template_dir = '';
44
45 /**
46 * Template files provided by this template set
47 *
48 * @var array
49 */
50 var $templates_provided = array();
51
52 /**
53 * Javascript files required by the template
54 *
55 * @var array
56 */
57 var $required_js_files = array();
58
59 /**
60 * Javascript files provided by the template. If a JS file is required, but
61 * not provided, the js file by the same name will be included from the
62 * default template directory.
63 *
64 * @var array
65 */
66 var $provided_js_files = array();
67
68 /**
69 * Additional stylesheets provided by the template. This allows template
70 * authors to provide additional CSS sheets to templates while using the
71 * default template set stylesheet for other definitions.
72 */
73 var $additional_css_sheets = array();
74
75 /**
76 * Constructor
77 *
78 * @param string $sTplDir where the template set is located
79 */
80 function Template($sTplDir) {
81 $this->template_dir = $sTplDir;
82
83 // Pull in the tempalte config file
84 if (!file_exists($this->template_dir . 'template.php')) {
85 trigger_error('No template.php could be found in the requested template directory ("'.$this->template_dir.'")', E_USER_ERROR);
86 } else {
87 include ($this->template_dir . 'template.php');
88 $this->templates_provided = is_array($templates_provided) ? $templates_provided : array();
89 $this->required_js_files = is_array($required_js_files) ? $required_js_files : array();
90 $this->provided_js_files = is_array($provided_js_files) ? $provided_js_files: array();
91 $this->additional_css_sheets = is_array($additional_css_sheets) ? $additional_css_sheets : array();
92 }
93 }
94
95
96 /**
97 * Assigns values to template variables
98 *
99 * @param array|string $tpl_var the template variable name(s)
100 * @param mixed $value the value to assign
101 */
102 function assign($tpl_var, $value = NULL) {
103 if (is_array($tpl_var))
104 {
105 foreach ($tpl_var as $key => $val)
106 {
107 if ($key != '')
108 $this->values[$key] = $val;
109 }
110 }
111 else
112 {
113 if ($tpl_var != '')
114 $this->values[$tpl_var] = $value;
115 }
116 }
117
118 /**
119 * Assigns values to template variables by reference
120 *
121 * @param string $tpl_var the template variable name
122 * @param mixed $value the referenced value to assign
123 */
124 function assign_by_ref($tpl_var, &$value)
125 {
126 if ($tpl_var != '')
127 $this->values[$tpl_var] = &$value;
128 }
129
130 /**
131 * Appends values to template variables
132 *
133 * @param array|string $tpl_var the template variable name(s)
134 * @param mixed $value the value to append
135 * @param boolean $merge when $value is given as an array,
136 * this indicates whether or not that
137 * array itself should be appended as
138 * a new template variable value or if
139 * that array's values should be merged
140 * into the existing array of template
141 * variable values
142 */
143 function append($tpl_var, $value = NULL, $merge = FALSE)
144 {
145 if (is_array($tpl_var))
146 {
147 //FIXME: $tpl_var is supposed to be a list of template var names,
148 // so we should be looking at the values NOT the keys!
149 foreach ($tpl_var as $_key => $_val)
150 {
151 if ($_key != '')
152 {
153 if(isset($this->values[$_key]) && !is_array($this->values[$_key]))
154 settype($this->values[$_key],'array');
155
156 //FIXME: we should be iterating the $value array here not the values of the
157 // list of template variable names! I think this is totally broken
158 // This might just be a matter of needing to clarify the method's API;
159 // values may have been meant to be passed in $tpl_var in the case that
160 // $tpl_var is an array. Ugly and non-intuitive.
161 // PROPOSAL: API should be as such:
162 // if (is_string($tpl_var)) then $values are added/merged as already done
163 // if (is_array($tpl_var)) then $values is required to be an array whose
164 // keys must match up with $tpl_var keys and
165 // whose values are then what is added to
166 // each template variable value (array or
167 // strings, doesn't matter)
168 if($merge && is_array($_val))
169 {
170 foreach($_val as $_mkey => $_mval)
171 $this->values[$_key][$_mkey] = $_mval;
172 }
173 else
174 $this->values[$_key][] = $_val;
175 }
176 }
177 }
178 else
179 {
180 if ($tpl_var != '' && isset($value))
181 {
182 if(isset($this->values[$tpl_var]) && !is_array($this->values[$tpl_var]))
183 settype($this->values[$tpl_var],'array');
184
185 if($merge && is_array($value))
186 {
187 foreach($value as $_mkey => $_mval)
188 $this->values[$tpl_var][$_mkey] = $_mval;
189 }
190 else
191 $this->values[$tpl_var][] = $value;
192 }
193 }
194 }
195
196 /**
197 * Appends values to template variables by reference
198 *
199 * @param string $tpl_var the template variable name
200 * @param mixed $value the referenced value to append
201 * @param boolean $merge when $value is given as an array,
202 * this indicates whether or not that
203 * array itself should be appended as
204 * a new template variable value or if
205 * that array's values should be merged
206 * into the existing array of template
207 * variable values
208 */
209 function append_by_ref($tpl_var, &$value, $merge = FALSE)
210 {
211 if ($tpl_var != '' && isset($value))
212 {
213 if(!@is_array($this->values[$tpl_var]))
214 settype($this->values[$tpl_var],'array');
215
216 if ($merge && is_array($value))
217 {
218 foreach($value as $_key => $_val)
219 $this->values[$tpl_var][$_key] = &$value[$_key];
220 }
221 else
222 $this->values[$tpl_var][] = &$value;
223 }
224 }
225
226 /**
227 * Display the template
228 *
229 * @param string $file The template file to use
230 */
231 function display($file)
232 {
233 // Pull in our config file
234 $t = &$this->values; // place values array directly in scope
235
236 $template = in_array($file, $this->templates_provided) ? $this->template_dir . $file : SM_PATH .'templates/default/'. $file;
237 if (!file_exists($template)) {
238 trigger_error('The template "'.htmlspecialchars($file).'" could not be displayed!', E_USER_ERROR);
239 } else {
240 ob_start();
241 include($template);
242 ob_end_flush();
243 }
244 }
245
246 /**
247 * Return the results of applying a template.
248 *
249 * @param string $file The template file to use
250 * @return string A string of the results
251 */
252 function fetch($file) {
253 $t = &$this->values; // place values array directly in scope
254
255 $template = in_array($file, $this->templates_provided) ? $this->template_dir . $file : SM_PATH .'templates/default/'. $file;
256 if (!file_exists($template)) {
257 trigger_error('The template "'.htmlspecialchars($file).'" could not be fetched!', E_USER_ERROR);
258 } else {
259 ob_start();
260 include($template);
261 $contents = ob_get_contents();
262 ob_end_clean();
263 return $contents;
264 }
265 }
266
267 /**
268 * Return paths to the required javascript files. Used when generating page
269 * header.
270 *
271 * @return array $paths
272 */
273 function getJavascriptIncludes () {
274 $paths = array();
275 foreach ($this->required_js_files as $file) {
276 if (in_array($file, $this->provided_js_files))
277 $paths[] = './'.$this->template_dir.'js/'.basename($file);
278 else $paths[] = SM_PATH .'templates/default/js/'.basename($file);
279 }
280
281 return $paths;
282 }
283
284 /**
285 * Return any additional stylsheets provided by the template. Used when
286 * generating page headers.
287 *
288 * @return array $paths
289 */
290 function getAdditionalStyleSheets () {
291 $paths = array();
292 foreach ($this->additional_css_sheets as $css) {
293 $css = basename($css);
294 if (strtolower($css) == 'stylesheet.tpl') {
295 continue;
296 }
297 $paths[] = $css;
298 }
299 return $paths;
300 }
301 }