[ Index ]

PHP Cross Reference of phpBB 3.0 Beta 3

title

Body

[close]

/includes/ -> template.php (source)

   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  ?>


Generated: Wed Nov 22 00:35:05 2006 Cross-referenced by PHPXref 0.6