[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |