[ Index ] |
PHP Cross Reference of phpBB 3.0 Beta 3 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package phpBB3 5 * @version $Id: template.php,v 1.103 2006/10/22 13:30:45 acydburn Exp $ 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 8 * 9 */ 10 11 /** 12 */ 13 if (!defined('IN_PHPBB')) 14 { 15 exit; 16 } 17 18 /** 19 * Base Template class. 20 * @package phpBB3 21 */ 22 class template 23 { 24 /** variable that holds all the data we'll be substituting into 25 * the compiled templates. Takes form: 26 * --> $this->_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value 27 * if it's a root-level variable, it'll be like this: 28 * --> $this->_tpldata[.][0][varname] == value 29 */ 30 var $_tpldata = array(); 31 32 // Root dir and hash of filenames for each template handle. 33 var $root = ''; 34 var $cachepath = ''; 35 var $files = array(); 36 37 // this will hash handle names to the compiled/uncompiled code for that handle. 38 var $compiled_code = array(); 39 40 /** 41 * Set template location 42 * @access public 43 */ 44 function set_template() 45 { 46 global $phpbb_root_path, $user; 47 48 if (file_exists($phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template')) 49 { 50 $this->root = $phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template'; 51 $this->cachepath = $phpbb_root_path . 'cache/tpl_' . $user->theme['template_path'] . '_'; 52 } 53 else 54 { 55 trigger_error('Template path could not be found: styles/' . $user->theme['template_path'] . '/template', E_USER_ERROR); 56 } 57 58 return true; 59 } 60 61 /** 62 * Set custom template location (able to use directory outside of phpBB) 63 * @access public 64 */ 65 function set_custom_template($template_path, $template_name) 66 { 67 global $phpbb_root_path; 68 69 $this->root = $template_path; 70 $this->cachepath = $phpbb_root_path . 'cache/ctpl_' . $template_name . '_'; 71 72 return true; 73 } 74 75 /** 76 * Sets the template filenames for handles. $filename_array 77 * should be a hash of handle => filename pairs. 78 * @access public 79 */ 80 function set_filenames($filename_array) 81 { 82 if (!is_array($filename_array)) 83 { 84 return false; 85 } 86 87 foreach ($filename_array as $handle => $filename) 88 { 89 if (empty($filename)) 90 { 91 trigger_error("template->set_filenames: Empty filename specified for $handle", E_USER_ERROR); 92 } 93 94 $this->filename[$handle] = $filename; 95 $this->files[$handle] = $this->root . '/' . $filename; 96 } 97 98 return true; 99 } 100 101 /** 102 * Destroy template data set 103 * @access public 104 */ 105 function destroy() 106 { 107 $this->_tpldata = array(); 108 } 109 110 /** 111 * Reset/empty complete block 112 * @access public 113 */ 114 function destroy_block_vars($blockname) 115 { 116 if (strpos($blockname, '.') !== false) 117 { 118 // Nested block. 119 $blocks = explode('.', $blockname); 120 $blockcount = sizeof($blocks) - 1; 121 122 $str = &$this->_tpldata; 123 for ($i = 0; $i < $blockcount; $i++) 124 { 125 $str = &$str[$blocks[$i]]; 126 $str = &$str[sizeof($str) - 1]; 127 } 128 129 unset($str[$blocks[$blockcount]]); 130 } 131 else 132 { 133 // Top-level block. 134 unset($this->_tpldata[$blockname]); 135 } 136 137 return true; 138 } 139 140 /** 141 * Display handle 142 * @access public 143 */ 144 function display($handle, $include_once = true) 145 { 146 global $user; 147 148 if ($filename = $this->_tpl_load($handle)) 149 { 150 ($include_once) ? include_once($filename) : include($filename); 151 } 152 else 153 { 154 eval(' ?>' . $this->compiled_code[$handle] . '<?php '); 155 } 156 157 return true; 158 } 159 160 /** 161 * Display the handle and assign the output to a template variable or return the compiled result. 162 * @access public 163 */ 164 function assign_display($handle, $template_var = '', $return_content = true, $include_once = false) 165 { 166 ob_start(); 167 $this->display($handle, $include_once); 168 $contents = ob_get_clean(); 169 170 if ($return_content) 171 { 172 return $contents; 173 } 174 175 $this->assign_var($template_var, $contents); 176 177 return true; 178 } 179 180 /** 181 * Load a compiled template if possible, if not, recompile it 182 * @access private 183 */ 184 function _tpl_load(&$handle) 185 { 186 global $user, $phpEx, $config; 187 188 $filename = $this->cachepath . str_replace('/', '.', $this->filename[$handle]) . '.' . $phpEx; 189 190 $recompile = (($config['load_tplcompile'] && @filemtime($filename) < filemtime($this->files[$handle])) || !file_exists($filename) || @filesize($filename) === 0) ? true : false; 191 192 // Recompile page if the original template is newer, otherwise load the compiled version 193 if (!$recompile) 194 { 195 return $filename; 196 } 197 198 global $db, $phpbb_root_path; 199 200 if (!class_exists('template_compile')) 201 { 202 include($phpbb_root_path . 'includes/functions_template.' . $phpEx); 203 } 204 205 $compile = new template_compile($this); 206 207 // If the file for this handle is already loaded and compiled, do nothing. 208 if (!empty($this->uncompiled_code[$handle])) 209 { 210 return true; 211 } 212 213 // If we don't have a file assigned to this handle, die. 214 if (!isset($this->files[$handle])) 215 { 216 trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR); 217 } 218 219 // Just compile if no user object is present (happens within the installer) 220 if (!$user) 221 { 222 $compile->_tpl_load_file($handle); 223 return false; 224 } 225 226 if (isset($user->theme['template_storedb']) && $user->theme['template_storedb']) 227 { 228 $sql = 'SELECT * FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' 229 WHERE template_id = ' . $user->theme['template_id'] . " 230 AND (template_filename = '" . $db->sql_escape($this->filename[$handle]) . "' 231 OR template_included LIKE '%" . $db->sql_escape($this->filename[$handle]) . ":%')"; 232 $result = $db->sql_query($sql); 233 234 while ($row = $db->sql_fetchrow($result)) 235 { 236 if ($row['template_mtime'] < filemtime($phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template/' . $row['template_filename'])) 237 { 238 if ($row['template_filename'] == $this->filename[$handle]) 239 { 240 $compile->_tpl_load_file($handle); 241 } 242 else 243 { 244 $this->files[$row['template_filename']] = $this->root . '/' . $row['template_filename']; 245 $compile->_tpl_load_file($row['template_filename']); 246 unset($this->compiled_code[$row['template_filename']]); 247 unset($this->files[$row['template_filename']]); 248 } 249 } 250 251 if ($row['template_filename'] == $this->filename[$handle]) 252 { 253 $this->compiled_code[$handle] = $compile->compile(trim($row['template_data'])); 254 $compile->compile_write($handle, $this->compiled_code[$handle]); 255 } 256 else 257 { 258 // Only bother compiling if it doesn't already exist 259 if (!file_exists($this->cachepath . str_replace('/', '.', $row['template_filename']) . '.' . $phpEx)) 260 { 261 $this->filename[$row['template_filename']] = $row['template_filename']; 262 $compile->compile_write($row['template_filename'], $compile->compile(trim($row['template_data']))); 263 unset($this->filename[$row['template_filename']]); 264 } 265 } 266 } 267 $db->sql_freeresult($result); 268 269 return false; 270 } 271 272 $compile->_tpl_load_file($handle); 273 return false; 274 } 275 276 /** 277 * Assign key variable pairs from an array 278 * @access public 279 */ 280 function assign_vars($vararray) 281 { 282 foreach ($vararray as $key => $val) 283 { 284 $this->_tpldata['.'][0][$key] = $val; 285 } 286 287 return true; 288 } 289 290 /** 291 * Assign a single variable to a single key 292 * @access public 293 */ 294 function assign_var($varname, $varval) 295 { 296 $this->_tpldata['.'][0][$varname] = $varval; 297 298 return true; 299 } 300 301 /** 302 * Assign key variable pairs from an array to a specified block 303 * @access public 304 */ 305 function assign_block_vars($blockname, $vararray) 306 { 307 if (strpos($blockname, '.') !== false) 308 { 309 // Nested block. 310 $blocks = explode('.', $blockname); 311 $blockcount = sizeof($blocks) - 1; 312 313 $str = &$this->_tpldata; 314 for ($i = 0; $i < $blockcount; $i++) 315 { 316 $str = &$str[$blocks[$i]]; 317 $str = &$str[sizeof($str) - 1]; 318 } 319 320 $s_row_count = isset($str[$blocks[$blockcount]]) ? sizeof($str[$blocks[$blockcount]]) : 0; 321 $vararray['S_ROW_COUNT'] = $s_row_count; 322 323 // Assign S_FIRST_ROW 324 if (!$s_row_count) 325 { 326 $vararray['S_FIRST_ROW'] = true; 327 } 328 329 // Now the tricky part, we always assign S_LAST_ROW and remove the entry before 330 // This is much more clever than going through the complete template data on display (phew) 331 $vararray['S_LAST_ROW'] = true; 332 if ($s_row_count > 0) 333 { 334 unset($str[$blocks[$blockcount]][($s_row_count - 1)]['S_LAST_ROW']); 335 } 336 337 // Now we add the block that we're actually assigning to. 338 // We're adding a new iteration to this block with the given 339 // variable assignments. 340 $str[$blocks[$blockcount]][] = $vararray; 341 } 342 else 343 { 344 // Top-level block. 345 $s_row_count = (isset($this->_tpldata[$blockname])) ? sizeof($this->_tpldata[$blockname]) : 0; 346 $vararray['S_ROW_COUNT'] = $s_row_count; 347 348 // Assign S_FIRST_ROW 349 if (!$s_row_count) 350 { 351 $vararray['S_FIRST_ROW'] = true; 352 } 353 354 // We always assign S_LAST_ROW and remove the entry before 355 $vararray['S_LAST_ROW'] = true; 356 if ($s_row_count > 0) 357 { 358 unset($this->_tpldata[$blockname][($s_row_count - 1)]['S_LAST_ROW']); 359 } 360 361 // Add a new iteration to this block with the variable assignments we were given. 362 $this->_tpldata[$blockname][] = $vararray; 363 } 364 365 return true; 366 } 367 368 /** 369 * Change already assigned key variable pair (one-dimensional - single loop entry) 370 * 371 * Some Examples: 372 * <code> 373 * alter_block_array('loop', $vararray); // Insert vararray at the beginning 374 * alter_block_array('loop', $vararray, 2); // Insert vararray at position 2 375 * alter_block_array('loop', $vararray, array('KEY' => 'value')); // Insert vararray at the position where the key 'KEY' has the value of 'value' 376 * alter_block_array('loop', $vararray, false); // Insert vararray at first position 377 * alter_block_array('loop', $vararray, true); // Insert vararray at last position (assign_block_vars equivalence) 378 * 379 * alter_block_array('loop', $vararray, 2, 'change'); // Change/Merge vararray with existing array at position 2 380 * alter_block_array('loop', $vararray, array('KEY' => 'value'), 'change'); // Change/Merge vararray with existing array at the position where the key 'KEY' has the value of 'value' 381 * alter_block_array('loop', $vararray, false, 'change'); // Change/Merge vararray with existing array at first position 382 * alter_block_array('loop', $vararray, true, 'change'); // Change/Merge vararray with existing array at last position 383 * </code> 384 * 385 * @param string $blockname the blockname, for example 'loop' 386 * @param array $vararray the var array to insert/add or merge 387 * @param mixed $key Key to search for 388 * 389 * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] 390 * 391 * int: Position [the position to change or insert at directly given] 392 * 393 * If key is false the position is set to 0 394 * If key is true the position is set to the last entry 395 * 396 * @param insert|change $mode Mode to execute 397 * 398 * If insert, the vararray is inserted at the given position (position counting from zero). 399 * 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). 400 * 401 * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) 402 * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) 403 * 404 * @return false on error, true on success 405 * @access public 406 */ 407 function alter_block_array($blockname, $vararray, $key = false, $mode = 'insert') 408 { 409 if (strpos($blockname, '.') !== false) 410 { 411 // Nested blocks are not supported 412 return false; 413 } 414 415 // Change key to zero (change first position) if false and to last position if true 416 if ($key === false || $key === true) 417 { 418 $key = ($key === false) ? 0 : sizeof($this->_tpldata[$blockname]); 419 } 420 421 // Get correct position if array given 422 if (is_array($key)) 423 { 424 // Search array to get correct position 425 list($search_key, $search_value) = @each($key); 426 427 $key = NULL; 428 foreach ($this->_tpldata[$blockname] as $i => $val_ary) 429 { 430 if ($val_ary[$search_key] === $search_value) 431 { 432 $key = $i; 433 break; 434 } 435 } 436 437 // key/value pair not found 438 if ($key === NULL) 439 { 440 return false; 441 } 442 } 443 444 // Insert Block 445 if ($mode == 'insert') 446 { 447 // Make sure we are not exceeding the last iteration 448 if ($key >= sizeof($this->_tpldata[$blockname])) 449 { 450 $key = sizeof($this->_tpldata[$blockname]); 451 unset($this->_tpldata[$blockname][($key - 1)]['S_LAST_ROW']); 452 $vararray['S_LAST_ROW'] = true; 453 } 454 else if ($key === 0) 455 { 456 unset($this->_tpldata[$blockname][0]['S_FIRST_ROW']); 457 $vararray['S_FIRST_ROW'] = true; 458 } 459 460 // Re-position template blocks 461 for ($i = sizeof($this->_tpldata[$blockname]); $i > $key; $i--) 462 { 463 $this->_tpldata[$blockname][$i] = $this->_tpldata[$blockname][$i-1]; 464 $this->_tpldata[$blockname][$i]['S_ROW_COUNT'] = $i; 465 } 466 467 // Insert vararray at given position 468 $vararray['S_ROW_COUNT'] = $key; 469 $this->_tpldata[$blockname][$key] = $vararray; 470 471 return true; 472 } 473 474 // Which block to change? 475 if ($mode == 'change') 476 { 477 if ($key == sizeof($this->_tpldata[$blockname])) 478 { 479 $key--; 480 } 481 482 $this->_tpldata[$blockname][$key] = array_merge($this->_tpldata[$blockname][$key], $vararray); 483 return true; 484 } 485 486 return false; 487 } 488 489 /** 490 * Include a seperate template 491 * @access private 492 */ 493 function _tpl_include($filename, $include = true) 494 { 495 $handle = $filename; 496 $this->filename[$handle] = $filename; 497 $this->files[$handle] = $this->root . '/' . $filename; 498 499 $filename = $this->_tpl_load($handle); 500 501 if ($include) 502 { 503 global $user; 504 505 if ($filename) 506 { 507 include($filename); 508 return; 509 } 510 eval(' ?>' . $this->compiled_code[$handle] . '<?php '); 511 } 512 } 513 } 514 515 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 22 00:35:05 2006 | Cross-referenced by PHPXref 0.6 |