$getter();
}
else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
{
$name=strtolower($name);
if(!isset($this->_e[$name]))
$this->_e[$name]=new TList;
return $this->_e[$name];
}
else
{
throw new TInvalidOperationException('component_property_undefined',get_class($this),$name);
}
}
public function __set($name,$value)
{
$setter='set'.$name;
if(method_exists($this,$setter))
{
$this->$setter($value);
}
else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
{
$this->attachEventHandler($name,$value);
}
else if(method_exists($this,'get'.$name))
{
throw new TInvalidOperationException('component_property_readonly',get_class($this),$name);
}
else
{
throw new TInvalidOperationException('component_property_undefined',get_class($this),$name);
}
}
public function hasProperty($name)
{
return method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
}
public function canGetProperty($name)
{
return method_exists($this,'get'.$name);
}
public function canSetProperty($name)
{
return method_exists($this,'set'.$name);
}
public function getSubProperty($path)
{
$object=$this;
foreach(explode('.',$path) as $property)
$object=$object->$property;
return $object;
}
public function setSubProperty($path,$value)
{
$object=$this;
if(($pos=strrpos($path,'.'))===false)
$property=$path;
else
{
$object=$this->getSubProperty(substr($path,0,$pos));
$property=substr($path,$pos+1);
}
$object->$property=$value;
}
public function hasEvent($name)
{
return strncasecmp($name,'on',2)===0 && method_exists($this,$name);
}
public function hasEventHandler($name)
{
$name=strtolower($name);
return isset($this->_e[$name]) && $this->_e[$name]->getCount()>0;
}
public function getEventHandlers($name)
{
if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
{
$name=strtolower($name);
if(!isset($this->_e[$name]))
$this->_e[$name]=new TList;
return $this->_e[$name];
}
else
throw new TInvalidOperationException('component_event_undefined',get_class($this),$name);
}
public function attachEventHandler($name,$handler)
{
$this->getEventHandlers($name)->add($handler);
}
public function detachEventHandler($name,$handler)
{
if($this->hasEventHandler($name))
{
try
{
$this->getEventHandlers($name)->remove($handler);
return true;
}
catch(Exception $e)
{
}
}
return false;
}
public function raiseEvent($name,$sender,$param)
{
$name=strtolower($name);
if(isset($this->_e[$name]))
{
foreach($this->_e[$name] as $handler)
{
if(is_string($handler))
{
call_user_func($handler,$sender,$param);
}
else if(is_callable($handler,true))
{
list($object,$method)=$handler;
if(is_string($object)) call_user_func($handler,$sender,$param);
else
{
if(($pos=strrpos($method,'.'))!==false)
{
$object=$this->getSubProperty(substr($method,0,$pos));
$method=substr($method,$pos+1);
}
$object->$method($sender,$param);
}
}
else
throw new TInvalidDataValueException('component_eventhandler_invalid',get_class($this),$name);
}
}
else if(!$this->hasEvent($name))
throw new TInvalidOperationException('component_event_undefined',get_class($this),$name);
}
public function evaluateExpression($expression)
{
try
{
if(eval("\$result=$expression;")===false)
throw new Exception('');
return $result;
}
catch(Exception $e)
{
throw new TInvalidOperationException('component_expression_invalid',get_class($this),$expression,$e->getMessage());
}
}
public function evaluateStatements($statements)
{
try
{
ob_start();
if(eval($statements)===false)
throw new Exception('');
$content=ob_get_contents();
ob_end_clean();
return $content;
}
catch(Exception $e)
{
throw new TInvalidOperationException('component_statements_invalid',get_class($this),$statements,$e->getMessage());
}
}
public function getApplication()
{
return Prado::getApplication();
}
public function getService()
{
return Prado::getApplication()->getService();
}
public function getRequest()
{
return Prado::getApplication()->getRequest();
}
public function getResponse()
{
return Prado::getApplication()->getResponse();
}
public function getSession()
{
return Prado::getApplication()->getSession();
}
public function getUser()
{
return Prado::getApplication()->getUser();
}
}
class TPropertyValue
{
public static function ensureBoolean($value)
{
if (is_string($value))
return strcasecmp($value,'true')==0 || $value!=0;
else
return (boolean)$value;
}
public static function ensureString($value)
{
if (is_bool($value))
return $value?'true':'false';
else
return (string)$value;
}
public static function ensureInteger($value)
{
return (integer)$value;
}
public static function ensureFloat($value)
{
return (float)$value;
}
public static function ensureArray($value)
{
if(is_string($value))
{
$trimmed = trim($value);
$len = strlen($value);
if ($len >= 2 && $trimmed[0] == '(' && $trimmed[$len-1] == ')')
{
eval('$array=array'.$trimmed.';');
return $array;
}
else
return $len>0?array($value):array();
}
else
return (array)$value;
}
public static function ensureObject($value)
{
return (object)$value;
}
public static function ensureEnum($value,$enums)
{
if(!is_array($enums))
{
$enums=func_get_args();
array_shift($enums);
}
if(in_array($value,$enums,true))
return $value;
else
throw new TInvalidDataValueException('propertyvalue_enumvalue_invalid',$value,implode(' | ',$enums));
}
}
class TEventParameter extends TComponent
{
}
?>_errorCode=$errorMessage;
$args=func_get_args();
$args[0]=$this->translateErrorMessage($errorMessage);
$str=call_user_func_array('sprintf',$args);
parent::__construct($str);
}
protected function translateErrorMessage($key)
{
$lang=Prado::getPreferredLanguage();
$msgFile=Prado::getFrameworkPath().'/Exceptions/messages-'.$lang.'.txt';
if(!is_file($msgFile))
$msgFile=Prado::getFrameworkPath().'/Exceptions/messages.txt';
if(($entries=@file($msgFile))===false)
return $key;
else
{
foreach($entries as $entry)
{
@list($code,$message)=explode('=',$entry,2);
if(trim($code)===$key)
return trim($message);
}
return $key;
}
}
public function getErrorCode()
{
return $this->_errorCode;
}
public function getErrorMessage()
{
return $this->getMessage();
}
}
class TSystemException extends TException
{
}
class TApplicationException extends TException
{
}
class TInvalidOperationException extends TSystemException
{
}
class TInvalidDataTypeException extends TSystemException
{
}
class TInvalidDataValueException extends TSystemException
{
}
class TInvalidDataFormatException extends TSystemException
{
}
class TConfigurationException extends TSystemException
{
}
class TIOException extends TSystemException
{
}
class TDBException extends TSystemException
{
}
class TSecurityException extends TSystemException
{
}
class TNotSupportedException extends TSystemException
{
}
class TTemplateParsingException extends TSystemException
{
}
class TTemplateRuntimeException extends TSystemException
{
}
class TPhpErrorException extends TException
{
public function __construct($errno,$errstr,$errfile,$errline)
{
static $errorTypes=array(
E_ERROR => "Error",
E_WARNING => "Warning",
E_PARSE => "Parsing Error",
E_NOTICE => "Notice",
E_CORE_ERROR => "Core Error",
E_CORE_WARNING => "Core Warning",
E_COMPILE_ERROR => "Compile Error",
E_COMPILE_WARNING => "Compile Warning",
E_USER_ERROR => "User Error",
E_USER_WARNING => "User Warning",
E_USER_NOTICE => "User Notice",
E_STRICT => "Runtime Notice"
);
$errorType=isset($errorTypes[$errno])?$errorTypes[$errno]:'Unknown Error';
parent::__construct("[$errorType] $errstr (@line $errline in file $errfile).");
}
}
class THttpException extends TException
{
private $_statusCode;
public function __construct($statusCode,$errorMessage)
{
$args=func_get_args();
array_shift($args);
call_user_func_array(array('TException', '__construct'), $args);
$this->_statusCode=TPropertyValue::ensureInteger($statusCode);
}
public function getStatusCode()
{
return $this->_statusCode;
}
}
?>copyFrom($data);
}
public function getIterator()
{
return new TListIterator($this->_d);
}
public function getCount()
{
return $this->_c;
}
public function itemAt($index)
{
if(isset($this->_d[$index]))
return $this->_d[$index];
else
throw new TInvalidDataValueException('list_index_invalid',$index);
}
public function add($item)
{
if($this->canAddItem($item))
{
$this->_d[$this->_c++]=$item;
$this->addedItem($item);
}
else
throw new TInvalidOperationException('list_addition_disallowed');
}
public function insert($index,$item)
{
if($this->canAddItem($item))
{
if($index===$this->_c)
$this->add($item);
else if($index>=0 && $index<$this->_c)
{
array_splice($this->_d,$index,0,array($item));
$this->_c++;
$this->addedItem($item);
}
else
throw new TInvalidDataValueException('list_index_invalid',$index);
}
else
throw new TInvalidOperationException('list_addition_disallowed');
}
public function remove($item)
{
if(($index=$this->indexOf($item))>=0)
{
if($this->canRemoveItem($item))
$this->removeAt($index);
else
throw new TInvalidOperationException('list_item_unremovable');
}
else
throw new TInvalidDataValueException('list_item_inexistent');
}
public function removeAt($index)
{
if(isset($this->_d[$index]))
{
$item=$this->_d[$index];
if($this->canRemoveItem($item))
{
if($index===$this->_c-1)
unset($this->_d[$index]);
else
array_splice($this->_d,$index,1);
$this->_c--;
$this->removedItem($item);
return $item;
}
else
throw new TInvalidOperationException('list_item_unremovable');
}
else
throw new TInvalidDataValueException('list_index_invalid',$index);
}
public function clear()
{
for($i=$this->_c-1;$i>=0;--$i)
$this->removeAt($i);
}
public function contains($item)
{
return $this->indexOf($item)>=0;
}
public function indexOf($item)
{
if(($index=array_search($item,$this->_d,true))===false)
return -1;
else
return $index;
}
public function toArray()
{
return $this->_d;
}
public function copyFrom($data)
{
if(is_array($data) || ($data instanceof Traversable))
{
if($this->_c>0)
$this->clear();
foreach($data as $item)
$this->add($item);
}
else if($data!==null)
throw new TInvalidDataTypeException('list_data_not_iterable');
}
public function mergeWith($data)
{
if(is_array($data) || ($data instanceof Traversable))
{
foreach($data as $item)
$this->add($item);
}
else if($data!==null)
throw new TInvalidDataTypeException('list_data_not_iterable');
}
public function offsetExists($offset)
{
return isset($this->_d[$offset]);
}
public function offsetGet($offset)
{
if(isset($this->_d[$offset]))
return $this->_d[$offset];
else
throw new TInvalidDataValueException('list_index_invalid',$offset);
}
public function offsetSet($offset,$item)
{
if($offset===null || $offset===$this->_c)
$this->add($item);
else
{
$this->removeAt($offset);
$this->insert($offset,$item);
}
}
public function offsetUnset($offset)
{
$this->removeAt($offset);
}
protected function addedItem($item)
{
}
protected function removedItem($item)
{
}
protected function canAddItem($item)
{
return true;
}
protected function canRemoveItem($item)
{
return true;
}
}
class TListIterator implements Iterator
{
private $_d;
private $_i;
public function __construct(&$data)
{
$this->_d=&$data;
$this->_i=0;
}
public function rewind()
{
$this->_i=0;
}
public function key()
{
return $this->_i;
}
public function current()
{
return $this->_d[$this->_i];
}
public function next()
{
$this->_i++;
}
public function valid()
{
return isset($this->_d[$this->_i]);
}
}
?>copyFrom($data);
}
public function getIterator()
{
return new TMapIterator($this->_d);
}
public function getCount()
{
return count($this->_d);
}
public function getKeys()
{
return array_keys($this->_d);
}
public function itemAt($key)
{
return isset($this->_d[$key]) ? $this->_d[$key] : null;
}
public function add($key,$value)
{
if($this->canAddItem($key,$value))
{
if(isset($this->_d[$key]))
$this->remove($key);
$this->_d[$key]=$value;
$this->addedItem($key,$value);
}
else
throw new TInvalidOperationException('map_addition_disallowed');
}
public function remove($key)
{
if(isset($this->_d[$key]))
{
$value=$this->_d[$key];
if($this->canRemoveItem($key,$value))
{
unset($this->_d[$key]);
$this->removedItem($key,$value);
return $value;
}
else
throw new TInvalidOperationException('map_item_unremovable');
}
else
return null;
}
public function clear()
{
foreach(array_keys($this->_d) as $key)
$this->remove($key);
}
public function contains($key)
{
return isset($this->_d[$key]);
}
public function toArray()
{
return $this->_d;
}
public function copyFrom($data)
{
if(is_array($data) || $data instanceof Traversable)
{
if($this->getCount()>0)
$this->clear();
foreach($data as $key=>$value)
$this->add($key,$value);
}
else if($data!==null)
throw new TInvalidDataTypeException('map_data_not_iterable');
}
public function mergeWith($data)
{
if(is_array($data) || $data instanceof Traversable)
{
foreach($data as $key=>$value)
$this->add($key,$value);
}
else if($data!==null)
throw new TInvalidDataTypeException('map_data_not_iterable');
}
public function offsetExists($offset)
{
return $this->contains($offset);
}
public function offsetGet($offset)
{
return isset($this->_d[$offset]) ? $this->_d[$offset] : null;
}
public function offsetSet($offset,$item)
{
$this->add($offset,$item);
}
public function offsetUnset($offset)
{
$this->remove($offset);
}
protected function addedItem($key,$item)
{
}
protected function removedItem($key,$item)
{
}
protected function canAddItem($key,$item)
{
return true;
}
protected function canRemoveItem($key,$item)
{
return true;
}
}
class TMapIterator implements Iterator
{
private $_d;
private $_keys;
private $_key;
public function __construct(&$data)
{
$this->_d=&$data;
$this->_keys=array_keys($data);
}
public function rewind()
{
$this->_key=reset($this->_keys);
}
public function key()
{
return $this->_key;
}
public function current()
{
return $this->_d[$this->_key];
}
public function next()
{
do
{
$this->_key=next($this->_keys);
}
while(!isset($this->_d[$this->_key]) && $this->_key!==false);
}
public function valid()
{
return $this->_key!==false;
}
}
?>contains($name)?$this->itemAt($name):parent::__get($name);
}
public function __set($name,$value)
{
$this->add(strtolower($name),$value);
}
public function hasProperty($name)
{
$name=strtolower($name);
return $this->contains($name) || parent::hasProperty($name);
}
public function canGetProperty($name)
{
$name=strtolower($name);
return $this->contains($name) || parent::canGetProperty($name);
}
public function canSetProperty($name)
{
return true;
}
}
?>setTagName($tagName);
}
public function getParent()
{
return $this->_parent;
}
public function setParent($parent)
{
$this->_parent=$parent;
}
public function getTagName()
{
return $this->_tagName;
}
public function setTagName($tagName)
{
$this->_tagName=$tagName;
}
public function getValue()
{
return $this->_value;
}
public function setValue($value)
{
$this->_value=$value;
}
public function getHasElement()
{
return $this->_elements!==null && $this->_elements->getCount()>0;
}
public function getHasAttribute()
{
return $this->_attributes!==null && $this->_attributes->getCount()>0;
}
public function getAttribute($name)
{
if($this->_attributes!==null)
return $this->_attributes->itemAt($name);
else
return null;
}
public function getElements()
{
if(!$this->_elements)
$this->_elements=new TXmlElementList($this);
return $this->_elements;
}
public function getAttributes()
{
if(!$this->_attributes)
$this->_attributes=new TMap;
return $this->_attributes;
}
public function getElementByTagName($tagName)
{
if($this->_elements)
{
foreach($this->_elements as $element)
if($element->_tagName===$tagName)
return $element;
}
return null;
}
public function getElementsByTagName($tagName)
{
$list=new TList;
if($this->_elements)
{
foreach($this->_elements as $element)
if($element->_tagName===$tagName)
$list->add($element);
}
return $list;
}
public function toString($indent=0)
{
$attr='';
if($this->_attributes!==null)
{
foreach($this->_attributes as $name=>$value)
$attr.=" $name=\"$value\"";
}
$prefix=str_repeat(' ',$indent*4);
if($this->getHasElement())
{
$str=$prefix."<{$this->_tagName}$attr>\n";
foreach($this->getElements() as $element)
$str.=$element->toString($indent+1)."\n";
$str.=$prefix."{$this->_tagName}>";
return $str;
}
else if($this->getValue()!=='')
{
return $prefix."<{$this->_tagName}$attr>{$this->_value}{$this->_tagName}>";
}
else
return $prefix."<{$this->_tagName}$attr />";
}
}
class TXmlDocument extends TXmlElement
{
private $_version;
private $_encoding;
public function __construct($version='1.0',$encoding='')
{
parent::__construct('');
$this->setversion($version);
$this->setEncoding($encoding);
}
public function getVersion()
{
return $this->_version;
}
public function setVersion($version)
{
$this->_version=$version;
}
public function getEncoding()
{
return $this->_encoding;
}
public function setEncoding($encoding)
{
$this->_encoding=$encoding;
}
public function loadFromFile($file)
{
if(($str=@file_get_contents($file))!==false)
return $this->loadFromString($str);
else
throw new TIOException('xmldocument_file_read_failed',$file);
}
public function loadFromString($string)
{
$doc=new DOMDocument();
if($doc->loadXML($string)===false)
return false;
$this->setEncoding($doc->encoding);
$this->setVersion($doc->version);
$element=$doc->documentElement;
$this->setTagName($element->tagName);
$this->setValue($element->nodeValue);
$elements=$this->getElements();
$attributes=$this->getAttributes();
$elements->clear();
$attributes->clear();
foreach($element->attributes as $name=>$attr)
$attributes->add($name,$attr->value);
foreach($element->childNodes as $child)
{
if($child instanceof DOMElement)
$elements->add($this->buildElement($child));
}
return true;
}
public function saveToFile($file)
{
if(($fw=fopen($file,'w'))!==false)
{
fwrite($fw,$this->saveToString());
fclose($fw);
}
else
throw new TIOException('xmldocument_file_write_failed',$file);
}
public function saveToString()
{
$version=empty($this->_version)?' version="1.0"':' version="'.$this->_version.'"';
$encoding=empty($this->_encoding)?'':' encoding="'.$this->_encoding.'"';
return "\n".$this->toString(0);
}
private function buildElement($node)
{
$element=new TXmlElement($node->tagName);
$element->setValue($node->nodeValue);
foreach($node->attributes as $name=>$attr)
$element->getAttributes()->add($name,$attr->value);
foreach($node->childNodes as $child)
{
if($child instanceof DOMElement)
$element->getElements()->add($this->buildElement($child));
}
return $element;
}
}
class TXmlElementList extends TList
{
private $_o;
public function __construct(TXmlElement $owner)
{
parent::__construct();
$this->_o=$owner;
}
protected function getOwner()
{
return $this->_o;
}
protected function addedItem($item)
{
if($item->getParent()!==null)
$item->getParent()->getElements()->remove($item);
$item->setParent($this->_o);
}
protected function removedItem($item)
{
$item->setParent(null);
}
protected function canAddItem($item)
{
return ($item instanceof TXmlElement);
}
}
?>'%25',"\t"=>'\t',"\n"=>'\n',"\r"=>'\r','"'=>'\"','\''=>'\\\'','\\'=>'\\\\'));
else
return strtr($js,array("\t"=>'\t',"\n"=>'\n',"\r"=>'\r','"'=>'\"','\''=>'\\\'','\\'=>'\\\\'));
}
public static function trimJavaScriptString($js)
{
if($js!=='' && $js!==null)
{
$js=trim($js);
if(($pos=strpos($js,'javascript:'))===0)
$js=substr($js,11);
$js=rtrim($js,';').';';
}
return $js;
}
}
?>_logs[]=array($message,$level,$category,microtime(true));
}
public function getLogs($levels=null,$categories=null)
{
$this->_levels=$levels;
$this->_categories=$categories;
if(empty($levels) && empty($categories))
return $this->_logs;
else if(empty($levels))
return array_values(array_filter(array_filter($this->_logs,array($this,'filterByCategories'))));
else if(empty($categories))
return array_values(array_filter(array_filter($this->_logs,array($this,'filterByLevels'))));
else
{
$ret=array_values(array_filter(array_filter($this->_logs,array($this,'filterByLevels'))));
return array_values(array_filter(array_filter($ret,array($this,'filterByCategories'))));
}
}
private function filterByCategories($value)
{
foreach($this->_categories as $category)
{
if($value[2]===$category || strpos($value[2],$category.'.')===0)
return $value;
}
return false;
}
private function filterByLevels($value)
{
if($value[1] & $this->_levels)
return $value;
else
return false;
}
}
?>_id;
}
public function setID($value)
{
$this->_id=$value;
}
}
abstract class TService extends TComponent implements IService
{
private $_id;
public function init($config)
{
}
public function getID()
{
return $this->_id;
}
public function setID($value)
{
$this->_id=$value;
}
public function run()
{
}
}
class PradoBase
{
const CLASS_FILE_EXT='.php';
private static $_aliases=array('System'=>PRADO_DIR);
private static $_usings=array();
private static $_application=null;
private static $_logger=null;
public static function getVersion()
{
return '3.0b';
}
public static function poweredByPrado()
{
return '';
}
public static function phpErrorHandler($errno,$errstr,$errfile,$errline)
{
if(error_reporting()!=0)
throw new TPhpErrorException($errno,$errstr,$errfile,$errline);
}
public static function exceptionHandler($exception)
{
if(self::$_application!==null && ($errorHandler=self::$_application->getErrorHandler())!==null)
{
$errorHandler->handleError(null,$exception);
}
else
{
echo $exception;
}
exit(1);
}
public static function setApplication($application)
{
if(self::$_application!==null)
throw new TInvalidOperationException('prado_application_singleton_required');
self::$_application=$application;
}
public static function getApplication()
{
return self::$_application;
}
public static function getFrameworkPath()
{
return PRADO_DIR;
}
public static function serialize($data)
{
$arr[0]=$data;
return serialize($arr);
}
public static function unserialize($str)
{
$arr=unserialize($str);
return isset($arr[0])?$arr[0]:null;
}
public static function createComponent($type)
{
self::using($type);
if(($pos=strrpos($type,'.'))!==false)
$type=substr($type,$pos+1);
if(($n=func_num_args())>1)
{
$args=func_get_args();
$s='$args[1]';
for($i=2;$i<$n;++$i)
$s.=",\$args[$i]";
eval("\$component=new $type($s);");
return $component;
}
else
return new $type;
}
public static function using($namespace)
{
if(isset(self::$_usings[$namespace]) || class_exists($namespace,false))
return;
if(($pos=strrpos($namespace,'.'))===false) {
include_once($namespace.self::CLASS_FILE_EXT);
if(!class_exists($namespace,false))
throw new TInvalidOperationException('prado_component_unknown',$namespace);
}
else if(($path=self::getPathOfNamespace($namespace,self::CLASS_FILE_EXT))!==null)
{
$className=substr($namespace,$pos+1);
if($className==='*') {
if(is_dir($path))
{
self::$_usings[$namespace]=$path;
set_include_path(get_include_path().PATH_SEPARATOR.$path);
}
else
throw new TInvalidDataValueException('prado_using_invalid',$namespace);
}
else {
if(is_file($path))
{
self::$_usings[$namespace]=$path;
if(!class_exists($className,false))
include_once($path);
}
else
throw new TInvalidDataValueException('prado_using_invalid',$namespace);
}
}
else
throw new TInvalidDataValueException('prado_using_invalid',$namespace);
}
public static function getPathOfNamespace($namespace,$ext='')
{
if(isset(self::$_usings[$namespace]))
return self::$_usings[$namespace];
else if(isset(self::$_aliases[$namespace]))
return self::$_aliases[$namespace];
else
{
$segs=explode('.',$namespace);
$alias=array_shift($segs);
if(($file=array_pop($segs))!==null && ($root=self::getPathOfAlias($alias))!==null)
return rtrim($root.'/'.implode('/',$segs),'/').(($file==='*')?'':'/'.$file.$ext);
else
return null;
}
}
public static function getPathOfAlias($alias)
{
return isset(self::$_aliases[$alias])?self::$_aliases[$alias]:null;
}
public static function setPathOfAlias($alias,$path)
{
if(isset(self::$_aliases[$alias]))
throw new TInvalidOperationException('prado_alias_redefined',$alias);
else if(($rp=realpath($path))!==false && is_dir($rp))
{
if(strpos($alias,'.')===false)
self::$_aliases[$alias]=$rp;
else
throw new TInvalidDataValueException('prado_aliasname_invalid',$alias);
}
else
throw new TInvalidDataValueException('prado_alias_invalid',$alias,$path);
}
public static function fatalError($msg)
{
echo '
Fatal Error
';
echo ''.$msg.'
';
if(!function_exists('debug_backtrace'))
return;
echo 'Debug Backtrace
';
echo '';
$index=-1;
foreach(debug_backtrace() as $t)
{
$index++;
if($index==0) continue;
echo '#'.$index.' ';
if(isset($t['file']))
echo basename($t['file']) . ':' . $t['line'];
else
echo '';
echo ' -- ';
if(isset($t['class']))
echo $t['class'] . $t['type'];
echo $t['function'];
if(isset($t['args']) && sizeof($t['args']) > 0)
echo '(...)';
else
echo '()';
echo "\n";
}
echo '
';
exit(1);
}
public static function getUserLanguages()
{
static $languages=null;
if($languages===null)
{
$languages=array();
foreach(explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']) as $language)
{
$array=split(';q=',trim($language));
$languages[trim($array[0])]=isset($array[1])?(float)$array[1]:1.0;
}
arsort($languages);
$languages=array_keys($languages);
if(empty($languages))
$languages[0]='en';
}
return $languages;
}
public static function getPreferredLanguage()
{
static $language=null;
if($language===null)
{
$langs=Prado::getUserLanguages();
$lang=explode('-',$langs[0]);
if(empty($lang[0]) || !ctype_alpha($lang[0]))
$language='en';
else
$language=$lang[0];
}
return $language;
}
public static function trace($msg,$category='Uncategorized')
{
if(self::$_application && self::$_application->getMode()==='Performance')
return;
if(!self::$_application || self::$_application->getMode()==='Debug')
{
$trace=debug_backtrace();
if(isset($trace[0]['file']) && isset($trace[0]['line']))
$msg.=" (line {$trace[0]['line']}, {$trace[0]['file']})";
$level=TLogger::DEBUG;
}
else
$level=TLogger::INFO;
self::log($msg,$level,$category);
}
public static function log($msg,$level=TLogger::INFO,$category='Uncategorized')
{
if(self::$_logger===null)
self::$_logger=new TLogger;
self::$_logger->log($msg,$level,$category);
}
public static function getLogger()
{
if(self::$_logger===null)
self::$_logger=new TLogger;
return self::$_logger;
}
}
class TTextWriter extends TComponent implements ITextWriter
{
private $_str='';
public function flush()
{
$str=$this->_str;
$this->_str='';
return $str;
}
public function write($str)
{
$this->_str.=$str;
}
public function writeLine($str='')
{
$this->write($str."\n");
}
}
class TDate extends TComponent
{
}
?>_basePath=realpath($basePath))===false || !is_dir($this->_basePath))
throw new TConfigurationException('application_basepath_invalid',$basePath);
$configFile=$this->_basePath.'/'.self::CONFIG_FILE;
$this->_configFile=is_file($configFile) ? $configFile : null;
$this->_runtimePath=$this->_basePath.'/'.self::RUNTIME_PATH;
if(!is_dir($this->_runtimePath) || !is_writable($this->_runtimePath))
throw new TConfigurationException('application_runtimepath_invalid',$this->_runtimePath);
$this->_cacheFile=$cacheConfig ? $this->_runtimePath.'/'.self::CONFIGCACHE_FILE : null;
$this->_uniqueID=md5($this->_basePath);
}
public function run()
{
try
{
$this->initApplication();
$n=count(self::$_steps);
$this->_step=0;
$this->_requestCompleted=false;
while($this->_step<$n)
{
if($this->_mode===self::STATE_OFF)
throw new THttpException(503,'application_service_unavailable');
$method='on'.self::$_steps[$this->_step];
$this->$method($this);
if($this->_requestCompleted && $this->_step<$n-1)
$this->_step=$n-1;
else
$this->_step++;
}
}
catch(Exception $e)
{
$this->onError($e);
}
}
public function completeRequest()
{
$this->_requestCompleted=true;
}
public function getGlobalState($key,$defaultValue=null)
{
return isset($this->_globals[$key])?$this->_globals[$key]:$defaultValue;
}
public function setGlobalState($key,$value,$defaultValue=null)
{
$this->_stateChanged=true;
if($value===$defaultValue)
unset($this->_globals[$key]);
else
$this->_globals[$key]=$value;
}
public function clearGlobalState($key)
{
$this->_stateChanged=true;
unset($this->_globals[$key]);
}
protected function loadGlobals()
{
$this->_globals=$this->getApplicationStatePersister()->load();
}
protected function saveGlobals()
{
if(!$this->_stateChanged)
return;
$this->getApplicationStatePersister()->save($this->_globals);
}
public function getID()
{
return $this->_id;
}
public function setID($value)
{
$this->_id=$value;
}
public function getUniqueID()
{
return $this->_uniqueID;
}
public function getMode()
{
return $this->_mode;
}
public function setMode($value)
{
$this->_mode=TPropertyValue::ensureEnum($value,array(self::STATE_OFF,self::STATE_DEBUG,self::STATE_NORMAL,self::STATE_PERFORMANCE));
}
public function getBasePath()
{
return $this->_basePath;
}
public function getConfigurationFile()
{
return $this->_configFile;
}
public function getRuntimePath()
{
return $this->_runtimePath;
}
public function getService()
{
return $this->_service;
}
public function setModule($id,IModule $module)
{
if(isset($this->_modules[$id]))
throw new TConfigurationException('application_moduleid_duplicated',$id);
else
$this->_modules[$id]=$module;
}
public function getModule($id)
{
return isset($this->_modules[$id])?$this->_modules[$id]:null;
}
public function getModules()
{
return $this->_modules;
}
public function getParameters()
{
return $this->_parameters;
}
public function getPageService()
{
if(!$this->_pageService)
{
$this->_pageService=new TPageService;
$this->_pageService->init(null);
}
return $this->_pageService;
}
public function setPageService(TPageService $service)
{
$this->_pageService=$service;
}
public function getRequest()
{
if(!$this->_request)
{
$this->_request=new THttpRequest;
$this->_request->init(null);
}
return $this->_request;
}
public function setRequest(THttpRequest $request)
{
$this->_request=$request;
}
public function getResponse()
{
if(!$this->_response)
{
$this->_response=new THttpResponse;
$this->_response->init(null);
}
return $this->_response;
}
public function setResponse(THttpResponse $response)
{
$this->_response=$response;
}
public function getSession()
{
if(!$this->_session)
{
$this->_session=new THttpSession;
$this->_session->init(null);
}
return $this->_session;
}
public function setSession(THttpSession $session)
{
$this->_session=$session;
}
public function getErrorHandler()
{
if(!$this->_errorHandler)
{
$this->_errorHandler=new TErrorHandler;
$this->_errorHandler->init(null);
}
return $this->_errorHandler;
}
public function setErrorHandler(TErrorHandler $handler)
{
$this->_errorHandler=$handler;
}
public function getApplicationStatePersister()
{
if(!$this->_statePersister)
{
$this->_statePersister=new TApplicationStatePersister;
$this->_statePersister->init(null);
}
return $this->_statePersister;
}
public function setApplicationStatePersister(IStatePersister $persister)
{
$this->_statePersister=$persister;
}
public function getCache()
{
return $this->_cache;
}
public function setCache(ICache $cache)
{
$this->_cache=$cache;
}
public function getUser()
{
return $this->_user;
}
public function setUser(IUser $user)
{
$this->_user=$user;
}
public function getGlobalization()
{
return $this->_globalization;
}
public function setGlobalization(TGlobalization $handler)
{
$this->_globalization = $handler;
}
public function getAuthorizationRules()
{
if($this->_authRules===null)
$this->_authRules=new TAuthorizationRuleCollection;
return $this->_authRules;
}
protected function initApplication()
{
Prado::setPathOfAlias('Application',$this->_basePath);
if($this->_configFile===null)
{
$this->getRequest()->setAvailableServices(array(self::PAGE_SERVICE_ID));
$this->_service=$this->getPageService();
return;
}
if($this->_cacheFile===null || @filemtime($this->_cacheFile)_configFile))
{
$config=new TApplicationConfiguration;
$config->loadFromFile($this->_configFile);
if($this->_cacheFile!==null)
{
if(($fp=fopen($this->_cacheFile,'wb'))!==false)
{
fputs($fp,Prado::serialize($config));
fclose($fp);
}
else
syslog(LOG_WARNING, 'Prado application config cache file "'.$this->_cacheFile.'" cannot be created.');
}
}
else
{
$config=Prado::unserialize(file_get_contents($this->_cacheFile));
}
foreach($config->getAliases() as $alias=>$path)
Prado::setPathOfAlias($alias,$path);
foreach($config->getUsings() as $using)
Prado::using($using);
foreach($config->getProperties() as $name=>$value)
$this->setSubProperty($name,$value);
$this->_parameters=new TMap;
foreach($config->getParameters() as $id=>$parameter)
{
if(is_string($parameter))
$this->_parameters->add($id,$parameter);
else
{
$component=Prado::createComponent($parameter[0]);
foreach($parameter[1] as $name=>$value)
$component->setSubProperty($name,$value);
$this->_parameters->add($id,$component);
}
}
$this->_modules=array();
foreach($config->getModules() as $id=>$moduleConfig)
{
$module=Prado::createComponent($moduleConfig[0]);
$this->setModule($id,$module);
foreach($moduleConfig[1] as $name=>$value)
$module->setSubProperty($name,$value);
$module->init($moduleConfig[2]);
}
$services=$config->getServices();
$serviceIDs=array_keys($services);
array_unshift($serviceIDs,self::PAGE_SERVICE_ID);
$request=$this->getRequest();
$request->setAvailableServices($serviceIDs);
if(($serviceID=$request->getServiceID())===null)
$serviceID=self::PAGE_SERVICE_ID;
if(isset($services[$serviceID]))
{
$serviceConfig=$services[$serviceID];
$service=Prado::createComponent($serviceConfig[0]);
if(!($service instanceof IService))
throw new THttpException(500,'application_service_unknown',$serviceID);
$this->_service=$service;
foreach($serviceConfig[1] as $name=>$value)
$service->setSubProperty($name,$value);
$service->init($serviceConfig[2]);
}
else
$this->_service=$this->getPageService();
}
public function onError($param)
{
if($this->hasEventHandler('OnError'))
$this->raiseEvent('OnError',$this,$param);
else
$this->getErrorHandler()->handleError($this,$param);
}
public function onBeginRequest($param)
{
$this->raiseEvent('OnBeginRequest',$this,$param);
}
public function onAuthentication($param)
{
$this->raiseEvent('OnAuthentication',$this,$param);
}
public function onPostAuthentication($param)
{
$this->raiseEvent('OnPostAuthentication',$this,$param);
}
public function onAuthorization($param)
{
$this->raiseEvent('OnAuthorization',$this,$param);
}
public function onPostAuthorization($param)
{
$this->raiseEvent('OnPostAuthorization',$this,$param);
}
public function onLoadState($param)
{
$this->loadGlobals();
$this->raiseEvent('OnLoadState',$this,$param);
}
public function onPostLoadState($param)
{
$this->raiseEvent('OnPostLoadState',$this,$param);
}
public function onPreRunService($param)
{
$this->raiseEvent('OnPreRunService',$this,$param);
}
public function onRunService($param)
{
$this->raiseEvent('OnRunService',$this,$param);
if($this->_service)
$this->_service->run();
}
public function onPostRunService($param)
{
$this->raiseEvent('OnPostRunService',$this,$param);
}
public function onSaveState($param)
{
$this->raiseEvent('OnSaveState',$this,$param);
$this->saveGlobals();
}
public function onPostSaveState($param)
{
$this->raiseEvent('OnPostSaveState',$this,$param);
}
public function onEndRequest($param)
{
$this->raiseEvent('OnEndRequest',$this,$param);
}
}
class TApplicationConfiguration extends TComponent
{
private $_properties=array();
private $_usings=array();
private $_aliases=array();
private $_modules=array();
private $_services=array();
private $_parameters=array();
public function loadFromFile($fname)
{
$configPath=dirname($fname);
$dom=new TXmlDocument;
$dom->loadFromFile($fname);
foreach($dom->getAttributes() as $name=>$value)
$this->_properties[$name]=$value;
if(($pathsNode=$dom->getElementByTagName('paths'))!==null)
{
foreach($pathsNode->getElementsByTagName('alias') as $aliasNode)
{
if(($id=$aliasNode->getAttribute('id'))!==null && ($path=$aliasNode->getAttribute('path'))!==null)
{
$path=str_replace('\\','/',$path);
if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) $p=realpath($path);
else
$p=realpath($configPath.'/'.$path);
if($p===false || !is_dir($p))
throw new TConfigurationException('appconfig_aliaspath_invalid',$id,$path);
if(isset($this->_aliases[$id]))
throw new TConfigurationException('appconfig_alias_redefined',$id);
$this->_aliases[$id]=$p;
}
else
throw new TConfigurationException('appconfig_alias_invalid');
}
foreach($pathsNode->getElementsByTagName('using') as $usingNode)
{
if(($namespace=$usingNode->getAttribute('namespace'))!==null)
$this->_usings[]=$namespace;
else
throw new TConfigurationException('appconfig_using_invalid');
}
}
if(($modulesNode=$dom->getElementByTagName('modules'))!==null)
{
foreach($modulesNode->getElementsByTagName('module') as $node)
{
$properties=$node->getAttributes();
if(($id=$properties->itemAt('id'))===null)
throw new TConfigurationException('appconfig_moduleid_required');
if(($type=$properties->remove('class'))===null && isset($this->_modules[$id]) && $this->_modules[$id][2]===null)
$type=$this->_modules[$id][0];
if($type===null)
throw new TConfigurationException('appconfig_moduletype_required',$id);
$node->setParent(null);
$this->_modules[$id]=array($type,$properties->toArray(),$node);
}
}
if(($servicesNode=$dom->getElementByTagName('services'))!==null)
{
foreach($servicesNode->getElementsByTagName('service') as $node)
{
$properties=$node->getAttributes();
if(($id=$properties->itemAt('id'))===null)
throw new TConfigurationException('appconfig_serviceid_required');
if(($type=$properties->remove('class'))===null && isset($this->_services[$id]) && $this->_services[$id][2]===null)
$type=$this->_services[$id][0];
if($type===null)
throw new TConfigurationException('appconfig_servicetype_required',$id);
$node->setParent(null);
$this->_services[$id]=array($type,$properties->toArray(),$node);
}
}
if(($parametersNode=$dom->getElementByTagName('parameters'))!==null)
{
foreach($parametersNode->getElementsByTagName('parameter') as $node)
{
$properties=$node->getAttributes();
if(($id=$properties->remove('id'))===null)
throw new TConfigurationException('appconfig_parameterid_required');
if(($type=$properties->remove('class'))===null)
$this->_parameters[$id]=$node->getValue();
else
$this->_parameters[$id]=array($type,$properties->toArray());
}
}
}
public function getProperties()
{
return $this->_properties;
}
public function getAliases()
{
return $this->_aliases;
}
public function getUsings()
{
return $this->_usings;
}
public function getModules()
{
return $this->_modules;
}
public function getServices()
{
return $this->_services;
}
public function getParameters()
{
return $this->_parameters;
}
}
class TApplicationStatePersister extends TModule implements IStatePersister
{
const CACHE_NAME='prado:appstate';
public function init($config)
{
$this->getApplication()->setApplicationStatePersister($this);
}
protected function getStateFilePath()
{
return $this->getApplication()->getRuntimePath().'/global.cache';
}
public function load()
{
if(($cache=$this->getApplication()->getCache())!==null && ($value=$cache->get(self::CACHE_NAME))!==false)
return unserialize($value);
else
{
if(($content=@file_get_contents($this->getStateFilePath()))!==false)
return unserialize($content);
else
return null;
}
}
public function save($state)
{
$content=serialize($state);
$saveFile=true;
if(($cache=$this->getApplication()->getCache())!==null)
{
if($cache->get(self::CACHE_NAME)===$content)
$saveFile=false;
else
$cache->set(self::CACHE_NAME,$content);
}
if($saveFile)
{
$fileName=$this->getStateFilePath();
if(version_compare(phpversion(),'5.1.0','>='))
file_put_contents($fileName,$content,LOCK_EX);
else
file_put_contents($fileName,$content);
}
}
}
?>getApplication()->setErrorHandler($this);
}
public function getErrorTemplatePath()
{
return $this->_templatePath;
}
public function setErrorTemplatePath($value)
{
if(($templatePath=Prado::getPathOfNamespace($this->_templatePath))!==null && is_dir($templatePath))
$this->_templatePath=$templatePath;
else
throw new TConfigurationException('errorhandler_errortemplatepath_invalid',$value);
}
public function handleError($sender,$param)
{
static $handling=false;
restore_error_handler();
restore_exception_handler();
if($handling)
$this->handleRecursiveError($param);
else
{
$handling=true;
if(($response=$this->getResponse())!==null)
$response->clear();
if(!headers_sent())
header('Content-Type: text/html; charset=UTF-8');
if($param instanceof THttpException)
$this->handleExternalError($param->getStatusCode(),$param);
else if($this->getApplication()->getMode()===TApplication::STATE_DEBUG)
$this->displayException($param);
else
$this->handleExternalError(500,$param);
}
exit(1);
}
protected function handleExternalError($statusCode,$exception)
{
if(!($exception instanceof THttpException))
error_log($exception->__toString());
if($this->_templatePath===null)
$this->_templatePath=Prado::getFrameworkPath().'/Exceptions/templates';
$base=$this->_templatePath.'/'.self::ERROR_FILE_NAME;
$lang=Prado::getPreferredLanguage();
if(is_file("$base$statusCode-$lang.html"))
$errorFile="$base$statusCode-$lang.html";
else if(is_file("$base$statusCode.html"))
$errorFile="$base$statusCode.html";
else if(is_file("$base-$lang.html"))
$errorFile="$base-$lang.html";
else
$errorFile="$base.html";
if(($content=@file_get_contents($errorFile))===false)
die("Unable to open error template file '$errorFile'.");
$serverAdmin=isset($_SERVER['SERVER_ADMIN'])?$_SERVER['SERVER_ADMIN']:'';
$tokens=array(
'%%StatusCode%%' => "$statusCode",
'%%ErrorMessage%%' => htmlspecialchars($exception->getMessage()),
'%%ServerAdmin%%' => $serverAdmin,
'%%Version%%' => $_SERVER['SERVER_SOFTWARE'].' PRADO/'.Prado::getVersion(),
'%%Time%%' => @strftime('%Y-%m-%d %H:%M',time())
);
echo strtr($content,$tokens);
}
protected function handleRecursiveError($exception)
{
if($this->getApplication()->getMode()===TApplication::STATE_DEBUG)
{
echo "Recursive Error\n";
echo "Recursive Error
\n";
echo "".$exception->__toString()."
\n";
echo "";
}
else
{
error_log("Error happened while processing an existing error:\n".$param->__toString());
header('HTTP/1.0 500 Internal Error');
}
}
protected function displayException($exception)
{
$lines=file($exception->getFile());
$errorLine=$exception->getLine();
$beginLine=$errorLine-self::SOURCE_LINES>=0?$errorLine-self::SOURCE_LINES:0;
$endLine=$errorLine+self::SOURCE_LINES<=count($lines)?$errorLine+self::SOURCE_LINES:count($lines);
$source='';
for($i=$beginLine-1;$i<$endLine;++$i)
{
if($i===$errorLine-1)
{
$line=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",' ',$lines[$i])));
$source.="".$line."
";
}
else
$source.=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",' ',$lines[$i])));
}
$tokens=array(
'%%ErrorType%%' => get_class($exception),
'%%ErrorMessage%%' => htmlspecialchars($exception->getMessage()),
'%%SourceFile%%' => htmlspecialchars($exception->getFile()).' ('.$exception->getLine().')',
'%%SourceCode%%' => $source,
'%%StackTrace%%' => htmlspecialchars($exception->getTraceAsString()),
'%%Version%%' => $_SERVER['SERVER_SOFTWARE'].' PRADO/'.Prado::getVersion(),
'%%Time%%' => @strftime('%Y-%m-%d %H:%M',time())
);
$lang=Prado::getPreferredLanguage();
$exceptionFile=Prado::getFrameworkPath().'/Exceptions/templates/'.self::EXCEPTION_FILE_NAME.'-'.$lang.'.html';
if(!is_file($exceptionFile))
$exceptionFile=Prado::getFrameworkPath().'/Exceptions/templates/'.self::EXCEPTION_FILE_NAME.'.html';
if(($content=@file_get_contents($exceptionFile))===false)
die("Unable to open exception template file '$exceptionFile'.");
echo strtr($content,$tokens);
}
}
?>_requestUri=$_SERVER['REQUEST_URI'];
else $this->_requestUri=$_SERVER['SCRIPT_NAME'].(empty($_SERVER['QUERY_STRING'])?'':'?'.$_SERVER['QUERY_STRING']);
if(isset($_SERVER['PATH_INFO']))
$this->_pathInfo=$_SERVER['PATH_INFO'];
else if(strpos($_SERVER['PHP_SELF'],$_SERVER['SCRIPT_NAME'])===0)
$this->_pathInfo=substr($_SERVER['PHP_SELF'],strlen($_SERVER['SCRIPT_NAME']));
else
$this->_pathInfo='';
if(get_magic_quotes_gpc())
{
if(isset($_GET))
$_GET=$this->stripSlashes($_GET);
if(isset($_POST))
$_POST=$this->stripSlashes($_POST);
if(isset($_REQUEST))
$_REQUEST=$this->stripSlashes($_REQUEST);
if(isset($_COOKIE))
$_COOKIE=$this->stripSlashes($_COOKIE);
}
$this->_items=new TMap(array_merge($_POST,$_GET));
$this->_initialized=true;
$this->getApplication()->setRequest($this);
}
public function stripSlashes(&$data)
{
return is_array($data)?array_map(array($this,'stripSlashes'),$data):stripslashes($data);
}
public function getUrl()
{
if($this->_url===null)
{
$secure=$this->getIsSecureConnection();
$url=$secure?'https://':'http://';
if(empty($_SERVER['HTTP_HOST']))
{
$url.=$_SERVER['SERVER_NAME'];
$port=$_SERVER['SERVER_PORT'];
if(($port!=80 && !$secure) || ($port!=443 && $secure))
$url.=':'.$port;
}
else
$url.=$_SERVER['HTTP_HOST'];
$url.=$this->getRequestUri();
$this->_url=new TUri($url);
}
return $this->_url;
}
public function getRequestType()
{
return $_SERVER['REQUEST_METHOD'];
}
public function getIsSecureConnection()
{
return !empty($_SERVER['HTTPS']);
}
public function getPathInfo()
{
return $this->_pathInfo;
}
public function getQueryString()
{
return isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:'';
}
public function getRequestUri()
{
return $this->_requestUri;
}
public function getApplicationPath()
{
return $_SERVER['SCRIPT_NAME'];
}
public function getPhysicalApplicationPath()
{
return realpath($_SERVER['SCRIPT_FILENAME']);
}
public function getServerName()
{
return $_SERVER['SERVER_NAME'];
}
public function getServerPort()
{
return $_SERVER['SERVER_PORT'];
}
public function getUrlReferrer()
{
return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null;
}
public function getBrowser()
{
return get_browser();
}
public function getUserAgent()
{
return $_SERVER['HTTP_USER_AGENT'];
}
public function getUserHostAddress()
{
return $_SERVER['REMOTE_ADDR'];
}
public function getUserHost()
{
return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null;
}
public function getAcceptTypes()
{
return $_SERVER['HTTP_ACCEPT'];
}
public function getUserLanguages()
{
return Prado::getUserLanguages();
}
public function getItems()
{
return $this->_items;
}
public function getParameters()
{
return $this->_items;
}
public function getCookies()
{
if($this->_cookies===null)
{
$this->_cookies=new THttpCookieCollection;
foreach($_COOKIE as $key=>$value)
$this->_cookies->add(new THttpCookie($key,$value));
}
return $this->_cookies;
}
public function getUploadedFiles()
{
return $_FILES;
}
public function getServerVariables()
{
return $_SERVER;
}
public function getEnvironmentVariables()
{
return $_ENV;
}
public function constructUrl($serviceID,$serviceParam,$getItems=null,$encodeAmpersand=false)
{
$url=$this->getApplicationPath();
$url.='?'.$serviceID.'=';
if(!empty($serviceParam))
$url.=$serviceParam;
$amp=$encodeAmpersand?'&':'&';
if(is_array($getItems) || $getItems instanceof Traversable)
{
foreach($getItems as $name=>$value)
$url.=$amp.urlencode($name).'='.urlencode($value);
}
if(defined('SID') && SID != '')
$url.=$amp.SID;
return $url;
}
protected function resolveRequest()
{
$this->_requestResolved=true;
foreach($this->_services as $id)
{
if(isset($_GET[$id]))
{
$this->setServiceID($id);
$this->setServiceParameter($_GET[$id]);
break;
}
}
}
public function getAvailableServices()
{
return $this->_services;
}
public function setAvailableServices($services)
{
$this->_services=$services;
}
public function getServiceID()
{
if(!$this->_requestResolved)
$this->resolveRequest();
return $this->_serviceID;
}
protected function setServiceID($value)
{
$this->_serviceID=$value;
}
public function getServiceParameter()
{
if(!$this->_requestResolved)
$this->resolveRequest();
return $this->_serviceParam;
}
protected function setServiceParameter($value)
{
$this->_serviceParam=$value;
}
}
class THttpCookieCollection extends TList
{
private $_o;
public function __construct($owner=null)
{
parent::__construct();
$this->_o=$owner;
}
protected function addedItem($item)
{
if($this->_o instanceof THttpResponse)
$this->_o->addCookie($item);
}
protected function removedItem($item)
{
if($this->_o instanceof THttpResponse)
$this->_o->removeCookie($item);
}
protected function canAddItem($item)
{
return ($item instanceof THttpCookie);
}
}
class THttpCookie extends TComponent
{
private $_domain='';
private $_name;
private $_value=0;
private $_expire=0;
private $_path='/';
private $_secure=false;
public function __construct($name,$value)
{
parent::__construct();
$this->_name=$name;
$this->_value=$value;
}
public function getDomain()
{
return $this->_domain;
}
public function setDomain($value)
{
$this->_domain=$value;
}
public function getExpire()
{
return $this->_expire;
}
public function setExpire($value)
{
$this->_expire=TPropertyValue::ensureInteger($value);
}
public function getName()
{
return $this->_name;
}
public function setName($value)
{
$this->_name=$value;
}
public function getValue()
{
return $this->_value;
}
public function setValue($value)
{
$this->_value=$value;
}
public function getPath()
{
return $this->_path;
}
public function setPath($value)
{
$this->_path=$value;
}
public function getSecure()
{
return $this->_secure;
}
public function setSecure($value)
{
$this->_secure=TPropertyValue::ensureBoolean($value);
}
}
class TUri extends TComponent
{
private static $_defaultPort=array(
'ftp'=>21,
'gopher'=>70,
'http'=>80,
'https'=>443,
'news'=>119,
'nntp'=>119,
'wais'=>210,
'telnet'=>23
);
private $_scheme;
private $_host;
private $_port;
private $_user;
private $_pass;
private $_path;
private $_query;
private $_fragment;
private $_uri;
public function __construct($uri)
{
parent::__construct();
if(($ret=@parse_url($uri))!==false)
{
$this->_scheme=$ret['scheme'];
$this->_host=$ret['host'];
$this->_port=$ret['port'];
$this->_user=$ret['user'];
$this->_pass=$ret['pass'];
$this->_path=$ret['path'];
$this->_query=$ret['query'];
$this->_fragment=$ret['fragment'];
$this->_uri=$uri;
}
else
{
throw new TInvalidDataValueException('uri_format_invalid',$uri);
}
}
public function getUri()
{
return $this->_uri;
}
public function getScheme()
{
return $this->_scheme;
}
public function getHost()
{
return $this->_host;
}
public function getPort()
{
return $this->_port;
}
public function getUser()
{
return $this->_user;
}
public function getPassword()
{
return $this->_pass;
}
public function getPath()
{
return $this->_path;
}
public function getQuery()
{
return $this->_query;
}
public function getFragment()
{
return $this->_fragment;
}
}
?>_bufferOutput)
@ob_end_flush();
parent::__destruct();
}
public function init($config)
{
if($this->_bufferOutput)
ob_start();
$this->_initialized=true;
$this->getApplication()->setResponse($this);
}
public function getCacheExpire()
{
return session_cache_expire();
}
public function setCacheExpire($value)
{
session_cache_expire(TPropertyValue::ensureInteger($value));
}
public function getCacheControl()
{
return session_cache_limiter();
}
public function setCacheControl($value)
{
session_cache_limiter(TPropertyValue::ensureEnum($value,array('none','nocache','private','private_no_expire','public')));
}
public function setContentType($type)
{
$this->_contentType = $type;
}
public function getContentType()
{
return $this->_contentType;
}
public function getCharset()
{
return $this->_charset;
}
public function setCharset($charset)
{
$this->_charset = $charset;
}
public function getBufferOutput()
{
return $this->_bufferOutput;
}
public function setBufferOutput($value)
{
if($this->_initialized)
throw new TInvalidOperationException('httpresponse_bufferoutput_unchangeable');
else
$this->_bufferOutput=TPropertyValue::ensureBoolean($value);
}
public function getStatusCode()
{
return $this->_status;
}
public function setStatusCode($status)
{
$this->_status=TPropertyValue::ensureInteger($status);
}
public function getCookies()
{
if($this->_cookies===null)
$this->_cookies=new THttpCookieCollection($this);
return $this->_cookies;
}
public function write($str)
{
echo $str;
}
public function writeFile($fileName)
{
static $defaultMimeTypes=array(
'css'=>'text/css',
'gif'=>'image/gif',
'jpg'=>'image/jpeg',
'jpeg'=>'image/jpeg',
'htm'=>'text/html',
'html'=>'text/html',
'js'=>'javascript/js'
);
if(!is_file($fileName))
throw new TInvalidDataValueException('httpresponse_file_inexistent',$fileName);
header('Pragma: public');
header('Expires: 0');
header('Cache-Component: must-revalidate, post-check=0, pre-check=0');
$mimeType='text/plain';
if(function_exists('mime_content_type'))
$mimeType=mime_content_type($fileName);
else
{
$ext=array_pop(explode('.',$fileName));
if(isset($defaultMimeTypes[$ext]))
$mimeType=$defaultMimeTypes[$ext];
}
$fn=basename($fileName);
header("Content-type: $mimeType");
header('Content-Length: '.filesize($fileName));
header("Content-Disposition: attachment; filename=\"$fn\"");
header('Content-Transfer-Encoding: binary');
readfile($fileName);
}
public function redirect($url)
{
header('Location:'.$url);
exit();
}
public function flush()
{
$header = $this->getContentTypeHeader();
$this->appendHeader($header);
if($this->_bufferOutput)
ob_flush();
}
protected function getContentTypeHeader()
{
$app = $this->getApplication()->getGlobalization();
$charset = $this->getCharset();
if(empty($charset))
$charset = !is_null($app) ? $app->getCharset() : 'UTF-8';
$type = $this->getContentType();
return "Content-Type: $type; charset=$charset";
}
public function clear()
{
if($this->_bufferOutput)
ob_clean();
}
public function appendHeader($value)
{
header($value);
}
public function sendContentTypeHeader($type=null)
{
}
public function appendLog($message,$messageType=0,$destination='',$extraHeaders='')
{
error_log($message,$messageType,$destination,$extraHeaders);
}
public function addCookie($cookie)
{
setcookie($cookie->getName(),$cookie->getValue(),$cookie->getExpire(),$cookie->getPath(),$cookie->getDomain(),$cookie->getSecure());
}
public function removeCookie($cookie)
{
setcookie($cookie->getName(),null,0,$cookie->getPath(),$cookie->getDomain(),$cookie->getSecure());
}
public function getHtmlWriterType()
{
return $this->_htmlWriterType;
}
public function setHtmlWriterType($value)
{
$this->_htmlWriterType=$value;
}
public function createHtmlWriter($type=null)
{
if($type===null)
$type=$this->_htmlWriterType;
return Prado::createComponent($type,$this);
}
}
?>_autoStart)
session_start();
$this->_initialized=true;
$this->getApplication()->setSession($this);
}
public function open()
{
if(!$this->_started)
{
if($this->_cookie!==null)
session_set_cookie_params($this->_cookie->getExpire(),$this->_cookie->getPath(),$this->_cookie->getDomain(),$this->_cookie->getSecure());
session_start();
$this->_started=true;
}
}
public function close()
{
if($this->_started)
{
session_write_close();
$this->_started=false;
}
}
public function destroy()
{
if($this->_started)
{
session_destroy();
$this->_started=false;
}
}
public function getItems()
{
if($this->_items===null)
$this->_items=new THttpSessionCollection($_SESSION);
return $this->_items;
}
public function getIsStarted()
{
return $this->_started;
}
public function getSessionID()
{
return session_id();
}
public function setSessionID($value)
{
if($this->_started)
throw new TInvalidOperationException('httpsession_sessionid_unchangeable');
else
session_id($value);
}
public function getSessionName()
{
return session_name();
}
public function setSessionName($value)
{
if($this->_started)
throw new TInvalidOperationException('httpsession_sessionname_unchangeable');
else if(ctype_alnum($value))
session_name($value);
else
throw new TInvalidDataValueException('httpsession_sessionname_invalid',$name);
}
public function getSavePath()
{
return session_save_path();
}
public function setSavePath($value)
{
if($this->_started)
throw new TInvalidOperationException('httpsession_savepath_unchangeable');
else if(is_dir($value))
session_save_path($value);
else
throw new TInvalidDataValueException('httpsession_savepath_invalid',$value);
}
public function getStorage()
{
switch(session_module_name())
{
case 'files': return 'File';
case 'mm': return 'SharedMemory';
case 'user': return 'Custom';
default: return 'Unknown';
}
}
public function setStorage($value)
{
if($this->_started)
throw new TInvalidOperationException('httpsession_storage_unchangeable');
else
{
$value=TPropertyValue::ensureEnum($value,array('File','SharedMemory','Custom'));
if($value==='Custom')
session_set_save_handler(array($this,'_open'),array($this,'_close'),array($this,'_read'),array($this,'_write'),array($this,'_destroy'),array($this,'_gc'));
switch($value)
{
case 'Custom':
session_module_name('user');
break;
case 'SharedMemory':
session_module_name('mm');
break;
default:
session_module_name('files');
break;
}
}
}
public function getCookie()
{
if($this->_cookie===null)
$this->_cookie=new THttpCookie($this->getSessionName(),$this->getSessionID());
return $this->_cookie;
}
public function getCookieMode()
{
if(ini_get('session.use_cookies')==='0')
return 'None';
else if(ini_get('session.use_only_cookies')==='0')
return 'Allow';
else
return 'Only';
}
public function setCookieMode($value)
{
if($this->_started)
throw new TInvalidOperationException('httpsession_cookiemode_unchangeable');
else
{
$value=TPropertyValue::ensureEnum($value,array('None','Allow','Only'));
if($value==='None')
ini_set('session.use_cookies','0');
else if($value==='Allow')
{
ini_set('session.use_cookies','1');
ini_set('session.use_only_cookies','0');
}
else
{
ini_set('session.use_cookies','1');
ini_set('session.use_only_cookies','1');
}
}
}
public function getAutoStart()
{
return $this->_autoStart;
}
public function setAutoStart($value)
{
if($this->_initialized)
throw new TInvalidOperationException('httpsession_autostart_unchangeable');
else
$this->_autoStart=TPropertyValue::ensureBoolean($value);
}
public function getGCProbability()
{
return TPropertyValue::ensureInteger(ini_get('session.gc_probability'));
}
public function setGCProbability($value)
{
if($this->_started)
throw new TInvalidOperationException('httpsession_gcprobability_unchangeable');
else
{
$value=TPropertyValue::ensureInteger($value);
if($value>=0 && $value<=100)
{
ini_set('session.gc_probability',$value);
ini_set('session.gc_divisor','100');
}
else
throw new TInvalidDataValueException('httpsession_gcprobability_invalid',$value);
}
}
public function getUseTransparentSessionID()
{
return ini_get('session.use_trans_sid')==='1';
}
public function setUseTransparentSessionID($value)
{
if($this->_started)
throw new TInvalidOperationException('httpsession_transid_unchangeable');
else
ini_set('session.use_only_cookies',TPropertyValue::ensureBoolean($value)?'1':'0');
}
public function getTimeout()
{
return TPropertyValue::ensureInteger(ini_get('session.gc_maxlifetime'));
}
public function setTimeout($value)
{
if($this->_started)
throw new TInvalidOperationException('httpsession_maxlifetime_unchangeable');
else
ini_set('session.gc_maxlifetime',$value);
}
public function _open($savePath,$sessionName)
{
return true;
}
public function _close()
{
return true;
}
public function _read($id)
{
return '';
}
public function _write($id,$data)
{
return true;
}
public function _destroy($id)
{
return true;
}
public function _gc($maxLifetime)
{
return true;
}
}
class THttpSessionCollection extends TMap
{
private $_initialized=false;
public function __construct($data=null)
{
parent::__construct($data);
$this->_initialized=true;
}
protected function addedItem($key,$value)
{
if($this->_initialized)
$_SESSION[$key]=$value;
}
protected function removedItem($key,$value)
{
unset($_SESSION[$key]);
}
}
?>_action=$action;
else
throw new TInvalidDataValueException('authorizationrule_action_invalid',$action);
$this->_users=array();
$this->_roles=array();
$this->_everyone=false;
$this->_guest=false;
foreach(explode(',',$users) as $user)
{
if(($user=trim(strtolower($user)))!=='')
{
if($user==='*')
$this->_everyone=true;
else if($user==='?')
$this->_guest=true;
else
$this->_users[]=$user;
}
}
foreach(explode(',',$roles) as $role)
{
if(($role=trim(strtolower($role)))!=='')
$this->_roles[]=$role;
}
$verb=trim(strtolower($verb));
if($verb==='' || $verb==='get' || $verb==='post')
$this->_verb=$verb;
else
throw new TInvalidDataValueException('authorizationrule_verb_invalid',$verb);
}
public function getAction()
{
return $this->_action;
}
public function getUsers()
{
return $this->_users;
}
public function getRoles()
{
return $this->_roles;
}
public function getVerb()
{
return $this->_verb;
}
public function getGuestApplied()
{
return $this->_guest;
}
public function getEveryoneApplied()
{
return $this->_everyone;
}
public function isUserAllowed(IUser $user,$verb)
{
$decision=($this->_action==='allow')?1:-1;
if($this->_verb==='' || strcasecmp($verb,$this->_verb)===0)
{
if($this->_everyone || ($this->_guest && $user->getIsGuest()))
return $decision;
if(in_array(strtolower($user->getName()),$this->_users))
return $decision;
foreach($this->_roles as $role)
if($user->isInRole($role))
return $decision;
}
return 0;
}
}
class TAuthorizationRuleCollection extends TList
{
public function isUserAllowed($user,$verb)
{
if($user instanceof IUser)
{
$verb=strtolower(trim($verb));
foreach($this as $rule)
{
if(($decision=$rule->isUserAllowed($user,$verb))!==0)
return ($decision>0);
}
return true;
}
else
return false;
}
protected function canAddItem($item)
{
return ($item instanceof TAuthorizationRule);
}
}
?>getApplication();
$application->setPageService($this);
if($this->_basePath===null)
{
$basePath=$application->getBasePath().'/'.self::DEFAULT_BASEPATH;
if(($this->_basePath=realpath($basePath))===false || !is_dir($this->_basePath))
throw new TConfigurationException('pageservice_basepath_invalid',$basePath);
}
$this->_pagePath=$application->getRequest()->getServiceParameter();
if(empty($this->_pagePath))
$this->_pagePath=$this->_defaultPage;
if(empty($this->_pagePath))
throw new THttpException(404,'pageservice_page_required');
if(($cache=$application->getCache())===null)
{
$pageConfig=new TPageConfiguration;
if($config!==null)
$pageConfig->loadXmlElement($config,$application->getBasePath(),null);
$pageConfig->loadConfigurationFiles($this->_pagePath,$this->_basePath);
}
else
{
$configCached=true;
$currentTimestamp=array();
$arr=$cache->get(self::CONFIG_CACHE_PREFIX.$this->_pagePath);
if(is_array($arr))
{
list($pageConfig,$timestamps)=$arr;
if($application->getMode()!==TApplication::STATE_PERFORMANCE)
{
foreach($timestamps as $fileName=>$timestamp)
{
if($fileName===0) {
$appConfigFile=$application->getConfigurationFile();
$currentTimestamp[0]=$appConfigFile===null?0:@filemtime($appConfigFile);
if($currentTimestamp[0]>$timestamp || ($timestamp>0 && !$currentTimestamp[0]))
$configCached=false;
}
else
{
$currentTimestamp[$fileName]=@filemtime($fileName);
if($currentTimestamp[$fileName]>$timestamp || ($timestamp>0 && !$currentTimestamp[$fileName]))
$configCached=false;
}
}
}
}
else
{
$configCached=false;
$paths=explode('.',$this->_pagePath);
array_pop($paths);
$configPath=$this->_basePath;
foreach($paths as $path)
{
$configFile=$configPath.'/'.self::CONFIG_FILE;
$currentTimestamp[$configFile]=@filemtime($configFile);
$configPath.='/'.$path;
}
$appConfigFile=$application->getConfigurationFile();
$currentTimestamp[0]=$appConfigFile===null?0:@filemtime($appConfigFile);
}
if(!$configCached)
{
$pageConfig=new TPageConfiguration;
if($config!==null)
$pageConfig->loadXmlElement($config,$application->getBasePath(),null);
$pageConfig->loadConfigurationFiles($this->_pagePath,$this->_basePath);
$cache->set(self::CONFIG_CACHE_PREFIX.$this->_pagePath,array($pageConfig,$currentTimestamp));
}
}
foreach($pageConfig->getAliases() as $alias=>$path)
Prado::setPathOfAlias($alias,$path);
foreach($pageConfig->getUsings() as $using)
Prado::using($using);
$this->_properties=$pageConfig->getProperties();
$parameters=$application->getParameters();
foreach($pageConfig->getParameters() as $id=>$parameter)
{
if(is_string($parameter))
$parameters->add($id,$parameter);
else
{
$component=Prado::createComponent($parameter[0]);
foreach($parameter[1] as $name=>$value)
$component->setSubProperty($name,$value);
$parameters->add($id,$component);
}
}
foreach($pageConfig->getModules() as $id=>$moduleConfig)
{
$module=Prado::createComponent($moduleConfig[0]);
$application->setModule($id,$module);
foreach($moduleConfig[1] as $name=>$value)
$module->setSubProperty($name,$value);
$module->init($moduleConfig[2]);
}
$application->getAuthorizationRules()->mergeWith($pageConfig->getRules());
$this->_initialized=true;
}
public function getID()
{
return $this->_id;
}
public function setID($value)
{
$this->_id=$value;
}
public function getTemplateManager()
{
if(!$this->_templateManager)
{
$this->_templateManager=new TTemplateManager;
$this->_templateManager->init(null);
}
return $this->_templateManager;
}
public function setTemplateManager(TTemplateManager $value)
{
$this->_templateManager=$value;
}
public function getAssetManager()
{
if(!$this->_assetManager)
{
$this->_assetManager=new TAssetManager;
$this->_assetManager->init(null);
}
return $this->_assetManager;
}
public function setAssetManager(TAssetManager $value)
{
$this->_assetManager=$value;
}
public function getThemeManager()
{
if(!$this->_themeManager)
{
$this->_themeManager=new TThemeManager;
$this->_themeManager->init(null);
}
return $this->_themeManager;
}
public function setThemeManager(TThemeManager $value)
{
$this->_themeManager=$value;
}
public function getPageStatePersister()
{
if(!$this->_pageStatePersister)
{
$this->_pageStatePersister=new TPageStatePersister;
$this->_pageStatePersister->init(null);
}
return $this->_pageStatePersister;
}
public function setPageStatePersister(IStatePersister $value)
{
$this->_pageStatePersister=$value;
}
public function getRequestedPagePath()
{
return $this->_pagePath;
}
public function getRequestedPage()
{
return $this->_page;
}
public function getDefaultPage()
{
return $this->_defaultPage;
}
public function setDefaultPage($value)
{
if($this->_initialized)
throw new TInvalidOperationException('pageservice_defaultpage_unchangeable');
else
$this->_defaultPage=$value;
}
public function getBasePath()
{
return $this->_basePath;
}
public function setBasePath($value)
{
if($this->_initialized)
throw new TInvalidOperationException('pageservice_basepath_unchangeable');
else if(($this->_basePath=realpath(Prado::getPathOfNamespace($value)))===false || !is_dir($this->_basePath))
throw new TConfigurationException('pageservice_basepath_invalid',$value);
}
public function run()
{
$page=null;
$path=$this->_basePath.'/'.strtr($this->_pagePath,'.','/');
if(is_file($path.self::PAGE_FILE_EXT))
{
if(is_file($path.Prado::CLASS_FILE_EXT))
{
$className=basename($path);
if(!class_exists($className,false))
include_once($path.Prado::CLASS_FILE_EXT);
if(!class_exists($className,false))
throw new TConfigurationException('pageservice_pageclass_unknown',$className);
}
else
$className='TPage';
$this->_properties['Template']=$this->getTemplateManager()->getTemplateByFileName($path.self::PAGE_FILE_EXT);
$this->_page=new $className($this->_properties);
}
else
throw new THttpException(404,'pageservice_page_unknown',$this->_pagePath);
$writer=$this->getResponse()->createHtmlWriter();
$this->_page->run($writer);
$writer->flush();
}
public function constructUrl($pagePath,$getParams=null,$encodeAmpersand=false)
{
return $this->getRequest()->constructUrl($this->_id,$pagePath,$getParams,$encodeAmpersand);
}
public function getAsset($path)
{
return $this->getAssetManager()->publishFilePath($path);
}
}
class TPageConfiguration extends TComponent
{
private $_properties=array();
private $_usings=array();
private $_aliases=array();
private $_modules=array();
private $_parameters=array();
private $_rules=array();
public function getProperties()
{
return $this->_properties;
}
public function getAliases()
{
return $this->_aliases;
}
public function getUsings()
{
return $this->_usings;
}
public function getModules()
{
return $this->_modules;
}
public function getParameters()
{
return $this->_parameters;
}
public function getRules()
{
return $this->_rules;
}
public function loadConfigurationFiles($pagePath,$basePath)
{
$paths=explode('.',$pagePath);
$page=array_pop($paths);
$path=$basePath;
foreach($paths as $p)
{
$this->loadFromFile($path.'/'.TPageService::CONFIG_FILE,null);
$path.='/'.$p;
}
$this->loadFromFile($path.'/'.TPageService::CONFIG_FILE,$page);
$this->_rules=new TAuthorizationRuleCollection($this->_rules);
}
private function loadFromFile($fname,$page)
{
if(empty($fname) || !is_file($fname))
return;
$dom=new TXmlDocument;
if($dom->loadFromFile($fname))
$this->loadXmlElement($dom,dirname($fname),$page);
else
throw new TConfigurationException('pageserviceconf_file_invalid',$fname);
}
public function loadXmlElement($dom,$configPath,$page)
{
if(($pathsNode=$dom->getElementByTagName('paths'))!==null)
{
foreach($pathsNode->getElementsByTagName('alias') as $aliasNode)
{
if(($id=$aliasNode->getAttribute('id'))!==null && ($p=$aliasNode->getAttribute('path'))!==null)
{
$p=str_replace('\\','/',$p);
$path=realpath(preg_match('/^\\/|.:\\//',$p)?$p:$configPath.'/'.$p);
if($path===false || !is_dir($path))
throw new TConfigurationException('pageserviceconf_aliaspath_invalid',$id,$p,$configPath);
if(isset($this->_aliases[$id]))
throw new TConfigurationException('pageserviceconf_alias_redefined',$id,$configPath);
$this->_aliases[$id]=$path;
}
else
throw new TConfigurationException('pageserviceconf_alias_invalid',$configPath);
}
foreach($pathsNode->getElementsByTagName('using') as $usingNode)
{
if(($namespace=$usingNode->getAttribute('namespace'))!==null)
$this->_usings[]=$namespace;
else
throw new TConfigurationException('pageserviceconf_using_invalid',$configPath);
}
}
if(($modulesNode=$dom->getElementByTagName('modules'))!==null)
{
foreach($modulesNode->getElementsByTagName('module') as $node)
{
$properties=$node->getAttributes();
$type=$properties->remove('class');
if(($id=$properties->itemAt('id'))===null)
throw new TConfigurationException('pageserviceconf_module_invalid',$configPath);
if(isset($this->_modules[$id]))
{
if($type===null || $type===$this->_modules[$id][0])
{
$this->_modules[$id][1]=array_merge($this->_modules[$id][1],$properties->toArray());
$elements=$this->_modules[$id][2]->getElements();
foreach($node->getElements() as $element)
$elements->add($element);
}
else
{
$node->setParent(null);
$this->_modules[$id]=array($type,$properties->toArray(),$node);
}
}
else if($type===null)
throw new TConfigurationException('pageserviceconf_moduletype_required',$id,$configPath);
else
{
$node->setParent(null);
$this->_modules[$id]=array($type,$properties->toArray(),$node);
}
}
}
if(($parametersNode=$dom->getElementByTagName('parameters'))!==null)
{
foreach($parametersNode->getElementsByTagName('parameter') as $node)
{
$properties=$node->getAttributes();
if(($id=$properties->remove('id'))===null)
throw new TConfigurationException('pageserviceconf_parameter_invalid',$configPath);
if(($type=$properties->remove('class'))===null)
$this->_parameters[$id]=$node->getValue();
else
$this->_parameters[$id]=array($type,$properties->toArray());
}
}
if(($authorizationNode=$dom->getElementByTagName('authorization'))!==null)
{
$rules=array();
foreach($authorizationNode->getElements() as $node)
{
$pages=$node->getAttribute('pages');
$ruleApplies=false;
if(empty($pages))
$ruleApplies=true;
else if($page!==null)
{
$ps=explode(',',$pages);
foreach($ps as $p)
{
if($page===trim($p))
{
$ruleApplies=true;
break;
}
}
}
if($ruleApplies)
$rules[]=new TAuthorizationRule($node->getTagName(),$node->getAttribute('users'),$node->getAttribute('roles'),$node->getAttribute('verb'));
}
$this->_rules=array_merge($rules,$this->_rules);
}
if(($pagesNode=$dom->getElementByTagName('pages'))!==null)
{
$this->_properties=array_merge($this->_properties,$pagesNode->getAttributes()->toArray());
if($page!==null) {
foreach($pagesNode->getElementsByTagName('page') as $node)
{
$properties=$node->getAttributes();
if(($id=$properties->itemAt('id'))===null)
throw new TConfigurationException('pageserviceconf_page_invalid',$configPath);
if($id===$page)
$this->_properties=array_merge($this->_properties,$properties->toArray());
}
}
}
}
}
?>2,
'a'=>0,
'acronym'=>0,
'address'=>2,
'area'=>1,
'b'=>0,
'base'=>1,
'basefont'=>1,
'bdo'=>0,
'bgsound'=>1,
'big'=>0,
'blockquote'=>2,
'body'=>2,
'br'=>2,
'button'=>0,
'caption'=>2,
'center'=>2,
'cite'=>0,
'code'=>0,
'col'=>1,
'colgroup'=>2,
'del'=>0,
'dd'=>0,
'dfn'=>0,
'dir'=>2,
'div'=>2,
'dl'=>2,
'dt'=>0,
'em'=>0,
'embed'=>1,
'fieldset'=>2,
'font'=>0,
'form'=>2,
'frame'=>1,
'frameset'=>2,
'h1'=>2,
'h2'=>2,
'h3'=>2,
'h4'=>2,
'h5'=>2,
'h6'=>2,
'head'=>2,
'hr'=>1,
'html'=>2,
'i'=>0,
'iframe'=>2,
'img'=>1,
'input'=>1,
'ins'=>0,
'isindex'=>1,
'kbd'=>0,
'label'=>0,
'legend'=>2,
'li'=>0,
'link'=>1,
'map'=>2,
'marquee'=>2,
'menu'=>2,
'meta'=>1,
'nobr'=>0,
'noframes'=>2,
'noscript'=>2,
'object'=>2,
'ol'=>2,
'option'=>2,
'p'=>0,
'param'=>2,
'pre'=>2,
'ruby'=>2,
'rt'=>2,
'q'=>0,
's'=>0,
'samp'=>0,
'script'=>2,
'select'=>2,
'small'=>2,
'span'=>0,
'strike'=>0,
'strong'=>0,
'style'=>2,
'sub'=>0,
'sup'=>0,
'table'=>2,
'tbody'=>2,
'td'=>0,
'textarea'=>0,
'tfoot'=>2,
'th'=>0,
'thead'=>2,
'title'=>2,
'tr'=>2,
'tt'=>0,
'u'=>0,
'ul'=>2,
'var'=>0,
'wbr'=>1,
'xml'=>2
);
private static $_attrEncode=array(
'abbr'=>true,
'accesskey'=>true,
'alt'=>true,
'axis'=>true,
'background'=>true,
'class'=>true,
'content'=>true,
'headers'=>true,
'href'=>true,
'longdesc'=>true,
'onclick'=>true,
'onchange'=>true,
'src'=>true,
'title'=>true,
'value'=>true
);
private static $_styleEncode=array(
'background-image'=>true,
'list-style-image'=>true
);
private $_attributes=array();
private $_openTags=array();
private $_writer=null;
private $_styles=array();
public function __construct($writer)
{
$this->_writer=$writer;
}
public function isValidFormAttribute($name)
{
return true;
}
public function addAttributes($attrs)
{
foreach($attrs as $name=>$value)
$this->_attributes[$name]=isset(self::$_attrEncode[$name])?THttpUtility::htmlEncode($value):$value;
}
public function addAttribute($name,$value)
{
$this->_attributes[$name]=isset(self::$_attrEncode[$name])?THttpUtility::htmlEncode($value):$value;
}
public function addStyleAttribute($name,$value)
{
$this->_styles[$name]=isset(self::$_styleEncode[$name])?THttpUtility::htmlEncode($value):$value;
}
public function flush()
{
$this->_writer->flush();
}
public function write($str)
{
$this->_writer->write($str);
}
public function writeLine($str='')
{
$this->_writer->write($str.self::CHAR_NEWLINE);
}
public function writeBreak()
{
$this->_writer->write('
');
}
public function writeAttribute($name,$value,$encode=false)
{
$this->_writer->write(' '.$name.='"'.($encode?THttpUtility::htmlEncode($value):$value).'"');
}
public function renderBeginTag($tagName)
{
$tagType=isset(self::$_tagTypes[$tagName])?self::$_tagTypes[$tagName]:self::TAG_OTHER;
$str='<'.$tagName;
foreach($this->_attributes as $name=>$value)
$str.=' '.$name.'="'.$value.'"';
if(!empty($this->_styles))
{
$str.=' style="';
foreach($this->_styles as $name=>$value)
$str.=$name.':'.$value.';';
$str.='"';
}
if($tagType===self::TAG_NONCLOSING)
{
$str.=' />';
array_push($this->_openTags,'');
}
else
{
$str.='>';
array_push($this->_openTags,$tagName);
}
$this->_writer->write($str);
$this->_attributes=array();
$this->_styles=array();
}
public function renderEndTag()
{
if(!empty($this->_openTags) && ($tagName=array_pop($this->_openTags))!=='')
$this->_writer->write(''.$tagName.'>');
}
}
?>getService()->setTemplateManager($this);
}
public function getTemplateByClassName($className)
{
$class=new ReflectionClass($className);
$tplFile=dirname($class->getFileName()).'/'.$className.self::TEMPLATE_FILE_EXT;
return $this->getTemplateByFileName($tplFile);
}
public function getTemplateByFileName($fileName)
{
if(!is_null($fileName=$this->getLocalizedTemplate($fileName)))
{
if(($cache=$this->getApplication()->getCache())===null)
return new TTemplate(file_get_contents($fileName),dirname($fileName),$fileName);
else
{
$array=$cache->get(self::TEMPLATE_CACHE_PREFIX.$fileName);
if(is_array($array))
{
list($template,$timestamp)=$array;
if(filemtime($fileName)<$timestamp)
return $template;
}
$template=new TTemplate(file_get_contents($fileName),dirname($fileName),$fileName);
$cache->set(self::TEMPLATE_CACHE_PREFIX.$fileName,array($template,time()));
return $template;
}
}
else
return null;
}
protected function getLocalizedTemplate($filename)
{
$app = $this->getApplication()->getGlobalization();
if(is_null($app)) return $filename;
foreach($app->getLocalizedResource($filename) as $file)
{
if(($file=realpath($file))!==false && is_file($file))
return $file;
}
}
}
class TTemplate extends TComponent implements ITemplate
{
const REGEX_RULES='/||<\/?com:([\w\.]+)((?:\s*[\w\.]+=\'.*?\'|\s*[\w\.]+=".*?"|\s*[\w\.]+=<%.*?%>)*)\s*\/?>|<\/?prop:([\w\.]+)\s*>|<%@\s*((?:\s*[\w\.]+=\'.*?\'|\s*[\w\.]+=".*?")*)\s*%>|<%[%#~\\$=\\[](.*?)%>/msS';
const CONFIG_DATABIND=0;
const CONFIG_EXPRESSION=1;
const CONFIG_ASSET=2;
const CONFIG_PARAMETER=3;
const CONFIG_LOCALIZATION=4;
private $_tpl=array();
private $_directive=array();
private $_contextPath;
private $_tplFile=null;
private $_assetManager;
public function __construct($template,$contextPath,$tplFile=null)
{
$this->_contextPath=$contextPath;
$this->_tplFile=$tplFile;
$this->parse($template);
}
public function getContextPath()
{
return $this->_contextPath;
}
public function getDirective()
{
return $this->_directive;
}
public function &getItems()
{
return $this->_tpl;
}
public function instantiateIn($tplControl)
{
if(($page=$tplControl->getPage())===null)
$page=$this->getService()->getRequestedPage();
$this->_assetManager=$this->getService()->getAssetManager();
$controls=array();
foreach($this->_tpl as $key=>$object)
{
if(isset($object[2])) {
$component=Prado::createComponent($object[1]);
if($component instanceof TControl)
{
$controls[$key]=$component;
$component->setTemplateControl($tplControl);
if(isset($object[2]['id']))
$tplControl->registerObject($object[2]['id'],$component);
if(isset($object[2]['skinid']))
{
$component->setSkinID($object[2]['skinid']);
unset($object[2]['skinid']);
}
$component->applyStyleSheetSkin($page);
foreach($object[2] as $name=>$value)
$this->configureControl($component,$name,$value);
$parent=isset($controls[$object[0]])?$controls[$object[0]]:$tplControl;
$component->createdOnTemplate($parent);
}
else if($component instanceof TComponent)
{
if(isset($object[2]['id']))
{
$tplControl->registerObject($object[2]['id'],$component);
if(!$component->hasProperty('id'))
unset($object[2]['id']);
}
foreach($object[2] as $name=>$value)
$this->configureComponent($component,$name,$value);
$parent=isset($controls[$object[0]])?$controls[$object[0]]:$tplControl;
$parent->addParsedObject($component);
}
}
else {
if(isset($controls[$object[0]]))
$controls[$object[0]]->addParsedObject($object[1]);
else
$tplControl->addParsedObject($object[1]);
}
}
}
protected function configureControl($control,$name,$value)
{
if(is_string($value) && strncasecmp($name,'on',2)===0) $this->configureEvent($control,$name,$value);
else if(strpos($name,'.')===false) $this->configureProperty($control,$name,$value);
else $this->configureSubProperty($control,$name,$value);
}
protected function configureComponent($component,$name,$value)
{
if(strpos($name,'.')===false) $this->configureProperty($component,$name,$value);
else $this->configureSubProperty($component,$name,$value);
}
protected function configureEvent($component,$name,$value)
{
if(strpos($value,'.')===false)
$component->attachEventHandler($name,array($component,'TemplateControl.'.$value));
else
$component->attachEventHandler($name,array($component,$value));
}
protected function configureProperty($component,$name,$value)
{
$setter='set'.$name;
if(is_array($value))
{
switch($value[0])
{
case self::CONFIG_DATABIND:
$component->bindProperty($name,$value[1]);
break;
case self::CONFIG_EXPRESSION:
$component->$setter($component->evaluateExpression($value[1]));
break;
case self::CONFIG_ASSET: $url=$this->_assetManager->publishFilePath($this->_contextPath.'/'.$value[1]);
$component->$setter($url);
break;
case self::CONFIG_PARAMETER: $component->$setter($this->getApplication()->getParameters()->itemAt($value[1]));
break;
case self::CONFIG_LOCALIZATION:
$component->$setter(localize($value[1]));
break;
default: break;
}
}
else
$component->$setter($value);
}
protected function configureSubProperty($component,$name,$value)
{
if(is_array($value))
{
switch($value[0])
{
case self::CONFIG_DATABIND: $component->bindProperty($name,$value[1]);
break;
case self::CONFIG_EXPRESSION: $component->setSubProperty($name,$component->evaluateExpression($value[1]));
break;
case self::CONFIG_ASSET: $url=$this->_assetManager->publishFilePath($this->_contextPath.'/'.$value[1]);
$component->setSubProperty($name,$url);
break;
case self::CONFIG_PARAMETER: $component->setSubProperty($name,$this->getApplication()->getParameters()->itemAt($value[1]));
break;
case self::CONFIG_LOCALIZATION:
$component->setSubProperty($name,localize($value[1]));
break;
default: break;
}
}
else
$component->setSubProperty($name,$value);
}
protected function parse($input)
{
$tpl=&$this->_tpl;
$n=preg_match_all(self::REGEX_RULES,$input,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
$expectPropEnd=false;
$textStart=0;
$stack=array();
$container=-1;
$c=0;
for($i=0;$i<$n;++$i)
{
$match=&$matches[$i];
$str=$match[0][0];
$matchStart=$match[0][1];
$matchEnd=$matchStart+strlen($str)-1;
if(strpos($str,'$textStart)
$tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart));
$textStart=$matchEnd+1;
$type=$match[1][0];
$attributes=$this->parseAttributes($match[2][0]);
try
{
$this->validateAttributes($type,$attributes);
}
catch(Exception $e)
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
throw new TTemplateParsingException('template_componenttag_invalid',"Line $line",$type,$e->getMessage());
else
throw new TTemplateParsingException('template_componenttag_invalid',"{$this->_tplFile} (Line $line)",$type,$e->getMessage());
}
$tpl[$c++]=array($container,$type,$attributes);
if($str[strlen($str)-2]!=='/') {
array_push($stack,$type);
$container=$c-1;
}
}
else if(strpos($str,'$textStart)
$tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart));
$textStart=$matchEnd+1;
$type=$match[1][0];
if(empty($stack))
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
throw new TTemplateParsingException('template_closingtag_unexpected',"Line $line","");
else
throw new TTemplateParsingException('template_closingtag_unexpected',"{$this->_tplFile} (Line $line)","");
}
$name=array_pop($stack);
if($name!==$type)
{
if($name[0]==='@')
$tag='';
else
$tag='';
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
throw new TTemplateParsingException('template_closingtag_expected',"Line $line",$tag);
else
throw new TTemplateParsingException('template_closingtag_expected',"{$this->_tplFile} (Line $line)",$tag);
}
$container=$tpl[$container][0];
}
else if(strpos($str,'<%@')===0) {
if($expectPropEnd)
continue;
if($matchStart>$textStart)
$tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart));
$textStart=$matchEnd+1;
if(isset($tpl[0]))
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
throw new TTemplateParsingException('template_directive_nonunique',"Line $line");
else
throw new TTemplateParsingException('template_directive_nonunique',"{$this->_tplFile} (Line $line)");
}
$this->_directive=$this->parseAttributes($match[4][0]);
}
else if(strpos($str,'<%')===0) {
if($expectPropEnd)
continue;
if($matchStart>$textStart)
$tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart));
$textStart=$matchEnd+1;
if($str[2]==='=') $tpl[$c++]=array($container,'TExpression',array('Expression'=>THttpUtility::htmlDecode($match[5][0])));
else if($str[2]==='%') $tpl[$c++]=array($container,'TStatements',array('Statements'=>THttpUtility::htmlDecode($match[5][0])));
else
$tpl[$c++]=array($container,'TLiteral',array('Text'=>$this->parseAttribute($str)));
}
else if(strpos($str,'$textStart)
$tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart));
$textStart=$matchEnd+1;
$expectPropEnd=true;
}
}
else if(strpos($str,'_tplFile===null)
throw new TTemplateParsingException('template_closingtag_unexpected',"Line $line","");
else
throw new TTemplateParsingException('template_closingtag_unexpected',"{$this->_tplFile} (Line $line)","");
}
$name=array_pop($stack);
if($name!=='@'.$prop)
{
if($name[0]==='@')
$tag='';
else
$tag='';
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
throw new TTemplateParsingException('template_closingtag_expected',"Line $line",$tag);
else
throw new TTemplateParsingException('template_closingtag_expected',"{$this->_tplFile} (Line $line)",$tag);
}
if(($last=count($stack))<1 || $stack[$last-1][0]!=='@')
{
if($matchStart>$textStart && $container>=0)
{
$value=substr($input,$textStart,$matchStart-$textStart);
$value=$this->parseAttribute($value);
$type=$tpl[$container][1];
try
{
$this->validateAttributes($type,array($prop=>$value));
}
catch(Exception $e)
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
throw new TTemplateParsingException('template_componenttag_invalid',"Line $line",$type,$e->getMessage());
else
throw new TTemplateParsingException('template_componenttag_invalid',"{$this->_tplFile} (Line $line)",$type,$e->getMessage());
}
$tpl[$container][2][$prop]=$value;
$textStart=$matchEnd+1;
}
$expectPropEnd=false;
}
}
else if(strpos($str,'