[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/phpbb/template/ -> context.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  namespace phpbb\template;
  15  
  16  /**
  17  * Stores variables assigned to template.
  18  */
  19  class context
  20  {
  21      /**
  22      * variable that holds all the data we'll be substituting into
  23      * the compiled templates. Takes form:
  24      * --> $this->tpldata[block][iteration#][child][iteration#][child2][iteration#][variablename] == value
  25      * if it's a root-level variable, it'll be like this:
  26      * --> $this->tpldata[.][0][varname] == value
  27      *
  28      * @var array
  29      */
  30      private $tpldata = array('.' => array(0 => array()));
  31  
  32      /**
  33      * @var array Reference to template->tpldata['.'][0]
  34      */
  35      private $rootref;
  36  
  37      /**
  38      * @var bool
  39      */
  40      private $num_rows_is_set;
  41  
  42  	public function __construct()
  43      {
  44          $this->clear();
  45      }
  46  
  47      /**
  48      * Clears template data set.
  49      */
  50  	public function clear()
  51      {
  52          $this->tpldata = array('.' => array(0 => array()));
  53          $this->rootref = &$this->tpldata['.'][0];
  54          $this->num_rows_is_set = false;
  55      }
  56  
  57      /**
  58      * Assign a single scalar value to a single key.
  59      *
  60      * Value can be a string, an integer or a boolean.
  61      *
  62      * @param string $varname Variable name
  63      * @param string $varval Value to assign to variable
  64      * @return true
  65      */
  66  	public function assign_var($varname, $varval)
  67      {
  68          $this->rootref[$varname] = $varval;
  69  
  70          return true;
  71      }
  72  
  73      /**
  74      * Append text to the string value stored in a key.
  75      *
  76      * Text is appended using the string concatenation operator (.).
  77      *
  78      * @param string $varname Variable name
  79      * @param string $varval Value to append to variable
  80      * @return true
  81      */
  82  	public function append_var($varname, $varval)
  83      {
  84          $this->rootref[$varname] = (isset($this->rootref[$varname]) ? $this->rootref[$varname] : '') . $varval;
  85  
  86          return true;
  87      }
  88  
  89      /**
  90      * Returns a reference to template data array.
  91      *
  92      * This function is public so that template renderer may invoke it.
  93      * Users should alter template variables via functions in \phpbb\template\template.
  94      *
  95      * Note: modifying returned array will affect data stored in the context.
  96      *
  97      * @return array template data
  98      */
  99      public function &get_data_ref()
 100      {
 101          // returning a reference directly is not
 102          // something php is capable of doing
 103          $ref = &$this->tpldata;
 104  
 105          if (!$this->num_rows_is_set)
 106          {
 107              /*
 108              * We do not set S_NUM_ROWS while adding a row, to reduce the complexity
 109              * If we would set it on adding, each subsequent adding would cause
 110              * n modifications, resulting in a O(n!) complexity, rather then O(n)
 111              */
 112              foreach ($ref as $loop_name => &$loop_data)
 113              {
 114                  if ($loop_name === '.')
 115                  {
 116                      continue;
 117                  }
 118  
 119                  $this->set_num_rows($loop_data);
 120              }
 121              $this->num_rows_is_set = true;
 122          }
 123  
 124          return $ref;
 125      }
 126  
 127      /**
 128      * Set S_NUM_ROWS for each row in this template block
 129      *
 130      * @param array $loop_data
 131      */
 132  	protected function set_num_rows(&$loop_data)
 133      {
 134          $s_num_rows = sizeof($loop_data);
 135          foreach ($loop_data as &$mod_block)
 136          {
 137              foreach ($mod_block as $sub_block_name => &$sub_block)
 138              {
 139                  // If the key name is lowercase and the data is an array,
 140                  // it could be a template loop. So we set the S_NUM_ROWS there
 141                  // aswell.
 142                  if ($sub_block_name === strtolower($sub_block_name) && is_array($sub_block))
 143                  {
 144                      $this->set_num_rows($sub_block);
 145                  }
 146              }
 147  
 148              // Check whether we are inside a block before setting the variable
 149              if (isset($mod_block['S_BLOCK_NAME']))
 150              {
 151                  $mod_block['S_NUM_ROWS'] = $s_num_rows;
 152              }
 153          }
 154      }
 155  
 156      /**
 157      * Returns a reference to template root scope.
 158      *
 159      * This function is public so that template renderer may invoke it.
 160      * Users should not need to invoke this function.
 161      *
 162      * Note: modifying returned array will affect data stored in the context.
 163      *
 164      * @return array template data
 165      */
 166      public function &get_root_ref()
 167      {
 168          // rootref is already a reference
 169          return $this->rootref;
 170      }
 171  
 172      /**
 173      * Assign key variable pairs from an array to a specified block
 174      *
 175      * @param string $blockname Name of block to assign $vararray to
 176      * @param array $vararray A hash of variable name => value pairs
 177      * @return true
 178      */
 179  	public function assign_block_vars($blockname, array $vararray)
 180      {
 181          $this->num_rows_is_set = false;
 182          if (strpos($blockname, '.') !== false)
 183          {
 184              // Nested block.
 185              $blocks = explode('.', $blockname);
 186              $blockcount = sizeof($blocks) - 1;
 187  
 188              $str = &$this->tpldata;
 189              for ($i = 0; $i < $blockcount; $i++)
 190              {
 191                  $str = &$str[$blocks[$i]];
 192                  $str = &$str[sizeof($str) - 1];
 193              }
 194  
 195              $s_row_count = isset($str[$blocks[$blockcount]]) ? sizeof($str[$blocks[$blockcount]]) : 0;
 196              $vararray['S_ROW_COUNT'] = $vararray['S_ROW_NUM'] = $s_row_count;
 197  
 198              // Assign S_FIRST_ROW
 199              if (!$s_row_count)
 200              {
 201                  $vararray['S_FIRST_ROW'] = true;
 202              }
 203  
 204              // Assign S_BLOCK_NAME
 205              $vararray['S_BLOCK_NAME'] = $blocks[$blockcount];
 206  
 207              // Now the tricky part, we always assign S_LAST_ROW and remove the entry before
 208              // This is much more clever than going through the complete template data on display (phew)
 209              $vararray['S_LAST_ROW'] = true;
 210              if ($s_row_count > 0)
 211              {
 212                  unset($str[$blocks[$blockcount]][($s_row_count - 1)]['S_LAST_ROW']);
 213              }
 214  
 215              // Now we add the block that we're actually assigning to.
 216              // We're adding a new iteration to this block with the given
 217              // variable assignments.
 218              $str[$blocks[$blockcount]][] = $vararray;
 219          }
 220          else
 221          {
 222              // Top-level block.
 223              $s_row_count = (isset($this->tpldata[$blockname])) ? sizeof($this->tpldata[$blockname]) : 0;
 224              $vararray['S_ROW_COUNT'] = $vararray['S_ROW_NUM'] = $s_row_count;
 225  
 226              // Assign S_FIRST_ROW
 227              if (!$s_row_count)
 228              {
 229                  $vararray['S_FIRST_ROW'] = true;
 230              }
 231  
 232              // Assign S_BLOCK_NAME
 233              $vararray['S_BLOCK_NAME'] = $blockname;
 234  
 235              // We always assign S_LAST_ROW and remove the entry before
 236              $vararray['S_LAST_ROW'] = true;
 237              if ($s_row_count > 0)
 238              {
 239                  unset($this->tpldata[$blockname][($s_row_count - 1)]['S_LAST_ROW']);
 240              }
 241  
 242              // Add a new iteration to this block with the variable assignments we were given.
 243              $this->tpldata[$blockname][] = $vararray;
 244          }
 245  
 246          return true;
 247      }
 248  
 249      /**
 250      * Assign key variable pairs from an array to a whole specified block loop
 251      *
 252      * @param string $blockname Name of block to assign $block_vars_array to
 253      * @param array $block_vars_array An array of hashes of variable name => value pairs
 254      * @return true
 255      */
 256  	public function assign_block_vars_array($blockname, array $block_vars_array)
 257      {
 258          foreach ($block_vars_array as $vararray)
 259          {
 260              $this->assign_block_vars($blockname, $vararray);
 261          }
 262  
 263          return true;
 264      }
 265  
 266      /**
 267      * Find the index for a specified key in the innermost specified block
 268      *
 269      * @param    string    $blockname    the blockname, for example 'loop'
 270      * @param    mixed    $key        Key to search for
 271      *
 272      * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position]
 273      *
 274      * int: Position [the position to search for]
 275      *
 276      * If key is false the position is set to 0
 277      * If key is true the position is set to the last entry
 278      *
 279      * @return mixed false if not found, index position otherwise; be sure to test with ===
 280      */
 281  	public function find_key_index($blockname, $key)
 282      {
 283          // For nested block, $blockcount > 0, for top-level block, $blockcount == 0
 284          $blocks = explode('.', $blockname);
 285          $blockcount = sizeof($blocks) - 1;
 286  
 287          $block = $this->tpldata;
 288          for ($i = 0; $i < $blockcount; $i++)
 289          {
 290              if (($pos = strpos($blocks[$i], '[')) !== false)
 291              {
 292                  $name = substr($blocks[$i], 0, $pos);
 293  
 294                  if (strpos($blocks[$i], '[]') === $pos)
 295                  {
 296                      $index = sizeof($block[$name]) - 1;
 297                  }
 298                  else
 299                  {
 300                      $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
 301                  }
 302              }
 303              else
 304              {
 305                  $name = $blocks[$i];
 306                  $index = sizeof($block[$name]) - 1;
 307              }
 308              if (!isset($block[$name]))
 309              {
 310                  return false;
 311              }
 312              $block = $block[$name];
 313              if (!isset($block[$index]))
 314              {
 315                  return false;
 316              }
 317              $block = $block[$index];
 318          }
 319  
 320          if (!isset($block[$blocks[$i]]))
 321          {
 322              return false;
 323          }
 324          $block = $block[$blocks[$i]]; // Traverse the last block
 325  
 326          // Change key to zero (change first position) if false and to last position if true
 327          if ($key === false || $key === true)
 328          {
 329              return ($key === false) ? 0 : sizeof($block) - 1;
 330          }
 331  
 332          // Get correct position if array given
 333          if (is_array($key))
 334          {
 335              // Search array to get correct position
 336              list($search_key, $search_value) = @each($key);
 337              foreach ($block as $i => $val_ary)
 338              {
 339                  if ($val_ary[$search_key] === $search_value)
 340                  {
 341                      return $i;
 342                  }
 343              }
 344          }
 345  
 346          return (is_int($key) && ((0 <= $key) && ($key < sizeof($block)))) ? $key : false;
 347      }
 348  
 349      /**
 350      * Change already assigned key variable pair (one-dimensional - single loop entry)
 351      *
 352      * An example of how to use this function:
 353      * {@example alter_block_array.php}
 354      *
 355      * @param    string    $blockname    the blockname, for example 'loop'
 356      * @param    array    $vararray    the var array to insert/add or merge
 357      * @param    mixed    $key        Key to search for
 358      *
 359      * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position]
 360      *
 361      * int: Position [the position to change or insert at directly given]
 362      *
 363      * If key is false the position is set to 0
 364      * If key is true the position is set to the last entry
 365      *
 366      * @param    string    $mode        Mode to execute (valid modes are 'insert' and 'change')
 367      *
 368      *    If insert, the vararray is inserted at the given position (position counting from zero).
 369      *    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).
 370      *
 371      * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array)
 372      * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars)
 373      *
 374      * @return bool false on error, true on success
 375      */
 376  	public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert')
 377      {
 378          $this->num_rows_is_set = false;
 379  
 380          // For nested block, $blockcount > 0, for top-level block, $blockcount == 0
 381          $blocks = explode('.', $blockname);
 382          $blockcount = sizeof($blocks) - 1;
 383  
 384          $block = &$this->tpldata;
 385          for ($i = 0; $i < $blockcount; $i++)
 386          {
 387              if (($pos = strpos($blocks[$i], '[')) !== false)
 388              {
 389                  $name = substr($blocks[$i], 0, $pos);
 390  
 391                  if (strpos($blocks[$i], '[]') === $pos)
 392                  {
 393                      $index = sizeof($block[$name]) - 1;
 394                  }
 395                  else
 396                  {
 397                      $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
 398                  }
 399              }
 400              else
 401              {
 402                  $name = $blocks[$i];
 403                  $index = sizeof($block[$name]) - 1;
 404              }
 405              $block = &$block[$name];
 406              $block = &$block[$index];
 407          }
 408          $name = $blocks[$i];
 409  
 410          // If last block does not exist and we are inserting, and not searching for key, we create it empty; otherwise, nothing to do
 411          if (!isset($block[$name]))
 412          {
 413              if ($mode != 'insert' || is_array($key))
 414              {
 415                  return false;
 416              }
 417              $block[$name] = array();
 418          }
 419  
 420          $block = &$block[$name]; // Now we can traverse the last block
 421  
 422          // Change key to zero (change first position) if false and to last position if true
 423          if ($key === false || $key === true)
 424          {
 425              $key = ($key === false) ? 0 : sizeof($block);
 426          }
 427  
 428          // Get correct position if array given
 429          if (is_array($key))
 430          {
 431              // Search array to get correct position
 432              list($search_key, $search_value) = @each($key);
 433  
 434              $key = null;
 435              foreach ($block as $i => $val_ary)
 436              {
 437                  if ($val_ary[$search_key] === $search_value)
 438                  {
 439                      $key = $i;
 440                      break;
 441                  }
 442              }
 443  
 444              // key/value pair not found
 445              if ($key === null)
 446              {
 447                  return false;
 448              }
 449          }
 450  
 451          // Insert Block
 452          if ($mode == 'insert')
 453          {
 454              // Make sure we are not exceeding the last iteration
 455              if ($key >= sizeof($block))
 456              {
 457                  $key = sizeof($block);
 458                  unset($block[($key - 1)]['S_LAST_ROW']);
 459                  $vararray['S_LAST_ROW'] = true;
 460              }
 461              if ($key <= 0)
 462              {
 463                  $key = 0;
 464                  unset($block[0]['S_FIRST_ROW']);
 465                  $vararray['S_FIRST_ROW'] = true;
 466              }
 467  
 468              // Assign S_BLOCK_NAME
 469              $vararray['S_BLOCK_NAME'] = $name;
 470  
 471              // Re-position template blocks
 472              for ($i = sizeof($block); $i > $key; $i--)
 473              {
 474                  $block[$i] = $block[$i-1];
 475  
 476                  $block[$i]['S_ROW_COUNT'] = $block[$i]['S_ROW_NUM'] = $i;
 477              }
 478  
 479              // Insert vararray at given position
 480              $block[$key] = $vararray;
 481              $block[$key]['S_ROW_COUNT'] = $block[$key]['S_ROW_NUM'] = $key;
 482  
 483              return true;
 484          }
 485  
 486          // Which block to change?
 487          if ($mode == 'change')
 488          {
 489              // If key is out of bounds, do not change anything
 490              if ($key > sizeof($block) || $key < 0)
 491              {
 492                  return false;
 493              }
 494  
 495              if ($key == sizeof($block))
 496              {
 497                  $key--;
 498              }
 499  
 500              $block[$key] = array_merge($block[$key], $vararray);
 501  
 502              return true;
 503          }
 504  
 505          return false;
 506      }
 507  
 508      /**
 509      * Reset/empty complete block
 510      *
 511      * @param string $blockname Name of block to destroy
 512      * @return true
 513      */
 514  	public function destroy_block_vars($blockname)
 515      {
 516          $this->num_rows_is_set = false;
 517          if (strpos($blockname, '.') !== false)
 518          {
 519              // Nested block.
 520              $blocks = explode('.', $blockname);
 521              $blockcount = sizeof($blocks) - 1;
 522  
 523              $str = &$this->tpldata;
 524              for ($i = 0; $i < $blockcount; $i++)
 525              {
 526                  $str = &$str[$blocks[$i]];
 527                  $str = &$str[sizeof($str) - 1];
 528              }
 529  
 530              unset($str[$blocks[$blockcount]]);
 531          }
 532          else
 533          {
 534              // Top-level block.
 535              unset($this->tpldata[$blockname]);
 536          }
 537  
 538          return true;
 539      }
 540  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1