<?php
/**
* Holds all variables needed for template file
*
* @package frea-framework
* @subpackage Template
*
* @copyright 2009 frea-framework
* @author Dawid Kraczkowski hide@address.com
* @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
*/
class Template_VariableContainer
{
/**
* Hold all variables
*
* @var mixed
*/
static public $vars;
/**
* get the variable form specified path
* @example $some.var
*
* @param string $path
* @return mixed
*/
static public function get($path)
{
//type:$ means local variable, @ means registered loop variable
$type = substr($path,0,1);
$path = explode('.',substr($path,1));
if($type == "$")#normal variable
{
$base = @self::$vars[$type][$path[0]];
}
elseif($type == '@')#loop variable
{
$loopName = $path[0];
$base = self::getItem($loopName);
}
else #return given string
{
return $path;
}
unset($path[0]);
//find variable
foreach ($path as $current)
{
if (is_object($base))
{
// look for method
if (method_exists($base, $current))
{
$base = $base->$current();
continue;
}
// look for variable
if (property_exists($base, $current))
{
$base = $base->$current;
continue;
}
if ($base instanceof ArrayAccess && $base->offsetExists($current))
{
$base = $base->offsetGet($current);
continue;
}
if ($base instanceof Countable && ($current === 'length'))
{
$base = count($base);
continue;
}
}
// array handling
if (is_array($base))
{
// key or index
if (array_key_exists((string)$current, $base))
{
$base = $base[$current];
continue;
}
if ($current == 'length')
{
$base = count($base);
continue;
}
}
// loop additional stuff handling
if( $type == '@')
{
if( $current == "index")
{
$base = self::getIndex($loopName);
continue;
}
if ($current == "odd")
{
$base = self::getIndex($loopName);
$base = (int)$base%2;
continue;
}
}
// string handling
if (is_string($base))
{
if ($current == 'length')
{
$base = strlen($base);
continue;
}
// access char at index
if (is_numeric($current))
{
$base = $base[$current];
continue;
}
}
//if this is reached then variable does not exists
return null;
}
return $base;
}
/**
* set variable
*
* @param string $name
* @param mixed $value
*/
public function __set($name,$value)
{
self::$vars["\$"][$name] = $value;
}
/**
* get variable
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
return self::$vars["\$"][$name];
}
/**
* regiter a new loop
*
* @param string $loopName
* @param string $variable variable path
*/
static public function registerLoop($loopName,$variable)
{
self::$vars["@"][$loopName]['index'] = 0;
if(substr($variable,0,1)=="$") #local variable
{
self::$vars["@"][$loopName]['variable'] = self::get($variable);
}
else #loop variable
{
$parentLoop = substr($variable,1);
self::$vars["@"][$loopName]['variable'] = ¤t(self::$vars["@"][$parentLoop]['variable']);
}
}
/**
* move array pointer to next element
* and increase index
*
* @param string $loopName
* @return bool true if next element exists
*/
static public function nextItem($loopName)
{
self::$vars["@"][$loopName]['index']++;
return next(self::$vars["@"][$loopName]['variable']);
}
/**
* get current array' element
*
* @param string $loopName
* @return mixed
*/
static public function getItem($loopName)
{
return current(self::$vars["@"][$loopName]['variable']);
}
/**
* get index for element
*
* @param string $loopName
* @return int
*/
static public function getIndex($loopName)
{
return self::$vars["@"][$loopName]['index'];
}
/**
* move array pointer to previous element
*
* @param string $loopName
* @return bool
*/
static public function prevItem($loopName)
{
self::$vars["@"][$loopName]['index']--;
return prev(self::$vars["@"][$loopName]['variable']);
}
}