From 57b6793551d29bad2b3b89f9a3f77a11682ccb48 Mon Sep 17 00:00:00 2001
From: xue <>
Date: Wed, 18 Jan 2006 02:43:31 +0000
Subject: Updated phpbuilder and the file list. Added pradolite.php.
---
.gitattributes | 1 +
framework/I18N/TTranslate.php | 64 +-
framework/Web/UI/WebControls/TExpression.php | 2 +-
framework/Web/UI/WebControls/TPlaceHolder.php | 2 +-
framework/Web/UI/WebControls/TStatements.php | 2 +-
framework/Web/UI/WebControls/TTextHighlighter.php | 1 -
framework/core.php | 22 +
framework/pradolite.php | 14631 ++++++++++++++++++++
tools/phpbuilder/build.php | 8 +-
tools/phpbuilder/files.txt | 66 +-
10 files changed, 14756 insertions(+), 43 deletions(-)
create mode 100644 framework/pradolite.php
diff --git a/.gitattributes b/.gitattributes
index e3cbd8ed..cc104658 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -580,6 +580,7 @@ framework/Web/UI/WebControls/TValidationSummary.php -text
framework/Web/UI/WebControls/TWebControl.php -text
framework/core.php -text
framework/prado.php -text
+framework/pradolite.php -text
/index.html -text
requirements/index.php -text
requirements/messages-zh.txt -text
diff --git a/framework/I18N/TTranslate.php b/framework/I18N/TTranslate.php
index ac708191..d38e3281 100644
--- a/framework/I18N/TTranslate.php
+++ b/framework/I18N/TTranslate.php
@@ -2,11 +2,11 @@
/**
* TTranslate, I18N translation component.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the BSD License.
*
- * Copyright(c) 2004 by Xiang Wei Zhuo.
+ * Copyright(c) 2004 by Xiang Wei Zhuo.
*
* To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}
* The latest version of PRADO can be obtained from:
@@ -17,11 +17,9 @@
* @package System.I18N
*/
- Prado::using('System.IO.TTextWriter');
-
/**
* TTranslate class.
- *
+ *
* This component performs message/string translation. The translation
* source is set in the TGlobalization handler. The following example
* demonstrated a simple message translation.
@@ -32,9 +30,9 @@
* Depending on the culture set on the page, the phrase "Goodbye" will
* be translated.
*
- * The values of any attribute in TTranslate are consider as values for
- * substitution. Strings enclosed with "{" and "}" are consider as the
- * parameters. The following example will substitution the string
+ * The values of any attribute in TTranslate are consider as values for
+ * substitution. Strings enclosed with "{" and "}" are consider as the
+ * parameters. The following example will substitution the string
* "{time}" with the value of the attribute "time="#time()". Note that
* the value of the attribute time is evaluated.
*
@@ -44,17 +42,17 @@
*
*
* More complex string substitution can be applied using the
- * TParam component.
+ * TParam component.
*
* Namespace: System.I18N
*
* Properties
- * - Text, string,
- *
Gets or sets the string to translate.
+ * - Text, string,
+ *
Gets or sets the string to translate.
* - Catalogue, string,
*
Gets or sets the catalogue for message translation. The
* default catalogue can be set by the @Page directive.
- * - Key, string,
+ * - Key, string,
*
Gets or sets the key used to message look up.
* - Trim, boolean,
*
Gets or sets an option to trim the contents.
@@ -65,7 +63,7 @@
* @package System.I18N
*/
class TTranslate extends TI18NControl
-{
+{
/**
* @return string the text to be localized/translated.
*/
@@ -91,52 +89,52 @@ class TTranslate extends TI18NControl
{
$this->setViewState('Key',$value,'');
}
-
+
/**
* Get the key for message lookup.
* @return string key
- */
+ */
function getKey()
{
return $this->getViewState('Key','');
}
-
+
/**
* Get the message catalogue.
- * @return string catalogue.
+ * @return string catalogue.
*/
function getCatalogue()
{
return $this->getViewState('Catalogue','');
}
-
+
/**
* Set the message catalogue.
- * @param string catalogue.
- */
+ * @param string catalogue.
+ */
function setCatalogue($value)
{
$this->setViewState('Catalogue',$value,'');
}
-
+
/**
* Set the option to trim the contents.
* @param boolean trim or not.
- */
+ */
function setTrim($value)
{
$this->setViewState('Trim',TPropertyValue::ensureBoolean($value),true);
}
-
+
/**
* Trim the content or not.
- * @return boolean trim or not.
- */
+ * @return boolean trim or not.
+ */
function getTrim()
{
return $this->getViewState('Trim',true);
}
-
+
/**
* renders the translated string.
*/
@@ -157,8 +155,8 @@ class TTranslate extends TI18NControl
$text = $this->getText();
if(strlen($text)==0)
- $text = $textWriter->flush();
- if($this->getTrim())
+ $text = $textWriter->flush();
+ if($this->getTrim())
$text = trim($text);
$writer->write($this->translateText($text, $subs));
@@ -177,20 +175,20 @@ class TTranslate extends TI18NControl
//no translation handler provided
if(is_null($config = $app->getTranslationConfiguration()))
return strtr($text, $subs);
-
+
Translation::init();
-
+
$catalogue = $this->getCatalogue();
if(empty($catalogue) && isset($config['catalogue']))
$catalogue = $config['catalogue'];
-
+
$key = $this->getKey();
if(!empty($key)) $text = $key;
-
+
//translate it
return Translation::formatter()->format($text,
$subs, $catalogue, $this->getCharset());
- }
+ }
}
?>
\ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TExpression.php b/framework/Web/UI/WebControls/TExpression.php
index eb1151b0..a1c00c9a 100644
--- a/framework/Web/UI/WebControls/TExpression.php
+++ b/framework/Web/UI/WebControls/TExpression.php
@@ -60,4 +60,4 @@ class TExpression extends TControl
}
}
-?>
+?>
\ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TPlaceHolder.php b/framework/Web/UI/WebControls/TPlaceHolder.php
index 91979a26..bc6858ff 100644
--- a/framework/Web/UI/WebControls/TPlaceHolder.php
+++ b/framework/Web/UI/WebControls/TPlaceHolder.php
@@ -26,4 +26,4 @@ class TPlaceHolder extends TControl
{
}
-?>
+?>
\ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TStatements.php b/framework/Web/UI/WebControls/TStatements.php
index 0474acf1..28e25500 100644
--- a/framework/Web/UI/WebControls/TStatements.php
+++ b/framework/Web/UI/WebControls/TStatements.php
@@ -61,4 +61,4 @@ class TStatements extends TControl
}
}
-?>
+?>
\ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TTextHighlighter.php b/framework/Web/UI/WebControls/TTextHighlighter.php
index 56ae406e..be104896 100644
--- a/framework/Web/UI/WebControls/TTextHighlighter.php
+++ b/framework/Web/UI/WebControls/TTextHighlighter.php
@@ -14,7 +14,6 @@
* Using GeSHi and TTextWriter classes
*/
Prado::using('System.3rdParty.geshi.geshi');
-Prado::using('System.IO.TTextWriter');
/**
* TTextHighlighter class.
diff --git a/framework/core.php b/framework/core.php
index de307cad..57c683b2 100644
--- a/framework/core.php
+++ b/framework/core.php
@@ -771,6 +771,28 @@ class PradoBase
}
}
+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
{
}
diff --git a/framework/pradolite.php b/framework/pradolite.php
new file mode 100644
index 00000000..6b8a5e2f
--- /dev/null
+++ b/framework/pradolite.php
@@ -0,0 +1,14631 @@
+$getter();
+ }
+ else if(method_exists($this,'on'.$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(method_exists($this,'on'.$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);
+ }
+ }
+final public function hasProperty($name)
+ {
+ return method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
+ }
+final public function canGetProperty($name)
+ {
+ return method_exists($this,'get'.$name);
+ }
+final 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 method_exists($this,'on'.$name);
+ }
+public function hasEventHandler($name)
+ {
+ $name=strtolower($name);
+ return isset($this->_e[$name]) && $this->_e[$name]->getCount()>0;
+ }
+public function getEventHandlers($name)
+ {
+ if(method_exists($this,'on'.$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;
+ }
+}
+?>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(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.0a';
+ }
+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)
+ {
+ if(!class_exists($type,false))
+ {
+ if(($pos=strrpos($type,'.'))===false)
+ {
+ include_once($type.self::CLASS_FILE_EXT);
+ if(!class_exists($type,false))
+ throw new TInvalidOperationException('prado_component_unknown',$type);
+ }
+ else
+ {
+ $className=substr($type,$pos+1);
+ if(!class_exists($className,false) && ($path=self::getPathOfNamespace($type))!==null)
+ {
+ include_once($path.self::CLASS_FILE_EXT);
+ if(!class_exists($className,false))
+ throw new TInvalidOperationException('prado_component_unknown',$type);
+ }
+ $type=$className;
+ }
+ }
+ 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]))
+ {
+ if(($path=self::getPathOfNamespace($namespace,self::CLASS_FILE_EXT))===null)
+ throw new TInvalidDataValueException('prado_using_invalid',$namespace);
+ else
+ {
+ if($namespace[strlen($namespace)-1]==='*') {
+ 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(substr(strrchr($namespace,'.'),1),false))
+ require_once($path);
+ }
+ 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)
+ {
+ if(isset(self::$_aliases[$alias]))
+ return self::$_aliases[$alias];
+ else
+ return 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))
+ self::$_aliases[$alias]=$rp;
+ 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('Error'))
+ $this->raiseEvent('Error',$this,$param);
+ else
+ $this->getErrorHandler()->handleError($this,$param);
+ }
+public function onBeginRequest($param)
+ {
+ $this->raiseEvent('BeginRequest',$this,$param);
+ }
+public function onAuthentication($param)
+ {
+ $this->raiseEvent('Authentication',$this,$param);
+ }
+public function onPostAuthentication($param)
+ {
+ $this->raiseEvent('PostAuthentication',$this,$param);
+ }
+public function onAuthorization($param)
+ {
+ $this->raiseEvent('Authorization',$this,$param);
+ }
+public function onPostAuthorization($param)
+ {
+ $this->raiseEvent('PostAuthorization',$this,$param);
+ }
+public function onLoadState($param)
+ {
+ $this->loadGlobals();
+ $this->raiseEvent('LoadState',$this,$param);
+ }
+public function onPostLoadState($param)
+ {
+ $this->raiseEvent('PostLoadState',$this,$param);
+ }
+public function onPreRunService($param)
+ {
+ $this->raiseEvent('PreRunService',$this,$param);
+ }
+public function onRunService($param)
+ {
+ $this->raiseEvent('RunService',$this,$param);
+ if($this->_service)
+ $this->_service->run();
+ }
+public function onPostRunService($param)
+ {
+ $this->raiseEvent('PostRunService',$this,$param);
+ }
+public function onSaveState($param)
+ {
+ $this->raiseEvent('SaveState',$this,$param);
+ $this->saveGlobals();
+ }
+public function onPostSaveState($param)
+ {
+ $this->raiseEvent('PostSaveState',$this,$param);
+ }
+public function onEndRequest($param)
+ {
+ $this->raiseEvent('EndRequest',$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
+ throw new TTemplateRuntimeException('template_component_required',$object[1]);
+ }
+ 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) && $control->hasEvent($name)) $this->configureEvent($control,$name,$value);
+ else if(strpos($name,'.')===false) {
+ if($control->hasProperty($name))
+ $this->configureProperty($control,$name,$value);
+ else if($control->getAllowCustomAttributes())
+ $this->configureAttribute($control,$name,$value);
+ else
+ throw new TTemplateRuntimeException('template_property_undefined',get_class($control),$name);
+ }
+ else {
+ $this->configureSubProperty($control,$name,$value);
+ }
+ }
+protected function configureComponent($component,$name,$value)
+ {
+ if(strpos($name,'.')===false) {
+ if($component->hasProperty($name))
+ $this->configureProperty($component,$name,$value);
+ else
+ throw new TTemplateRuntimeException('template_property_undefined',get_class($component),$name);
+ }
+ else {
+ $this->configureSubProperty($component,$name,$value);
+ }
+ }
+protected function configureEvent($component,$name,$value)
+ {
+ $value=THttpUtility::htmlDecode($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)
+ {
+ if($component->canSetProperty($name))
+ {
+ $setter='set'.$name;
+ if(is_array($value))
+ {
+ $v=THttpUtility::htmlDecode($value[1]);
+ switch($value[0])
+ {
+ case self::CONFIG_DATABIND:
+ $component->bindProperty($name,$v);
+ break;
+ case self::CONFIG_EXPRESSION:
+ $component->$setter($component->evaluateExpression($v));
+ break;
+ case self::CONFIG_ASSET: $url=$this->_assetManager->publishFilePath($this->_contextPath.'/'.$v);
+ $component->$setter($url);
+ break;
+ case self::CONFIG_PARAMETER: $component->$setter($this->getApplication()->getParameters()->itemAt($v));
+ break;
+ case self::CONFIG_LOCALIZATION:
+ $component->$setter(localize($v));
+ break;
+ default: break;
+ }
+ }
+ else
+ $component->$setter(THttpUtility::htmlDecode($value));
+ }
+ else
+ throw new TTemplateRuntimeException('template_property_readonly',get_class($component),$name);
+ }
+protected function configureSubProperty($component,$name,$value)
+ {
+ if(is_array($value))
+ {
+ $v=THttpUtility::htmlDecode($value[1]);
+ switch($value[0])
+ {
+ case self::CONFIG_DATABIND: $component->bindProperty($name,$v);
+ break;
+ case self::CONFIG_EXPRESSION: $component->setSubProperty($name,$component->evaluateExpression($v));
+ break;
+ case self::CONFIG_ASSET: $url=$this->_assetManager->publishFilePath($this->_contextPath.'/'.$v);
+ $component->setSubProperty($name,$url);
+ break;
+ case self::CONFIG_PARAMETER: $component->setSubProperty($name,$this->getApplication()->getParameters()->itemAt($v));
+ break;
+ case self::CONFIG_LOCALIZATION:
+ $component->setSubProperty($name,localize($v));
+ break;
+ default: break;
+ }
+ }
+ else
+ $component->setSubProperty($name,THttpUtility::htmlDecode($value));
+ }
+protected function configureAttribute($control,$name,$value)
+ {
+ if(is_array($value))
+ {
+ switch($value[0])
+ {
+ case self::CONFIG_DATABIND: throw new TTemplateRuntimeException('template_attribute_unbindable',get_class($control),$name);
+ case self::CONFIG_EXPRESSION:
+ $value=$control->evaluateExpression($value[1]);
+ break;
+ case self::CONFIG_ASSET:
+ $value=$this->_assetManager->publishFilePath($this->_contextPath.'/'.ltrim($value[1],'/'));
+ break;
+ case self::CONFIG_PARAMETER:
+ $value=$this->getApplication()->getParameters()->itemAt($value[1]);
+ break;
+ case self::CONFIG_LOCALIZATION:
+ $value=localize($value[1]);
+ break;
+ default:
+ break;
+ }
+ }
+ $control->getAttributes()->add($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]);
+ $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'=>$match[5][0]));
+ else if($str[2]==='%') $tpl[$c++]=array($container,'TStatements',array('Statements'=>$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);
+ $tpl[$container][2][$prop]=$this->parseAttribute($value);
+ $textStart=$matchEnd+1;
+ }
+ $expectPropEnd=false;
+ }
+ }
+ else if(strpos($str,'