6 * @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
14 if (!defined('IN_PHPBB'))
20 * Base Template class.
25 /** variable that holds all the data we'll be substituting into
26 * the compiled templates. Takes form:
27 * --> $this->_tpldata[block][iteration#][child][iteration#][child2][iteration#][variablename] == value
28 * if it's a root-level variable, it'll be like this:
29 * --> $this->_tpldata[.][0][varname] == value
31 private $_tpldata = array('.' => array(0 => array()));
34 // Root dir and hash of filenames for each template handle.
36 public $cachepath = '';
37 public $files = array();
38 public $filename = array();
41 * Set template location
44 public function set_template()
48 if (file_exists(PHPBB_ROOT_PATH
. 'styles/' . $user->theme
['template_path'] . '/template'))
50 $this->root
= PHPBB_ROOT_PATH
. 'styles/' . $user->theme
['template_path'] . '/template';
51 $this->cachepath
= PHPBB_ROOT_PATH
. 'cache/tpl_' . $user->theme
['template_path'] . '_';
55 trigger_error('Template path could not be found: styles/' . $user->theme
['template_path'] . '/template', E_USER_ERROR
);
58 $this->_rootref
= &$this->_tpldata
['.'][0];
64 * Set custom template location (able to use directory outside of phpBB)
67 public function set_custom_template($template_path, $template_name)
69 $this->root
= $template_path;
70 $this->cachepath
= PHPBB_ROOT_PATH
. 'cache/ctpl_' . str_replace('_', '-', $template_name) . '_';
76 * Sets the template filenames for handles. $filename_array
77 * should be a hash of handle => filename pairs.
80 public function set_filenames(array $filename_array)
82 foreach ($filename_array as $handle => $filename)
86 trigger_error("template->set_filenames: Empty filename specified for $handle", E_USER_ERROR
);
89 $this->filename
[$handle] = $filename;
90 $this->files
[$handle] = $this->root
. '/' . $filename;
97 * Destroy template data set
100 function __destruct()
102 $this->_tpldata
= array('.' => array(0 => array()));
106 * Reset/empty complete block
109 public function destroy_block_vars($blockname)
111 if (strpos($blockname, '.') !== false)
114 $blocks = explode('.', $blockname);
115 $blockcount = sizeof($blocks) - 1;
117 $str = &$this->_tpldata
;
118 for ($i = 0; $i < $blockcount; $i++
)
120 $str = &$str[$blocks[$i]];
121 $str = &$str[sizeof($str) - 1];
124 unset($str[$blocks[$blockcount]]);
129 unset($this->_tpldata
[$blockname]);
139 public function display($handle, $include_once = true)
141 global $user, $phpbb_hook;
143 if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__
, __FUNCTION__
), $handle, $include_once))
145 if ($phpbb_hook->hook_return(array(__CLASS__
, __FUNCTION__
)))
147 return $phpbb_hook->hook_return_result(array(__CLASS__
, __FUNCTION__
));
151 /* if (defined('IN_ERROR_HANDLER'))
153 if ((E_NOTICE & error_reporting()) == E_NOTICE)
155 //error_reporting(error_reporting() ^ E_NOTICE);
159 $_tpldata = &$this->_tpldata
;
160 $_rootref = &$this->_rootref
;
161 $_lang = &$user->lang
;
163 // These _are_ used the included files.
164 $_tpldata; $_rootref; $_lang;
166 if (($filename = $this->_tpl_load($handle)) !== false)
168 ($include_once) ?
include_once($filename) : include($filename);
170 else if (($code = $this->_tpl_eval($handle)) !== false)
172 $code = ' ?> ' . $code . ' <?php ';
177 // if we could not eval AND the file exists, something horrific has occured
185 * Display the handle and assign the output to a template variable or return the compiled result.
188 public function assign_display($handle, $template_var = '', $return_content = true, $include_once = false)
191 $this->display($handle, $include_once);
192 $contents = ob_get_clean();
199 $this->assign_var($template_var, $contents);
205 * Load a compiled template if possible, if not, recompile it
208 private function _tpl_load(&$handle)
212 $filename = $this->cachepath
. str_replace('/', '.', $this->filename
[$handle]) . '.' . PHP_EXT
;
214 $recompile = (($config['load_tplcompile'] && @filemtime
($filename) < filemtime($this->files
[$handle])) ||
!file_exists($filename) || @filesize
($filename) === 0) ?
true : false;
216 // Recompile page if the original template is newer, otherwise load the compiled version
219 if (!class_exists('template_compile'))
221 include(PHPBB_ROOT_PATH
. 'includes/functions_template.' . PHP_EXT
);
224 $compile = new template_compile($this);
226 // If we don't have a file assigned to this handle, die.
227 if (!isset($this->files
[$handle]))
229 trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR
);
232 if ($compile->_tpl_load_file($handle) === false)
242 * This code should only run when some high level error prevents us from writing to the cache.
245 private function _tpl_eval(&$handle)
247 // global $user, $config;
249 if (!class_exists('template_compile'))
251 include(PHPBB_ROOT_PATH
. 'includes/functions_template.' . PHP_EXT
);
254 $compile = new template_compile($this);
256 // If we don't have a file assigned to this handle, die.
257 if (!isset($this->files
[$handle]))
259 trigger_error("template->_tpl_eval(): No file specified for handle $handle", E_USER_ERROR
);
262 if (($code = $compile->_tpl_gen_src($handle)) === false)
271 * Assign key variable pairs from an array
274 public function assign_vars(array $vararray)
276 foreach ($vararray as $key => $val)
278 $this->_rootref
[$key] = $val;
285 * Assign a single variable to a single key
288 public function assign_var($varname, $varval)
290 $this->_rootref
[$varname] = $varval;
296 * Assign key variable pairs from an array to a specified block
299 public function assign_block_vars($blockname, array $vararray)
301 if (strpos($blockname, '.') !== false)
304 $blocks = explode('.', $blockname);
305 $blockcount = sizeof($blocks) - 1;
307 $str = &$this->_tpldata
;
308 for ($i = 0; $i < $blockcount; $i++
)
310 $str = &$str[$blocks[$i]];
311 $str = &$str[sizeof($str) - 1];
314 $s_row_count = isset($str[$blocks[$blockcount]]) ?
sizeof($str[$blocks[$blockcount]]) : 0;
315 $vararray['S_ROW_COUNT'] = $s_row_count;
317 // Assign S_FIRST_ROW
320 $vararray['S_FIRST_ROW'] = true;
323 // Now the tricky part, we always assign S_LAST_ROW and remove the entry before
324 // This is much more clever than going through the complete template data on display (phew)
325 $vararray['S_LAST_ROW'] = true;
326 if ($s_row_count > 0)
328 unset($str[$blocks[$blockcount]][($s_row_count - 1)]['S_LAST_ROW']);
331 // Now we add the block that we're actually assigning to.
332 // We're adding a new iteration to this block with the given
333 // variable assignments.
334 $str[$blocks[$blockcount]][] = $vararray;
339 $s_row_count = (isset($this->_tpldata
[$blockname])) ?
sizeof($this->_tpldata
[$blockname]) : 0;
340 $vararray['S_ROW_COUNT'] = $s_row_count;
342 // Assign S_FIRST_ROW
345 $vararray['S_FIRST_ROW'] = true;
348 // We always assign S_LAST_ROW and remove the entry before
349 $vararray['S_LAST_ROW'] = true;
350 if ($s_row_count > 0)
352 unset($this->_tpldata
[$blockname][($s_row_count - 1)]['S_LAST_ROW']);
355 // Add a new iteration to this block with the variable assignments we were given.
356 $this->_tpldata
[$blockname][] = $vararray;
363 * Change already assigned key variable pair (one-dimensional - single loop entry)
365 * An example of how to use this function:
366 * {@example alter_block_array.php}
368 * @param string $blockname the blockname, for example 'loop'
369 * @param array $vararray the var array to insert/add or merge
370 * @param mixed $key Key to search for
372 * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position]
374 * int: Position [the position to change or insert at directly given]
376 * If key is false the position is set to 0
377 * If key is true the position is set to the last entry
379 * @param string $mode Mode to execute (valid modes are 'insert' and 'change')
381 * If insert, the vararray is inserted at the given position (position counting from zero).
382 * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value).
384 * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array)
385 * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars)
387 * @return bool false on error, true on success
390 public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert')
392 if (strpos($blockname, '.') !== false)
394 // Nested blocks are not supported
398 // Change key to zero (change first position) if false and to last position if true
399 if ($key === false ||
$key === true)
401 $key = ($key === false) ?
0 : sizeof($this->_tpldata
[$blockname]);
404 // Get correct position if array given
407 // Search array to get correct position
408 list($search_key, $search_value) = @each
($key);
411 foreach ($this->_tpldata
[$blockname] as $i => $val_ary)
413 if ($val_ary[$search_key] === $search_value)
420 // key/value pair not found
428 if ($mode == 'insert')
430 // Make sure we are not exceeding the last iteration
431 if ($key >= sizeof($this->_tpldata
[$blockname]))
433 $key = sizeof($this->_tpldata
[$blockname]);
434 unset($this->_tpldata
[$blockname][($key - 1)]['S_LAST_ROW']);
435 $vararray['S_LAST_ROW'] = true;
439 unset($this->_tpldata
[$blockname][0]['S_FIRST_ROW']);
440 $vararray['S_FIRST_ROW'] = true;
443 // Re-position template blocks
444 for ($i = sizeof($this->_tpldata
[$blockname]); $i > $key; $i--)
446 $this->_tpldata
[$blockname][$i] = $this->_tpldata
[$blockname][$i-1];
447 $this->_tpldata
[$blockname][$i]['S_ROW_COUNT'] = $i;
450 // Insert vararray at given position
451 $vararray['S_ROW_COUNT'] = $key;
452 $this->_tpldata
[$blockname][$key] = $vararray;
457 // Which block to change?
458 if ($mode == 'change')
460 if ($key == sizeof($this->_tpldata
[$blockname]))
465 $this->_tpldata
[$blockname][$key] = array_merge($this->_tpldata
[$blockname][$key], $vararray);
473 * Include a separate template
476 public function _tpl_include($filename, $include = true)
479 $this->filename
[$handle] = $filename;
480 $this->files
[$handle] = $this->root
. '/' . $filename;
482 $filename = $this->_tpl_load($handle);
488 $_tpldata = &$this->_tpldata
;
489 $_rootref = &$this->_rootref
;
490 $_lang = &$user->lang
;
492 // These _are_ used the included files.
493 $_tpldata; $_rootref; $_lang;
502 if (!class_exists('template_compile'))
504 include(PHPBB_ROOT_PATH
. 'includes/functions_template.' . PHP_EXT
);
507 $compile = new template_compile($this);
509 if (($code = $compile->_tpl_gen_src($handle)) !== false)
511 $code = ' ?> ' . $code . ' <?php ';