diff options
Diffstat (limited to 'phpBB/includes/template/context.php')
| -rw-r--r-- | phpBB/includes/template/context.php | 342 | 
1 files changed, 342 insertions, 0 deletions
| diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php new file mode 100644 index 0000000000..f85f86a0ec --- /dev/null +++ b/phpBB/includes/template/context.php @@ -0,0 +1,342 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ +	exit; +} + +/** +* Stores variables assigned to template. +* +* @package phpBB3 +*/ +class phpbb_template_context +{ +	/** +	* variable that holds all the data we'll be substituting into +	* the compiled templates. Takes form: +	* --> $this->tpldata[block][iteration#][child][iteration#][child2][iteration#][variablename] == value +	* if it's a root-level variable, it'll be like this: +	* --> $this->tpldata[.][0][varname] == value +	* +	* @var array +	*/ +	private $tpldata = array('.' => array(0 => array())); + +	/** +	* @var array Reference to template->tpldata['.'][0] +	*/ +	private $rootref; + +	public function __construct() +	{ +		$this->clear(); +	} + +	/** +	* Clears template data set. +	*/ +	public function clear() +	{ +		$this->tpldata = array('.' => array(0 => array())); +		$this->rootref = &$this->tpldata['.'][0]; +	} + +	/** +	* Assign a single variable to a single key +	* +	* @param string $varname Variable name +	* @param string $varval Value to assign to variable +	*/ +	public function assign_var($varname, $varval) +	{ +		$this->rootref[$varname] = $varval; + +		return true; +	} + +	/** +	* Returns a reference to template data array. +	* +	* This function is public so that template renderer may invoke it. +	* Users should alter template variables via functions in phpbb_template. +	* +	* Note: modifying returned array will affect data stored in the context. +	* +	* @return array template data +	*/ +	public function &get_data_ref() +	{ +		// returning a reference directly is not +		// something php is capable of doing +		$ref = &$this->tpldata; +		return $ref; +	} + +	/** +	* Returns a reference to template root scope. +	* +	* This function is public so that template renderer may invoke it. +	* Users should not need to invoke this function. +	* +	* Note: modifying returned array will affect data stored in the context. +	* +	* @return array template data +	*/ +	public function &get_root_ref() +	{ +		// rootref is already a reference +		return $this->rootref; +	} + +	/** +	* Assign key variable pairs from an array to a specified block +	* +	* @param string $blockname Name of block to assign $vararray to +	* @param array $vararray A hash of variable name => value pairs +	*/ +	public function assign_block_vars($blockname, array $vararray) +	{ +		if (strpos($blockname, '.') !== false) +		{ +			// Nested block. +			$blocks = explode('.', $blockname); +			$blockcount = sizeof($blocks) - 1; + +			$str = &$this->tpldata; +			for ($i = 0; $i < $blockcount; $i++) +			{ +				$str = &$str[$blocks[$i]]; +				$str = &$str[sizeof($str) - 1]; +			} + +			$s_row_count = isset($str[$blocks[$blockcount]]) ? sizeof($str[$blocks[$blockcount]]) : 0; +			$vararray['S_ROW_COUNT'] = $s_row_count; + +			// Assign S_FIRST_ROW +			if (!$s_row_count) +			{ +				$vararray['S_FIRST_ROW'] = true; +			} + +			// Now the tricky part, we always assign S_LAST_ROW and remove the entry before +			// This is much more clever than going through the complete template data on display (phew) +			$vararray['S_LAST_ROW'] = true; +			if ($s_row_count > 0) +			{ +				unset($str[$blocks[$blockcount]][($s_row_count - 1)]['S_LAST_ROW']); +			} + +			// Now we add the block that we're actually assigning to. +			// We're adding a new iteration to this block with the given +			// variable assignments. +			$str[$blocks[$blockcount]][] = $vararray; +		} +		else +		{ +			// Top-level block. +			$s_row_count = (isset($this->tpldata[$blockname])) ? sizeof($this->tpldata[$blockname]) : 0; +			$vararray['S_ROW_COUNT'] = $s_row_count; + +			// Assign S_FIRST_ROW +			if (!$s_row_count) +			{ +				$vararray['S_FIRST_ROW'] = true; +			} + +			// We always assign S_LAST_ROW and remove the entry before +			$vararray['S_LAST_ROW'] = true; +			if ($s_row_count > 0) +			{ +				unset($this->tpldata[$blockname][($s_row_count - 1)]['S_LAST_ROW']); +			} + +			// Add a new iteration to this block with the variable assignments we were given. +			$this->tpldata[$blockname][] = $vararray; +		} + +		return true; +	} + +	/** +	* Change already assigned key variable pair (one-dimensional - single loop entry) +	* +	* An example of how to use this function: +	* {@example alter_block_array.php} +	* +	* @param	string	$blockname	the blockname, for example 'loop' +	* @param	array	$vararray	the var array to insert/add or merge +	* @param	mixed	$key		Key to search for +	* +	* array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] +	* +	* int: Position [the position to change or insert at directly given] +	* +	* If key is false the position is set to 0 +	* If key is true the position is set to the last entry +	* +	* @param	string	$mode		Mode to execute (valid modes are 'insert' and 'change') +	* +	*	If insert, the vararray is inserted at the given position (position counting from zero). +	*	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). +	* +	* Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) +	* and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) +	* +	* @return bool false on error, true on success +	*/ +	public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') +	{ +		if (strpos($blockname, '.') !== false) +		{ +			// Nested block. +			$blocks = explode('.', $blockname); +			$blockcount = sizeof($blocks) - 1; + +			$block = &$this->tpldata; +			for ($i = 0; $i < $blockcount; $i++) +			{ +				if (($pos = strpos($blocks[$i], '[')) !== false) +				{ +					$name = substr($blocks[$i], 0, $pos); + +					if (strpos($blocks[$i], '[]') === $pos) +					{ +						$index = sizeof($block[$name]) - 1; +					} +					else +					{ +						$index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1); +					} +				} +				else +				{ +					$name = $blocks[$i]; +					$index = sizeof($block[$name]) - 1; +				} +				$block = &$block[$name]; +				$block = &$block[$index]; +			} + +			$block = &$block[$blocks[$i]]; // Traverse the last block +		} +		else +		{ +			// Top-level block. +			$block = &$this->tpldata[$blockname]; +		} + +		// Change key to zero (change first position) if false and to last position if true +		if ($key === false || $key === true) +		{ +			$key = ($key === false) ? 0 : sizeof($block); +		} + +		// Get correct position if array given +		if (is_array($key)) +		{ +			// Search array to get correct position +			list($search_key, $search_value) = @each($key); + +			$key = NULL; +			foreach ($block as $i => $val_ary) +			{ +				if ($val_ary[$search_key] === $search_value) +				{ +					$key = $i; +					break; +				} +			} + +			// key/value pair not found +			if ($key === NULL) +			{ +				return false; +			} +		} + +		// Insert Block +		if ($mode == 'insert') +		{ +			// Make sure we are not exceeding the last iteration +			if ($key >= sizeof($this->tpldata[$blockname])) +			{ +				$key = sizeof($this->tpldata[$blockname]); +				unset($this->tpldata[$blockname][($key - 1)]['S_LAST_ROW']); +				$vararray['S_LAST_ROW'] = true; +			} +			else if ($key === 0) +			{ +				unset($this->tpldata[$blockname][0]['S_FIRST_ROW']); +				$vararray['S_FIRST_ROW'] = true; +			} + +			// Re-position template blocks +			for ($i = sizeof($block); $i > $key; $i--) +			{ +				$block[$i] = $block[$i-1]; +			} + +			// Insert vararray at given position +			$block[$key] = $vararray; + +			return true; +		} + +		// Which block to change? +		if ($mode == 'change') +		{ +			if ($key == sizeof($block)) +			{ +				$key--; +			} + +			$block[$key] = array_merge($block[$key], $vararray); + +			return true; +		} + +		return false; +	} + +	/** +	* Reset/empty complete block +	* +	* @param string $blockname Name of block to destroy +	*/ +	public function destroy_block_vars($blockname) +	{ +		if (strpos($blockname, '.') !== false) +		{ +			// Nested block. +			$blocks = explode('.', $blockname); +			$blockcount = sizeof($blocks) - 1; + +			$str = &$this->tpldata; +			for ($i = 0; $i < $blockcount; $i++) +			{ +				$str = &$str[$blocks[$i]]; +				$str = &$str[sizeof($str) - 1]; +			} + +			unset($str[$blocks[$blockcount]]); +		} +		else +		{ +			// Top-level block. +			unset($this->tpldata[$blockname]); +		} + +		return true; +	} +} | 
