diff options
Diffstat (limited to 'framework')
32 files changed, 1979 insertions, 12428 deletions
diff --git a/framework/IActiveControl.php b/framework/IActiveControl.php new file mode 100644 index 00000000..ccdbac12 --- /dev/null +++ b/framework/IActiveControl.php @@ -0,0 +1,27 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IActiveControl interface. + * + * Active controls must implement IActiveControl interface. + * + * @author Wei Zhuo <weizhuo[at]gamil[dot]com> + * @package System + * @since 3.1 + */ +interface IActiveControl +{ + /** + * @return TBaseActiveControl Active control properties. + */ + public function getActiveControl(); +}
\ No newline at end of file diff --git a/framework/IBaseBehavior.php b/framework/IBaseBehavior.php new file mode 100644 index 00000000..5c55f1f0 --- /dev/null +++ b/framework/IBaseBehavior.php @@ -0,0 +1,36 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IBaseBehavior interface is the base behavior class from which all other + * behaviors types are derived + * + * @author Brad Anderson <javalizard@mac.com> + * @version $Id$ + * @package System + * @since 3.2.3 + */ +interface IBaseBehavior { + /** + * Attaches the behavior object to the component. + * @param CComponent the component that this behavior is to be attached to. + */ + public function attach($component); + /** + * Detaches the behavior object from the component. + * @param CComponent the component that this behavior is to be detached from. + */ + public function detach($component); +}
\ No newline at end of file diff --git a/framework/IBehavior.php b/framework/IBehavior.php new file mode 100644 index 00000000..354fb94d --- /dev/null +++ b/framework/IBehavior.php @@ -0,0 +1,38 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IBehavior interfaces is implemented by instance behavior classes. + * + * A behavior is a way to enhance a component with additional methods and + * events that are defined in the behavior class and not available in the + * class. Objects may signal behaviors through dynamic events. + * + * @author Brad Anderson <javalizard@mac.com> + * @version $Id$ + * @package System + * @since 3.2.3 + */ +interface IBehavior extends IBaseBehavior +{ + /** + * @return boolean whether this behavior is enabled + */ + public function getEnabled(); + /** + * @param boolean whether this behavior is enabled + */ + public function setEnabled($value); +}
\ No newline at end of file diff --git a/framework/IBindable.php b/framework/IBindable.php new file mode 100644 index 00000000..e6ee32fa --- /dev/null +++ b/framework/IBindable.php @@ -0,0 +1,27 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IBindable interface. + * + * This interface must be implemented by classes that are capable of performing databinding. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface IBindable +{ + /** + * Performs databinding. + */ + public function dataBind(); +}
\ No newline at end of file diff --git a/framework/ICache.php b/framework/ICache.php new file mode 100644 index 00000000..d50694dd --- /dev/null +++ b/framework/ICache.php @@ -0,0 +1,63 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + + +/** + * ICache interface. + * + * This interface must be implemented by cache managers. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface ICache +{ + /** + * Retrieves a value from cache with a specified key. + * @param string a key identifying the cached value + * @return mixed the value stored in cache, false if the value is not in the cache or expired. + */ + public function get($id); + /** + * Stores a value identified by a key into cache. + * If the cache already contains such a key, the existing value and + * expiration time will be replaced with the new ones. + * + * @param string the key identifying the value to be cached + * @param mixed the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @param ICacheDependency dependency of the cached item. If the dependency changes, the item is labelled invalid. + * @return boolean true if the value is successfully stored into cache, false otherwise + */ + public function set($id,$value,$expire=0,$dependency=null); + /** + * Stores a value identified by a key into cache if the cache does not contain this key. + * Nothing will be done if the cache already contains the key. + * @param string the key identifying the value to be cached + * @param mixed the value to be cached + * @param integer the number of seconds in which the cached value will expire. 0 means never expire. + * @param ICacheDependency dependency of the cached item. If the dependency changes, the item is labelled invalid. + * @return boolean true if the value is successfully stored into cache, false otherwise + */ + public function add($id,$value,$expire=0,$dependency=null); + /** + * Deletes a value with the specified key from cache + * @param string the key of the value to be deleted + * @return boolean if no error happens during deletion + */ + public function delete($id); + /** + * Deletes all values from cache. + * Be careful of performing this operation if the cache is shared by multiple applications. + */ + public function flush(); +}
\ No newline at end of file diff --git a/framework/ICacheDependency.php b/framework/ICacheDependency.php new file mode 100644 index 00000000..c584e891 --- /dev/null +++ b/framework/ICacheDependency.php @@ -0,0 +1,30 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * ICacheDependency interface. + * + * This interface must be implemented by classes meant to be used as + * cache dependencies. + * + * Classes implementing this interface must support serialization and unserialization. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface ICacheDependency +{ + /** + * @return boolean whether the dependency has changed. Defaults to false. + */ + public function getHasChanged(); +}
\ No newline at end of file diff --git a/framework/ICallbackEventHandler.php b/framework/ICallbackEventHandler.php new file mode 100644 index 00000000..3afb3674 --- /dev/null +++ b/framework/ICallbackEventHandler.php @@ -0,0 +1,31 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * ICallbackEventHandler interface. + * + * If a control wants to respond to callback event, it must implement this + * interface. + * + * @author Wei Zhuo <weizhuo[at]gamil[dot]com> + * @package System + * @since 3.1 + */ +interface ICallbackEventHandler +{ + /** + * Raises callback event. The implementation of this function should raise + * appropriate event(s) (e.g. OnClick, OnCommand) indicating the component + * is responsible for the callback event. + * @param TCallbackEventParameter the parameter associated with the callback event + */ + public function raiseCallbackEvent($eventArgument); +}
\ No newline at end of file diff --git a/framework/IClassBehavior.php b/framework/IClassBehavior.php new file mode 100644 index 00000000..634cb1c4 --- /dev/null +++ b/framework/IClassBehavior.php @@ -0,0 +1,49 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + + +/** + * IClassBehavior interface is implements behaviors across all instances of + * a particular class + * + * Any calls to functions not present in the original object but to behaviors + * derived from this class, will have inserted as the first argument parameter + * the object containing the behavior. + * + * For example: + * <code> + * $objWithClassBehavior->MethodOfClassBehavior(1, 20); + * </code> + * will be acted within the class behavior like this: + * <code> + * public function MethodOfClassBehavior($object, $firstParam, $secondParam){ + * // $object === $objWithClassBehavior, $firstParam === 1, $secondParam === 20 + * } + * </code> + * + * This also holds for 'dy' events as well. For dynamic events, method arguments would be: + * <code> + * public function dyMethodOfClassBehavior($object, $firstParam, $secondParam, $callchain){ + * // $object === $objWithClassBehavior, $firstParam === 1, $secondParam === 20, $callchain instanceof {@link TCallChain} + * } + * </code> + * + * @author Brad Anderson <javalizard@mac.com> + * @version $Id$ + * @package System + * @since 3.2.3 + */ +interface IClassBehavior extends IBaseBehavior { +}
\ No newline at end of file diff --git a/framework/IDataRenderer.php b/framework/IDataRenderer.php new file mode 100644 index 00000000..f8deee8a --- /dev/null +++ b/framework/IDataRenderer.php @@ -0,0 +1,33 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IDataRenderer interface. + * + * If a control wants to be used a renderer for another data-bound control, + * this interface must be implemented. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.1 + */ +interface IDataRenderer +{ + /** + * @return mixed the data bound to this object + */ + public function getData(); + + /** + * @param mixed the data to be bound to this object + */ + public function setData($value); +}
\ No newline at end of file diff --git a/framework/IDynamicMethods.php b/framework/IDynamicMethods.php new file mode 100644 index 00000000..8a0de9ef --- /dev/null +++ b/framework/IDynamicMethods.php @@ -0,0 +1,29 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + + +/** + * IDynamicMethods interface. + * IDynamicMethods marks an object to receive undefined global or dynamic events. + * + * @author Brad Anderson <javalizard@mac.com> + * @version $Id$ + * @package System + * @since 3.2.3 + */ +interface IDynamicMethods +{ + public function __dycall($method,$args); +}
\ No newline at end of file diff --git a/framework/IInstanceCheck.php b/framework/IInstanceCheck.php new file mode 100644 index 00000000..8af12117 --- /dev/null +++ b/framework/IInstanceCheck.php @@ -0,0 +1,40 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + + +/** + * IInstanceCheck This interface allows objects to determine their own + * 'instanceof' results when {@link TComponent::isa} is called. This is + * important with behaviors because behaviors may want to look like + * particular objects other than themselves. + * + * @author Brad Anderson <javalizard@mac.com> + * @version $Id$ + * @package System + * @since 3.2.3 + */ +interface IInstanceCheck { + /** + * The method checks $this or, if needed, the parameter $instance is of type + * class. In the case of a Class Behavior, the instance to which the behavior + * is attached may be important to determine if $this is an instance + * of a particular class. + * @param class|string the component that this behavior is checking if it is an instanceof. + * @param object the object which the behavior is attached to. default: null + * @return boolean|null if the this or the instance is of type class. When null, no information could be derived and + * the default mechanisms take over. + */ + public function isinstanceof($class,$instance=null); +}
\ No newline at end of file diff --git a/framework/IModule.php b/framework/IModule.php new file mode 100644 index 00000000..4d1eaf00 --- /dev/null +++ b/framework/IModule.php @@ -0,0 +1,36 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IModule interface. + * + * This interface must be implemented by application modules. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface IModule +{ + /** + * Initializes the module. + * @param TXmlElement the configuration for the module + */ + public function init($config); + /** + * @return string ID of the module + */ + public function getID(); + /** + * @param string ID of the module + */ + public function setID($id); +}
\ No newline at end of file diff --git a/framework/IRenderable.php b/framework/IRenderable.php new file mode 100644 index 00000000..f455097e --- /dev/null +++ b/framework/IRenderable.php @@ -0,0 +1,29 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IRenderable interface. + * + * This interface must be implemented by classes that can be rendered + * to end-users. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface IRenderable +{ + /** + * Renders the component to end-users. + * @param ITextWriter writer for the rendering purpose + */ + public function render($writer); +}
\ No newline at end of file diff --git a/framework/IService.php b/framework/IService.php new file mode 100644 index 00000000..5cdbbcff --- /dev/null +++ b/framework/IService.php @@ -0,0 +1,48 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IService interface. + * + * This interface must be implemented by services. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface IService +{ + /** + * Initializes the service. + * @param TXmlElement the configuration for the service + */ + public function init($config); + /** + * @return string ID of the service + */ + public function getID(); + /** + * @param string ID of the service + */ + public function setID($id); + /** + * @return boolean whether the service is enabled + */ + public function getEnabled(); + /** + * @param boolean whether the service is enabled + */ + public function setEnabled($value); + /** + * Runs the service. + */ + public function run(); +}
\ No newline at end of file diff --git a/framework/IStatePersister.php b/framework/IStatePersister.php new file mode 100644 index 00000000..c8ab5f25 --- /dev/null +++ b/framework/IStatePersister.php @@ -0,0 +1,34 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IStatePersister class. + * + * This interface must be implemented by all state persister classes (such as + * {@link TPageStatePersister}, {@link TApplicationStatePersister}. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface IStatePersister +{ + /** + * Loads state from a persistent storage. + * @return mixed the state + */ + public function load(); + /** + * Saves state into a persistent storage. + * @param mixed the state to be saved + */ + public function save($state); +}
\ No newline at end of file diff --git a/framework/IStyleable.php b/framework/IStyleable.php new file mode 100644 index 00000000..92cc13ad --- /dev/null +++ b/framework/IStyleable.php @@ -0,0 +1,35 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * IStyleable interface. + * + * This interface should be implemented by classes that support CSS styles. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.1.0 + */ +interface IStyleable +{ + /** + * @return boolean whether the object has defined any style information + */ + public function getHasStyle(); + /** + * @return TStyle the object representing the css style of the object + */ + public function getStyle(); + /** + * Removes all styles associated with the object + */ + public function clearStyle(); +}
\ No newline at end of file diff --git a/framework/ITextWriter.php b/framework/ITextWriter.php new file mode 100644 index 00000000..bc7fa512 --- /dev/null +++ b/framework/ITextWriter.php @@ -0,0 +1,32 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * ITextWriter interface. + * + * This interface must be implemented by writers. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface ITextWriter +{ + /** + * Writes a string. + * @param string string to be written + */ + public function write($str); + /** + * Flushes the content that has been written. + */ + public function flush(); +}
\ No newline at end of file diff --git a/framework/IUser.php b/framework/IUser.php new file mode 100644 index 00000000..b8f7a6f6 --- /dev/null +++ b/framework/IUser.php @@ -0,0 +1,62 @@ +<?php +/** + * Core interfaces essential for TApplication class. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + + +/** + * IUser interface. + * + * This interface must be implemented by user objects. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +interface IUser +{ + /** + * @return string username + */ + public function getName(); + /** + * @param string username + */ + public function setName($value); + /** + * @return boolean if the user is a guest + */ + public function getIsGuest(); + /** + * @param boolean if the user is a guest + */ + public function setIsGuest($value); + /** + * @return array list of roles that the user is of + */ + public function getRoles(); + /** + * @return array|string list of roles that the user is of. If it is a string, roles are assumed by separated by comma + */ + public function setRoles($value); + /** + * @param string role to be tested + * @return boolean whether the user is of this role + */ + public function isInRole($role); + /** + * @return string user data that is serialized and will be stored in session + */ + public function saveToString(); + /** + * @param string user data that is serialized and restored from session + * @return IUser the user object + */ + public function loadFromString($string); +}
\ No newline at end of file diff --git a/framework/TApplication.php b/framework/TApplication.php index e015ead8..476fb5e1 100644 --- a/framework/TApplication.php +++ b/framework/TApplication.php @@ -1267,608 +1267,3 @@ class TApplication extends TComponent $this->raiseEvent('OnEndRequest',$this,null); } } - -/** - * TApplicationMode class. - * TApplicationMode defines the possible mode that an application can be set at by - * setting {@link TApplication::setMode Mode}. - * In particular, the following modes are defined - * - Off: the application is not running. Any request to the application will obtain an error. - * - Debug: the application is running in debug mode. - * - Normal: the application is running in normal production mode. - * - Performance: the application is running in performance mode. - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System - * @since 3.0.4 - */ -class TApplicationMode extends TEnumerable -{ - const Off='Off'; - const Debug='Debug'; - const Normal='Normal'; - const Performance='Performance'; -} - - -/** - * TApplicationConfiguration class. - * - * This class is used internally by TApplication to parse and represent application configuration. - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @author Carl G. Mathisen <carlgmathisen@gmail.com> - * @package System - * @since 3.0 - */ -class TApplicationConfiguration extends TComponent -{ - /** - * @var array list of application initial property values, indexed by property names - */ - private $_properties=array(); - /** - * @var array list of namespaces to be used - */ - private $_usings=array(); - /** - * @var array list of path aliases, indexed by alias names - */ - private $_aliases=array(); - /** - * @var array list of module configurations - */ - private $_modules=array(); - /** - * @var array list of service configurations - */ - private $_services=array(); - /** - * @var array list of parameters - */ - private $_parameters=array(); - /** - * @var array list of included configurations - */ - private $_includes=array(); - /** - * @var boolean whether this configuration contains actual stuff - */ - private $_empty=true; - - /** - * Parses the application configuration file. - * @param string configuration file name - * @throws TConfigurationException if there is any parsing error - */ - public function loadFromFile($fname) - { - if(Prado::getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP) - { - $fcontent = include $fname; - $this->loadFromPhp($fcontent,dirname($fname)); - } - else - { - $dom=new TXmlDocument; - $dom->loadFromFile($fname); - $this->loadFromXml($dom,dirname($fname)); - } - } - - /** - * @return boolean whether this configuration contains actual stuff - */ - public function getIsEmpty() - { - return $this->_empty; - } - - /** - * Parses the application configuration given in terms of a PHP array. - * @param array the PHP array - * @param string the context path (for specifying relative paths) - */ - public function loadFromPhp($config, $configPath) - { - // application properties - if(isset($config['application'])) - { - foreach($config['application'] as $name=>$value) - { - $this->_properties[$name]=$value; - } - $this->_empty = false; - } - - if(isset($config['paths']) && is_array($config['paths'])) - $this->loadPathsPhp($config['paths'],$configPath); - - if(isset($config['modules']) && is_array($config['modules'])) - $this->loadModulesPhp($config['modules'],$configPath); - - if(isset($config['services']) && is_array($config['services'])) - $this->loadServicesPhp($config['services'],$configPath); - - if(isset($config['parameters']) && is_array($config['parameters'])) - $this->loadParametersPhp($config['parameters'], $configPath); - - if(isset($config['includes']) && is_array($config['includes'])) - $this->loadExternalXml($config['includes'],$configPath); - } - - /** - * Parses the application configuration given in terms of a TXmlElement. - * @param TXmlElement the XML element - * @param string the context path (for specifying relative paths) - */ - public function loadFromXml($dom,$configPath) - { - // application properties - foreach($dom->getAttributes() as $name=>$value) - { - $this->_properties[$name]=$value; - $this->_empty=false; - } - - foreach($dom->getElements() as $element) - { - switch($element->getTagName()) - { - case 'paths': - $this->loadPathsXml($element,$configPath); - break; - case 'modules': - $this->loadModulesXml($element,$configPath); - break; - case 'services': - $this->loadServicesXml($element,$configPath); - break; - case 'parameters': - $this->loadParametersXml($element,$configPath); - break; - case 'include': - $this->loadExternalXml($element,$configPath); - break; - default: - //throw new TConfigurationException('appconfig_tag_invalid',$element->getTagName()); - break; - } - } - } - - /** - * Loads the paths PHP array - * @param array the paths PHP array - * @param string the context path (for specifying relative paths) - */ - protected function loadPathsPhp($pathsNode, $configPath) - { - if(isset($pathsNode['aliases']) && is_array($pathsNode['aliases'])) - { - foreach($pathsNode['aliases'] as $id=>$path) - { - $path=str_replace('\\','/',$path); - if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) // if absolute path - $p=realpath($path); - else - $p=realpath($configPath.DIRECTORY_SEPARATOR.$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; - } - } - - if(isset($pathsNode['using']) && is_array($pathsNode['using'])) - { - foreach($pathsNode['using'] as $namespace) - { - $this->_usings[] = $namespace; - } - } - } - - /** - * Loads the paths XML node. - * @param TXmlElement the paths XML node - * @param string the context path (for specifying relative paths) - */ - protected function loadPathsXml($pathsNode,$configPath) - { - foreach($pathsNode->getElements() as $element) - { - switch($element->getTagName()) - { - case 'alias': - { - if(($id=$element->getAttribute('id'))!==null && ($path=$element->getAttribute('path'))!==null) - { - $path=str_replace('\\','/',$path); - if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) // if absolute path - $p=realpath($path); - else - $p=realpath($configPath.DIRECTORY_SEPARATOR.$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'); - $this->_empty=false; - break; - } - case 'using': - { - if(($namespace=$element->getAttribute('namespace'))!==null) - $this->_usings[]=$namespace; - else - throw new TConfigurationException('appconfig_using_invalid'); - $this->_empty=false; - break; - } - default: - throw new TConfigurationException('appconfig_paths_invalid',$element->getTagName()); - } - } - } - - /** - * Loads the modules PHP array. - * @param array the modules PHP array - * @param string the context path (for specifying relative paths) - */ - protected function loadModulesPhp($modulesNode, $configPath) - { - foreach($modulesNode as $id=>$module) - { - if(!isset($module['class'])) - throw new TConfigurationException('appconfig_moduletype_required',$id); - $type = $module['class']; - unset($module['class']); - $properties = array(); - if(isset($module['properties'])) - { - $properties = $module['properties']; - unset($module['properties']); - } - $properties['id'] = $id; - $this->_modules[$id]=array($type,$properties,$module); - $this->_empty=false; - } - } - - /** - * Loads the modules XML node. - * @param TXmlElement the modules XML node - * @param string the context path (for specifying relative paths) - */ - protected function loadModulesXml($modulesNode,$configPath) - { - foreach($modulesNode->getElements() as $element) - { - if($element->getTagName()==='module') - { - $properties=$element->getAttributes(); - $id=$properties->itemAt('id'); - $type=$properties->remove('class'); - if($type===null) - throw new TConfigurationException('appconfig_moduletype_required',$id); - $element->setParent(null); - if($id===null) - $this->_modules[]=array($type,$properties->toArray(),$element); - else - $this->_modules[$id]=array($type,$properties->toArray(),$element); - $this->_empty=false; - } - else - throw new TConfigurationException('appconfig_modules_invalid',$element->getTagName()); - } - } - - /** - * Loads the services PHP array. - * @param array the services PHP array - * @param string the context path (for specifying relative paths) - */ - protected function loadServicesPhp($servicesNode,$configPath) - { - foreach($servicesNode as $id => $service) - { - if(!isset($service['class'])) - throw new TConfigurationException('appconfig_servicetype_required'); - $type = $service['class']; - $properties = isset($service['properties']) ? $service['properties'] : array(); - unset($service['properties']); - $properties['id'] = $id; - $this->_services[$id] = array($type,$properties,$service); - $this->_empty = false; - } - } - - /** - * Loads the services XML node. - * @param TXmlElement the services XML node - * @param string the context path (for specifying relative paths) - */ - protected function loadServicesXml($servicesNode,$configPath) - { - foreach($servicesNode->getElements() as $element) - { - if($element->getTagName()==='service') - { - $properties=$element->getAttributes(); - if(($id=$properties->itemAt('id'))===null) - throw new TConfigurationException('appconfig_serviceid_required'); - if(($type=$properties->remove('class'))===null) - throw new TConfigurationException('appconfig_servicetype_required',$id); - $element->setParent(null); - $this->_services[$id]=array($type,$properties->toArray(),$element); - $this->_empty=false; - } - else - throw new TConfigurationException('appconfig_services_invalid',$element->getTagName()); - } - } - - /** - * Loads the parameters PHP array. - * @param array the parameters PHP array - * @param string the context path (for specifying relative paths) - */ - protected function loadParametersPhp($parametersNode,$configPath) - { - foreach($parametersNode as $id => $parameter) - { - if(is_array($parameter)) - { - if(isset($parameter['class'])) - { - $type = $parameter['class']; - unset($parameter['class']); - $properties = isset($service['properties']) ? $service['properties'] : array(); - $properties['id'] = $id; - $this->_parameters[$id] = array($type,$properties); - } - } - else - { - $this->_parameters[$id] = $parameter; - } - } - } - - /** - * Loads the parameters XML node. - * @param TXmlElement the parameters XML node - * @param string the context path (for specifying relative paths) - */ - protected function loadParametersXml($parametersNode,$configPath) - { - foreach($parametersNode->getElements() as $element) - { - if($element->getTagName()==='parameter') - { - $properties=$element->getAttributes(); - if(($id=$properties->remove('id'))===null) - throw new TConfigurationException('appconfig_parameterid_required'); - if(($type=$properties->remove('class'))===null) - { - if(($value=$properties->remove('value'))===null) - $this->_parameters[$id]=$element; - else - $this->_parameters[$id]=$value; - } - else - $this->_parameters[$id]=array($type,$properties->toArray()); - $this->_empty=false; - } - else - throw new TConfigurationException('appconfig_parameters_invalid',$element->getTagName()); - } - } - - /** - * Loads the external PHP array. - * @param array the application PHP array - * @param string the context path (for specifying relative paths) - */ - protected function loadExternalPhp($includeNode,$configPath) - { - foreach($includeNode as $include) - { - $when = isset($include['when'])?true:false; - if(!isset($include['file'])) - throw new TConfigurationException('appconfig_includefile_required'); - $filePath = $include['file']; - if(isset($this->_includes[$filePath])) - $this->_includes[$filePath]='('.$this->_includes[$filePath].') || ('.$when.')'; - else - $$this->_includes[$filePath]=$when; - $this->_empty=false; - } - } - - /** - * Loads the external XML configurations. - * @param TXmlElement the application DOM element - * @param string the context path (for specifying relative paths) - */ - protected function loadExternalXml($includeNode,$configPath) - { - if(($when=$includeNode->getAttribute('when'))===null) - $when=true; - if(($filePath=$includeNode->getAttribute('file'))===null) - throw new TConfigurationException('appconfig_includefile_required'); - if(isset($this->_includes[$filePath])) - $this->_includes[$filePath]='('.$this->_includes[$filePath].') || ('.$when.')'; - else - $this->_includes[$filePath]=$when; - $this->_empty=false; - } - - /** - * Returns list of page initial property values. - * Each array element represents a single property with the key - * being the property name and the value the initial property value. - * @return array list of page initial property values - */ - public function getProperties() - { - return $this->_properties; - } - - /** - * Returns list of path alias definitions. - * The definitions are aggregated (top-down) from configuration files along the path - * to the specified page. Each array element represents a single alias definition, - * with the key being the alias name and the value the absolute path. - * @return array list of path alias definitions - */ - public function getAliases() - { - return $this->_aliases; - } - - /** - * Returns list of namespaces to be used. - * The namespaces are aggregated (top-down) from configuration files along the path - * to the specified page. Each array element represents a single namespace usage, - * with the value being the namespace to be used. - * @return array list of namespaces to be used - */ - public function getUsings() - { - return $this->_usings; - } - - /** - * Returns list of module configurations. - * The module configurations are aggregated (top-down) from configuration files - * along the path to the specified page. Each array element represents - * a single module configuration, with the key being the module ID and - * the value the module configuration. Each module configuration is - * stored in terms of an array with the following content - * ([0]=>module type, [1]=>module properties, [2]=>complete module configuration) - * The module properties are an array of property values indexed by property names. - * The complete module configuration is a TXmlElement object representing - * the raw module configuration which may contain contents enclosed within - * module tags. - * @return array list of module configurations to be used - */ - public function getModules() - { - return $this->_modules; - } - - /** - * @return array list of service configurations - */ - public function getServices() - { - return $this->_services; - } - - /** - * Returns list of parameter definitions. - * The parameter definitions are aggregated (top-down) from configuration files - * along the path to the specified page. Each array element represents - * a single parameter definition, with the key being the parameter ID and - * the value the parameter definition. A parameter definition can be either - * a string representing a string-typed parameter, or an array. - * The latter defines a component-typed parameter whose format is as follows, - * ([0]=>component type, [1]=>component properties) - * The component properties are an array of property values indexed by property names. - * @return array list of parameter definitions to be used - */ - public function getParameters() - { - return $this->_parameters; - } - - /** - * @return array list of external configuration files. Each element is like $filePath=>$condition - */ - public function getExternalConfigurations() - { - return $this->_includes; - } -} - -/** - * TApplicationStatePersister class. - * TApplicationStatePersister provides a file-based persistent storage - * for application state. Application state, when serialized, is stored - * in a file named 'global.cache' under the 'runtime' directory of the application. - * Cache will be exploited if it is enabled. - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System - * @since 3.0 - */ -class TApplicationStatePersister extends TModule implements IStatePersister -{ - /** - * Name of the value stored in cache - */ - const CACHE_NAME='prado:appstate'; - - /** - * Initializes module. - * @param TXmlElement module configuration (may be null) - */ - public function init($config) - { - $this->getApplication()->setApplicationStatePersister($this); - } - - /** - * @return string the file path storing the application state - */ - protected function getStateFilePath() - { - return $this->getApplication()->getRuntimePath().'/global.cache'; - } - - /** - * Loads application state from persistent storage. - * @return mixed application state - */ - 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; - } - } - - /** - * Saves application state in persistent storage. - * @param mixed application state - */ - 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(); - file_put_contents($fileName,$content,LOCK_EX); - } - } - -} diff --git a/framework/TApplicationConfiguration.php b/framework/TApplicationConfiguration.php new file mode 100644 index 00000000..06e894dc --- /dev/null +++ b/framework/TApplicationConfiguration.php @@ -0,0 +1,518 @@ +<?php +/** + * TApplication class file + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + + +/** + * TApplicationConfiguration class. + * + * This class is used internally by TApplication to parse and represent application configuration. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @author Carl G. Mathisen <carlgmathisen@gmail.com> + * @package System + * @since 3.0 + */ +class TApplicationConfiguration extends TComponent +{ + /** + * @var array list of application initial property values, indexed by property names + */ + private $_properties=array(); + /** + * @var array list of namespaces to be used + */ + private $_usings=array(); + /** + * @var array list of path aliases, indexed by alias names + */ + private $_aliases=array(); + /** + * @var array list of module configurations + */ + private $_modules=array(); + /** + * @var array list of service configurations + */ + private $_services=array(); + /** + * @var array list of parameters + */ + private $_parameters=array(); + /** + * @var array list of included configurations + */ + private $_includes=array(); + /** + * @var boolean whether this configuration contains actual stuff + */ + private $_empty=true; + + /** + * Parses the application configuration file. + * @param string configuration file name + * @throws TConfigurationException if there is any parsing error + */ + public function loadFromFile($fname) + { + if(Prado::getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP) + { + $fcontent = include $fname; + $this->loadFromPhp($fcontent,dirname($fname)); + } + else + { + $dom=new TXmlDocument; + $dom->loadFromFile($fname); + $this->loadFromXml($dom,dirname($fname)); + } + } + + /** + * @return boolean whether this configuration contains actual stuff + */ + public function getIsEmpty() + { + return $this->_empty; + } + + /** + * Parses the application configuration given in terms of a PHP array. + * @param array the PHP array + * @param string the context path (for specifying relative paths) + */ + public function loadFromPhp($config, $configPath) + { + // application properties + if(isset($config['application'])) + { + foreach($config['application'] as $name=>$value) + { + $this->_properties[$name]=$value; + } + $this->_empty = false; + } + + if(isset($config['paths']) && is_array($config['paths'])) + $this->loadPathsPhp($config['paths'],$configPath); + + if(isset($config['modules']) && is_array($config['modules'])) + $this->loadModulesPhp($config['modules'],$configPath); + + if(isset($config['services']) && is_array($config['services'])) + $this->loadServicesPhp($config['services'],$configPath); + + if(isset($config['parameters']) && is_array($config['parameters'])) + $this->loadParametersPhp($config['parameters'], $configPath); + + if(isset($config['includes']) && is_array($config['includes'])) + $this->loadExternalXml($config['includes'],$configPath); + } + + /** + * Parses the application configuration given in terms of a TXmlElement. + * @param TXmlElement the XML element + * @param string the context path (for specifying relative paths) + */ + public function loadFromXml($dom,$configPath) + { + // application properties + foreach($dom->getAttributes() as $name=>$value) + { + $this->_properties[$name]=$value; + $this->_empty=false; + } + + foreach($dom->getElements() as $element) + { + switch($element->getTagName()) + { + case 'paths': + $this->loadPathsXml($element,$configPath); + break; + case 'modules': + $this->loadModulesXml($element,$configPath); + break; + case 'services': + $this->loadServicesXml($element,$configPath); + break; + case 'parameters': + $this->loadParametersXml($element,$configPath); + break; + case 'include': + $this->loadExternalXml($element,$configPath); + break; + default: + //throw new TConfigurationException('appconfig_tag_invalid',$element->getTagName()); + break; + } + } + } + + /** + * Loads the paths PHP array + * @param array the paths PHP array + * @param string the context path (for specifying relative paths) + */ + protected function loadPathsPhp($pathsNode, $configPath) + { + if(isset($pathsNode['aliases']) && is_array($pathsNode['aliases'])) + { + foreach($pathsNode['aliases'] as $id=>$path) + { + $path=str_replace('\\','/',$path); + if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) // if absolute path + $p=realpath($path); + else + $p=realpath($configPath.DIRECTORY_SEPARATOR.$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; + } + } + + if(isset($pathsNode['using']) && is_array($pathsNode['using'])) + { + foreach($pathsNode['using'] as $namespace) + { + $this->_usings[] = $namespace; + } + } + } + + /** + * Loads the paths XML node. + * @param TXmlElement the paths XML node + * @param string the context path (for specifying relative paths) + */ + protected function loadPathsXml($pathsNode,$configPath) + { + foreach($pathsNode->getElements() as $element) + { + switch($element->getTagName()) + { + case 'alias': + { + if(($id=$element->getAttribute('id'))!==null && ($path=$element->getAttribute('path'))!==null) + { + $path=str_replace('\\','/',$path); + if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) // if absolute path + $p=realpath($path); + else + $p=realpath($configPath.DIRECTORY_SEPARATOR.$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'); + $this->_empty=false; + break; + } + case 'using': + { + if(($namespace=$element->getAttribute('namespace'))!==null) + $this->_usings[]=$namespace; + else + throw new TConfigurationException('appconfig_using_invalid'); + $this->_empty=false; + break; + } + default: + throw new TConfigurationException('appconfig_paths_invalid',$element->getTagName()); + } + } + } + + /** + * Loads the modules PHP array. + * @param array the modules PHP array + * @param string the context path (for specifying relative paths) + */ + protected function loadModulesPhp($modulesNode, $configPath) + { + foreach($modulesNode as $id=>$module) + { + if(!isset($module['class'])) + throw new TConfigurationException('appconfig_moduletype_required',$id); + $type = $module['class']; + unset($module['class']); + $properties = array(); + if(isset($module['properties'])) + { + $properties = $module['properties']; + unset($module['properties']); + } + $properties['id'] = $id; + $this->_modules[$id]=array($type,$properties,$module); + $this->_empty=false; + } + } + + /** + * Loads the modules XML node. + * @param TXmlElement the modules XML node + * @param string the context path (for specifying relative paths) + */ + protected function loadModulesXml($modulesNode,$configPath) + { + foreach($modulesNode->getElements() as $element) + { + if($element->getTagName()==='module') + { + $properties=$element->getAttributes(); + $id=$properties->itemAt('id'); + $type=$properties->remove('class'); + if($type===null) + throw new TConfigurationException('appconfig_moduletype_required',$id); + $element->setParent(null); + if($id===null) + $this->_modules[]=array($type,$properties->toArray(),$element); + else + $this->_modules[$id]=array($type,$properties->toArray(),$element); + $this->_empty=false; + } + else + throw new TConfigurationException('appconfig_modules_invalid',$element->getTagName()); + } + } + + /** + * Loads the services PHP array. + * @param array the services PHP array + * @param string the context path (for specifying relative paths) + */ + protected function loadServicesPhp($servicesNode,$configPath) + { + foreach($servicesNode as $id => $service) + { + if(!isset($service['class'])) + throw new TConfigurationException('appconfig_servicetype_required'); + $type = $service['class']; + $properties = isset($service['properties']) ? $service['properties'] : array(); + unset($service['properties']); + $properties['id'] = $id; + $this->_services[$id] = array($type,$properties,$service); + $this->_empty = false; + } + } + + /** + * Loads the services XML node. + * @param TXmlElement the services XML node + * @param string the context path (for specifying relative paths) + */ + protected function loadServicesXml($servicesNode,$configPath) + { + foreach($servicesNode->getElements() as $element) + { + if($element->getTagName()==='service') + { + $properties=$element->getAttributes(); + if(($id=$properties->itemAt('id'))===null) + throw new TConfigurationException('appconfig_serviceid_required'); + if(($type=$properties->remove('class'))===null) + throw new TConfigurationException('appconfig_servicetype_required',$id); + $element->setParent(null); + $this->_services[$id]=array($type,$properties->toArray(),$element); + $this->_empty=false; + } + else + throw new TConfigurationException('appconfig_services_invalid',$element->getTagName()); + } + } + + /** + * Loads the parameters PHP array. + * @param array the parameters PHP array + * @param string the context path (for specifying relative paths) + */ + protected function loadParametersPhp($parametersNode,$configPath) + { + foreach($parametersNode as $id => $parameter) + { + if(is_array($parameter)) + { + if(isset($parameter['class'])) + { + $type = $parameter['class']; + unset($parameter['class']); + $properties = isset($service['properties']) ? $service['properties'] : array(); + $properties['id'] = $id; + $this->_parameters[$id] = array($type,$properties); + } + } + else + { + $this->_parameters[$id] = $parameter; + } + } + } + + /** + * Loads the parameters XML node. + * @param TXmlElement the parameters XML node + * @param string the context path (for specifying relative paths) + */ + protected function loadParametersXml($parametersNode,$configPath) + { + foreach($parametersNode->getElements() as $element) + { + if($element->getTagName()==='parameter') + { + $properties=$element->getAttributes(); + if(($id=$properties->remove('id'))===null) + throw new TConfigurationException('appconfig_parameterid_required'); + if(($type=$properties->remove('class'))===null) + { + if(($value=$properties->remove('value'))===null) + $this->_parameters[$id]=$element; + else + $this->_parameters[$id]=$value; + } + else + $this->_parameters[$id]=array($type,$properties->toArray()); + $this->_empty=false; + } + else + throw new TConfigurationException('appconfig_parameters_invalid',$element->getTagName()); + } + } + + /** + * Loads the external PHP array. + * @param array the application PHP array + * @param string the context path (for specifying relative paths) + */ + protected function loadExternalPhp($includeNode,$configPath) + { + foreach($includeNode as $include) + { + $when = isset($include['when'])?true:false; + if(!isset($include['file'])) + throw new TConfigurationException('appconfig_includefile_required'); + $filePath = $include['file']; + if(isset($this->_includes[$filePath])) + $this->_includes[$filePath]='('.$this->_includes[$filePath].') || ('.$when.')'; + else + $$this->_includes[$filePath]=$when; + $this->_empty=false; + } + } + + /** + * Loads the external XML configurations. + * @param TXmlElement the application DOM element + * @param string the context path (for specifying relative paths) + */ + protected function loadExternalXml($includeNode,$configPath) + { + if(($when=$includeNode->getAttribute('when'))===null) + $when=true; + if(($filePath=$includeNode->getAttribute('file'))===null) + throw new TConfigurationException('appconfig_includefile_required'); + if(isset($this->_includes[$filePath])) + $this->_includes[$filePath]='('.$this->_includes[$filePath].') || ('.$when.')'; + else + $this->_includes[$filePath]=$when; + $this->_empty=false; + } + + /** + * Returns list of page initial property values. + * Each array element represents a single property with the key + * being the property name and the value the initial property value. + * @return array list of page initial property values + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Returns list of path alias definitions. + * The definitions are aggregated (top-down) from configuration files along the path + * to the specified page. Each array element represents a single alias definition, + * with the key being the alias name and the value the absolute path. + * @return array list of path alias definitions + */ + public function getAliases() + { + return $this->_aliases; + } + + /** + * Returns list of namespaces to be used. + * The namespaces are aggregated (top-down) from configuration files along the path + * to the specified page. Each array element represents a single namespace usage, + * with the value being the namespace to be used. + * @return array list of namespaces to be used + */ + public function getUsings() + { + return $this->_usings; + } + + /** + * Returns list of module configurations. + * The module configurations are aggregated (top-down) from configuration files + * along the path to the specified page. Each array element represents + * a single module configuration, with the key being the module ID and + * the value the module configuration. Each module configuration is + * stored in terms of an array with the following content + * ([0]=>module type, [1]=>module properties, [2]=>complete module configuration) + * The module properties are an array of property values indexed by property names. + * The complete module configuration is a TXmlElement object representing + * the raw module configuration which may contain contents enclosed within + * module tags. + * @return array list of module configurations to be used + */ + public function getModules() + { + return $this->_modules; + } + + /** + * @return array list of service configurations + */ + public function getServices() + { + return $this->_services; + } + + /** + * Returns list of parameter definitions. + * The parameter definitions are aggregated (top-down) from configuration files + * along the path to the specified page. Each array element represents + * a single parameter definition, with the key being the parameter ID and + * the value the parameter definition. A parameter definition can be either + * a string representing a string-typed parameter, or an array. + * The latter defines a component-typed parameter whose format is as follows, + * ([0]=>component type, [1]=>component properties) + * The component properties are an array of property values indexed by property names. + * @return array list of parameter definitions to be used + */ + public function getParameters() + { + return $this->_parameters; + } + + /** + * @return array list of external configuration files. Each element is like $filePath=>$condition + */ + public function getExternalConfigurations() + { + return $this->_includes; + } +}
\ No newline at end of file diff --git a/framework/TApplicationMode.php b/framework/TApplicationMode.php new file mode 100644 index 00000000..9ce1433c --- /dev/null +++ b/framework/TApplicationMode.php @@ -0,0 +1,31 @@ +<?php +/** + * TApplication class file + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * TApplicationMode class. + * TApplicationMode defines the possible mode that an application can be set at by + * setting {@link TApplication::setMode Mode}. + * In particular, the following modes are defined + * - Off: the application is not running. Any request to the application will obtain an error. + * - Debug: the application is running in debug mode. + * - Normal: the application is running in normal production mode. + * - Performance: the application is running in performance mode. + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0.4 + */ +class TApplicationMode extends TEnumerable +{ + const Off='Off'; + const Debug='Debug'; + const Normal='Normal'; + const Performance='Performance'; +} diff --git a/framework/TApplicationStatePersister.php b/framework/TApplicationStatePersister.php new file mode 100644 index 00000000..b498ac72 --- /dev/null +++ b/framework/TApplicationStatePersister.php @@ -0,0 +1,86 @@ +<?php +/** + * TApplication class file + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * TApplicationStatePersister class. + * TApplicationStatePersister provides a file-based persistent storage + * for application state. Application state, when serialized, is stored + * in a file named 'global.cache' under the 'runtime' directory of the application. + * Cache will be exploited if it is enabled. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +class TApplicationStatePersister extends TModule implements IStatePersister +{ + /** + * Name of the value stored in cache + */ + const CACHE_NAME='prado:appstate'; + + /** + * Initializes module. + * @param TXmlElement module configuration (may be null) + */ + public function init($config) + { + $this->getApplication()->setApplicationStatePersister($this); + } + + /** + * @return string the file path storing the application state + */ + protected function getStateFilePath() + { + return $this->getApplication()->getRuntimePath().'/global.cache'; + } + + /** + * Loads application state from persistent storage. + * @return mixed application state + */ + 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; + } + } + + /** + * Saves application state in persistent storage. + * @param mixed application state + */ + 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(); + file_put_contents($fileName,$content,LOCK_EX); + } + } + +}
\ No newline at end of file diff --git a/framework/TClassBehaviorEventParameter.php b/framework/TClassBehaviorEventParameter.php new file mode 100644 index 00000000..ffa9ba88 --- /dev/null +++ b/framework/TClassBehaviorEventParameter.php @@ -0,0 +1,83 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + + + +/** + * TClassBehaviorEventParameter class. + * TClassBehaviorEventParameter is the parameter sent with the class behavior changes. + * + * @author Brad Anderson <javalizard@mac.com> + * @version $Id$ + * @package System + * @since 3.2.3 + */ +class TClassBehaviorEventParameter extends TEventParameter +{ + private $_class; + private $_name; + private $_behavior; + private $_priority; + + /** + * Holds the parameters for the Class Behavior Events + * @param string $class this is the class to get the behavior + * @param string $name the name of the behavior + * @param object $behavior this is the behavior to implement the class behavior + */ + public function __construct($class,$name,$behavior,$priority) + { + $this->_class=$class; + $this->_name=$name; + $this->_behavior=$behavior; + $this->_priority=$priority; + } + + /** + * This is the class to get the behavior + * @return string the class to get the behavior + */ + public function getClass() + { + return $this->_class; + } + + /** + * name of the behavior + * @return string the name to get the behavior + */ + public function getName() + { + return $this->_name; + } + + /** + * This is the behavior which the class is to get + * @return object the behavior to implement + */ + public function getBehavior() + { + return $this->_behavior; + } + + /** + * This is the priority which the behavior is to get + * @return numeric the priority of the behavior + */ + public function getPriority() + { + return $this->_priority; + } +}
\ No newline at end of file diff --git a/framework/TComponent.php b/framework/TComponent.php index 484a3186..57ab7003 100644 --- a/framework/TComponent.php +++ b/framework/TComponent.php @@ -1727,679 +1727,4 @@ class TComponent $exprops[] = "\0TComponent\0_m"; return array_diff($a,$exprops); } -} - - -/** - * IDynamicMethods interface. - * IDynamicMethods marks an object to receive undefined global or dynamic events. - * - * @author Brad Anderson <javalizard@mac.com> - * @version $Id$ - * @package System - * @since 3.2.3 - */ -interface IDynamicMethods -{ - public function __dycall($method,$args); -} - - - -/** - * TClassBehaviorEventParameter class. - * TClassBehaviorEventParameter is the parameter sent with the class behavior changes. - * - * @author Brad Anderson <javalizard@mac.com> - * @version $Id$ - * @package System - * @since 3.2.3 - */ -class TClassBehaviorEventParameter extends TEventParameter -{ - private $_class; - private $_name; - private $_behavior; - private $_priority; - - /** - * Holds the parameters for the Class Behavior Events - * @param string $class this is the class to get the behavior - * @param string $name the name of the behavior - * @param object $behavior this is the behavior to implement the class behavior - */ - public function __construct($class,$name,$behavior,$priority) - { - $this->_class=$class; - $this->_name=$name; - $this->_behavior=$behavior; - $this->_priority=$priority; - } - - /** - * This is the class to get the behavior - * @return string the class to get the behavior - */ - public function getClass() - { - return $this->_class; - } - - /** - * name of the behavior - * @return string the name to get the behavior - */ - public function getName() - { - return $this->_name; - } - - /** - * This is the behavior which the class is to get - * @return object the behavior to implement - */ - public function getBehavior() - { - return $this->_behavior; - } - - /** - * This is the priority which the behavior is to get - * @return numeric the priority of the behavior - */ - public function getPriority() - { - return $this->_priority; - } -} - - -/** - * TEnumerable class. - * TEnumerable is the base class for all enumerable types. - * To define an enumerable type, extend TEnumberable and define string constants. - * Each constant represents an enumerable value. - * The constant name must be the same as the constant value. - * For example, - * <code> - * class TTextAlign extends TEnumerable - * { - * const Left='Left'; - * const Right='Right'; - * } - * </code> - * Then, one can use the enumerable values such as TTextAlign::Left and - * TTextAlign::Right. - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System - * @since 3.0 - */ -class TEnumerable implements Iterator -{ - private $_enums=array(); - - public function __construct() { - $reflection=new ReflectionClass($this); - $this->_enums=$reflection->getConstants(); - } - - public function current() { - return current($this->_enums); - } - - public function key() { - return key($this->_enums); - } - - public function next() { - return next($this->_enums); - } - - public function rewind() { - reset($this->_enums); - } - - public function valid() { - return $this->current()!==false; - } -} - -/** - * TPropertyValue class - * - * TPropertyValue is a utility class that provides static methods - * to convert component property values to specific types. - * - * TPropertyValue is commonly used in component setter methods to ensure - * the new property value is of specific type. - * For example, a boolean-typed property setter method would be as follows, - * <code> - * function setPropertyName($value) { - * $value=TPropertyValue::ensureBoolean($value); - * // $value is now of boolean type - * } - * </code> - * - * Properties can be of the following types with specific type conversion rules: - * - string: a boolean value will be converted to 'true' or 'false'. - * - boolean: string 'true' (case-insensitive) will be converted to true, - * string 'false' (case-insensitive) will be converted to false. - * - integer - * - float - * - array: string starting with '(' and ending with ')' will be considered as - * as an array expression and will be evaluated. Otherwise, an array - * with the value to be ensured is returned. - * - object - * - enum: enumerable type, represented by an array of strings. - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System - * @since 3.0 - */ -class TPropertyValue -{ - /** - * Converts a value to boolean type. - * Note, string 'true' (case-insensitive) will be converted to true, - * string 'false' (case-insensitive) will be converted to false. - * If a string represents a non-zero number, it will be treated as true. - * @param mixed the value to be converted. - * @return boolean - */ - public static function ensureBoolean($value) - { - if (is_string($value)) - return strcasecmp($value,'true')==0 || $value!=0; - else - return (boolean)$value; - } - - /** - * Converts a value to string type. - * Note, a boolean value will be converted to 'true' if it is true - * and 'false' if it is false. - * @param mixed the value to be converted. - * @return string - */ - public static function ensureString($value) - { - if (TJavaScript::isJsLiteral($value)) - return $value; - if (is_bool($value)) - return $value?'true':'false'; - else - return (string)$value; - } - - /** - * Converts a value to integer type. - * @param mixed the value to be converted. - * @return integer - */ - public static function ensureInteger($value) - { - return (integer)$value; - } - - /** - * Converts a value to float type. - * @param mixed the value to be converted. - * @return float - */ - public static function ensureFloat($value) - { - return (float)$value; - } - - /** - * Converts a value to array type. If the value is a string and it is - * in the form (a,b,c) then an array consisting of each of the elements - * will be returned. If the value is a string and it is not in this form - * then an array consisting of just the string will be returned. If the value - * is not a string then - * @param mixed the value to be converted. - * @return array - */ - public static function ensureArray($value) - { - if(is_string($value)) - { - $value = trim($value); - $len = strlen($value); - if ($len >= 2 && $value[0] == '(' && $value[$len-1] == ')') - { - eval('$array=array'.$value.';'); - return $array; - } - else - return $len>0?array($value):array(); - } - else - return (array)$value; - } - - /** - * Converts a value to object type. - * @param mixed the value to be converted. - * @return object - */ - public static function ensureObject($value) - { - return (object)$value; - } - - /** - * Converts a value to enum type. - * - * This method checks if the value is of the specified enumerable type. - * A value is a valid enumerable value if it is equal to the name of a constant - * in the specified enumerable type (class). - * For more details about enumerable, see {@link TEnumerable}. - * - * For backward compatibility, this method also supports sanity - * check of a string value to see if it is among the given list of strings. - * @param mixed the value to be converted. - * @param mixed class name of the enumerable type, or array of valid enumeration values. If this is not an array, - * the method considers its parameters are of variable length, and the second till the last parameters are enumeration values. - * @return string the valid enumeration value - * @throws TInvalidDataValueException if the original value is not in the string array. - */ - public static function ensureEnum($value,$enums) - { - static $types=array(); - if(func_num_args()===2 && is_string($enums)) - { - if(!isset($types[$enums])) - $types[$enums]=new ReflectionClass($enums); - if($types[$enums]->hasConstant($value)) - return $value; - else - throw new TInvalidDataValueException( - 'propertyvalue_enumvalue_invalid',$value, - implode(' | ',$types[$enums]->getConstants())); - } - else 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)); - } - - /** - * Converts the value to 'null' if the given value is empty - * @param mixed value to be converted - * @return mixed input or NULL if input is empty - */ - public static function ensureNullIfEmpty($value) - { - return empty($value)?null:$value; - } -} - -/** - * TEventParameter class. - * TEventParameter is the base class for all event parameter classes. - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System - * @since 3.0 - */ -class TEventParameter extends TComponent -{ -} - -class TEventResults extends TEnumerable { - const EVENT_RESULT_FEED_FORWARD=1; - const EVENT_RESULT_FILTER=2; - const EVENT_RESULT_ALL=4; -} - -/** - * TComponentReflection class. - * - * TComponentReflection provides functionalities to inspect the public/protected - * properties, events and methods defined in a class. - * - * The following code displays the properties and events defined in {@link TDataGrid}, - * <code> - * $reflection=new TComponentReflection('TDataGrid'); - * Prado::varDump($reflection->getProperties()); - * Prado::varDump($reflection->getEvents()); - * </code> - * - * @author Qiang Xue <qiang.xue@gmail.com> - * @package System - * @since 3.0 - */ -class TComponentReflection extends TComponent -{ - private $_className; - private $_properties=array(); - private $_events=array(); - private $_methods=array(); - - /** - * Constructor. - * @param object|string the component instance or the class name - * @throws TInvalidDataTypeException if the object is not a component - */ - public function __construct($component) - { - if(is_string($component) && class_exists($component,false)) - $this->_className=$component; - else if(is_object($component)) - $this->_className=get_class($component); - else - throw new TInvalidDataTypeException('componentreflection_class_invalid'); - $this->reflect(); - } - - private function isPropertyMethod($method) - { - $methodName=$method->getName(); - return $method->getNumberOfRequiredParameters()===0 - && strncasecmp($methodName,'get',3)===0 - && isset($methodName[3]); - } - - private function isEventMethod($method) - { - $methodName=$method->getName(); - return strncasecmp($methodName,'on',2)===0 - && isset($methodName[2]); - } - - private function reflect() - { - $class=new ReflectionClass($this->_className); - $properties=array(); - $events=array(); - $methods=array(); - $isComponent=is_subclass_of($this->_className,'TComponent') || strcasecmp($this->_className,'TComponent')===0; - foreach($class->getMethods() as $method) - { - if($method->isPublic() || $method->isProtected()) - { - $methodName=$method->getName(); - if(!$method->isStatic() && $isComponent) - { - if($this->isPropertyMethod($method)) - $properties[substr($methodName,3)]=$method; - else if($this->isEventMethod($method)) - { - $methodName[0]='O'; - $events[$methodName]=$method; - } - } - if(strncmp($methodName,'__',2)!==0) - $methods[$methodName]=$method; - } - } - $reserved=array(); - ksort($properties); - foreach($properties as $name=>$method) - { - $this->_properties[$name]=array( - 'type'=>$this->determinePropertyType($method), - 'readonly'=>!$class->hasMethod('set'.$name), - 'protected'=>$method->isProtected(), - 'class'=>$method->getDeclaringClass()->getName(), - 'comments'=>$method->getDocComment() - ); - $reserved['get'.strtolower($name)]=1; - $reserved['set'.strtolower($name)]=1; - } - ksort($events); - foreach($events as $name=>$method) - { - $this->_events[$name]=array( - 'class'=>$method->getDeclaringClass()->getName(), - 'protected'=>$method->isProtected(), - 'comments'=>$method->getDocComment() - ); - $reserved[strtolower($name)]=1; - } - ksort($methods); - foreach($methods as $name=>$method) - { - if(!isset($reserved[strtolower($name)])) - $this->_methods[$name]=array( - 'class'=>$method->getDeclaringClass()->getName(), - 'protected'=>$method->isProtected(), - 'static'=>$method->isStatic(), - 'comments'=>$method->getDocComment() - ); - } - } - - /** - * Determines the property type. - * This method uses the doc comment to determine the property type. - * @param ReflectionMethod - * @return string the property type, '{unknown}' if type cannot be determined from comment - */ - protected function determinePropertyType($method) - { - $comment=$method->getDocComment(); - if(preg_match('/@return\\s+(.*?)\\s+/',$comment,$matches)) - return $matches[1]; - else - return '{unknown}'; - } - - /** - * @return string class name of the component - */ - public function getClassName() - { - return $this->_className; - } - - /** - * @return array list of component properties. Array keys are property names. - * Each array element is of the following structure: - * [type]=>property type, - * [readonly]=>whether the property is read-only, - * [protected]=>whether the method is protected or not - * [class]=>the class where the property is inherited from, - * [comments]=>comments associated with the property. - */ - public function getProperties() - { - return $this->_properties; - } - - /** - * @return array list of component events. Array keys are event names. - * Each array element is of the following structure: - * [protected]=>whether the event is protected or not - * [class]=>the class where the event is inherited from. - * [comments]=>comments associated with the event. - */ - public function getEvents() - { - return $this->_events; - } - - /** - * @return array list of public/protected methods. Array keys are method names. - * Each array element is of the following structure: - * [protected]=>whether the method is protected or not - * [static]=>whether the method is static or not - * [class]=>the class where the property is inherited from, - * [comments]=>comments associated with the event. - */ - public function getMethods() - { - return $this->_methods; - } -} - -/** - * IBaseBehavior interface is the base behavior class from which all other - * behaviors types are derived - * - * @author Brad Anderson <javalizard@mac.com> - * @version $Id$ - * @package System - * @since 3.2.3 - */ -interface IBaseBehavior { - /** - * Attaches the behavior object to the component. - * @param CComponent the component that this behavior is to be attached to. - */ - public function attach($component); - /** - * Detaches the behavior object from the component. - * @param CComponent the component that this behavior is to be detached from. - */ - public function detach($component); -} - -/** - * IBehavior interfaces is implemented by instance behavior classes. - * - * A behavior is a way to enhance a component with additional methods and - * events that are defined in the behavior class and not available in the - * class. Objects may signal behaviors through dynamic events. - * - * @author Brad Anderson <javalizard@mac.com> - * @version $Id$ - * @package System - * @since 3.2.3 - */ -interface IBehavior extends IBaseBehavior -{ - /** - * @return boolean whether this behavior is enabled - */ - public function getEnabled(); - /** - * @param boolean whether this behavior is enabled - */ - public function setEnabled($value); -} - - -/** - * IClassBehavior interface is implements behaviors across all instances of - * a particular class - * - * Any calls to functions not present in the original object but to behaviors - * derived from this class, will have inserted as the first argument parameter - * the object containing the behavior. - * - * For example: - * <code> - * $objWithClassBehavior->MethodOfClassBehavior(1, 20); - * </code> - * will be acted within the class behavior like this: - * <code> - * public function MethodOfClassBehavior($object, $firstParam, $secondParam){ - * // $object === $objWithClassBehavior, $firstParam === 1, $secondParam === 20 - * } - * </code> - * - * This also holds for 'dy' events as well. For dynamic events, method arguments would be: - * <code> - * public function dyMethodOfClassBehavior($object, $firstParam, $secondParam, $callchain){ - * // $object === $objWithClassBehavior, $firstParam === 1, $secondParam === 20, $callchain instanceof {@link TCallChain} - * } - * </code> - * - * @author Brad Anderson <javalizard@mac.com> - * @version $Id$ - * @package System - * @since 3.2.3 - */ -interface IClassBehavior extends IBaseBehavior { -} - - -/** - * IInstanceCheck This interface allows objects to determine their own - * 'instanceof' results when {@link TComponent::isa} is called. This is - * important with behaviors because behaviors may want to look like - * particular objects other than themselves. - * - * @author Brad Anderson <javalizard@mac.com> - * @version $Id$ - * @package System - * @since 3.2.3 - */ -interface IInstanceCheck { - /** - * The method checks $this or, if needed, the parameter $instance is of type - * class. In the case of a Class Behavior, the instance to which the behavior - * is attached may be important to determine if $this is an instance - * of a particular class. - * @param class|string the component that this behavior is checking if it is an instanceof. - * @param object the object which the behavior is attached to. default: null - * @return boolean|null if the this or the instance is of type class. When null, no information could be derived and - * the default mechanisms take over. - */ - public function isinstanceof($class,$instance=null); -} - -/** - * TJavaScriptLiteral class that encloses string literals that are not - * supposed to be escaped by {@link TJavaScript::encode() } - * - * Since Prado 3.2 all the data that gets sent clientside inside a javascript statement - * is encoded by default to avoid any kind of injection. - * Sometimes there's the need to bypass this encoding and send raw javascript code. - * To ensure that a string doesn't get encoded by {@link TJavaScript::encode() }, - * construct a new TJavaScriptLiteral: - * <code> - * // a javascript test string - * $js="alert('hello')"; - * // the string in $raw will not be encoded when sent clientside inside a javascript block - * $raw=new TJavaScriptLiteral($js); - * // shortened form - * $raw=_js($js); - * </code> - * - * @package System - * @since 3.2.0 - */ -class TJavaScriptLiteral -{ - protected $_s; - - public function __construct($s) - { - $this->_s = $s; - } - - public function __toString() - { - return (string)$this->_s; - } - - public function toJavaScriptLiteral() - { - return $this->__toString(); - } -} - -/** - * TJavaScriptString class is an internal class that marks strings that will be - * forcibly encoded when rendered inside a javascript block - * - * @package System - * @since 3.2.0 - */ -class TJavaScriptString extends TJavaScriptLiteral -{ - public function toJavaScriptLiteral() - { - return TJavaScript::jsonEncode((string)$this->_s,JSON_HEX_QUOT | JSON_HEX_APOS | JSON_HEX_TAG); - } -} - +}
\ No newline at end of file diff --git a/framework/TComponentReflection.php b/framework/TComponentReflection.php new file mode 100644 index 00000000..aef99e8c --- /dev/null +++ b/framework/TComponentReflection.php @@ -0,0 +1,195 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * TComponentReflection class. + * + * TComponentReflection provides functionalities to inspect the public/protected + * properties, events and methods defined in a class. + * + * The following code displays the properties and events defined in {@link TDataGrid}, + * <code> + * $reflection=new TComponentReflection('TDataGrid'); + * Prado::varDump($reflection->getProperties()); + * Prado::varDump($reflection->getEvents()); + * </code> + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +class TComponentReflection extends TComponent +{ + private $_className; + private $_properties=array(); + private $_events=array(); + private $_methods=array(); + + /** + * Constructor. + * @param object|string the component instance or the class name + * @throws TInvalidDataTypeException if the object is not a component + */ + public function __construct($component) + { + if(is_string($component) && class_exists($component,false)) + $this->_className=$component; + else if(is_object($component)) + $this->_className=get_class($component); + else + throw new TInvalidDataTypeException('componentreflection_class_invalid'); + $this->reflect(); + } + + private function isPropertyMethod($method) + { + $methodName=$method->getName(); + return $method->getNumberOfRequiredParameters()===0 + && strncasecmp($methodName,'get',3)===0 + && isset($methodName[3]); + } + + private function isEventMethod($method) + { + $methodName=$method->getName(); + return strncasecmp($methodName,'on',2)===0 + && isset($methodName[2]); + } + + private function reflect() + { + $class=new ReflectionClass($this->_className); + $properties=array(); + $events=array(); + $methods=array(); + $isComponent=is_subclass_of($this->_className,'TComponent') || strcasecmp($this->_className,'TComponent')===0; + foreach($class->getMethods() as $method) + { + if($method->isPublic() || $method->isProtected()) + { + $methodName=$method->getName(); + if(!$method->isStatic() && $isComponent) + { + if($this->isPropertyMethod($method)) + $properties[substr($methodName,3)]=$method; + else if($this->isEventMethod($method)) + { + $methodName[0]='O'; + $events[$methodName]=$method; + } + } + if(strncmp($methodName,'__',2)!==0) + $methods[$methodName]=$method; + } + } + $reserved=array(); + ksort($properties); + foreach($properties as $name=>$method) + { + $this->_properties[$name]=array( + 'type'=>$this->determinePropertyType($method), + 'readonly'=>!$class->hasMethod('set'.$name), + 'protected'=>$method->isProtected(), + 'class'=>$method->getDeclaringClass()->getName(), + 'comments'=>$method->getDocComment() + ); + $reserved['get'.strtolower($name)]=1; + $reserved['set'.strtolower($name)]=1; + } + ksort($events); + foreach($events as $name=>$method) + { + $this->_events[$name]=array( + 'class'=>$method->getDeclaringClass()->getName(), + 'protected'=>$method->isProtected(), + 'comments'=>$method->getDocComment() + ); + $reserved[strtolower($name)]=1; + } + ksort($methods); + foreach($methods as $name=>$method) + { + if(!isset($reserved[strtolower($name)])) + $this->_methods[$name]=array( + 'class'=>$method->getDeclaringClass()->getName(), + 'protected'=>$method->isProtected(), + 'static'=>$method->isStatic(), + 'comments'=>$method->getDocComment() + ); + } + } + + /** + * Determines the property type. + * This method uses the doc comment to determine the property type. + * @param ReflectionMethod + * @return string the property type, '{unknown}' if type cannot be determined from comment + */ + protected function determinePropertyType($method) + { + $comment=$method->getDocComment(); + if(preg_match('/@return\\s+(.*?)\\s+/',$comment,$matches)) + return $matches[1]; + else + return '{unknown}'; + } + + /** + * @return string class name of the component + */ + public function getClassName() + { + return $this->_className; + } + + /** + * @return array list of component properties. Array keys are property names. + * Each array element is of the following structure: + * [type]=>property type, + * [readonly]=>whether the property is read-only, + * [protected]=>whether the method is protected or not + * [class]=>the class where the property is inherited from, + * [comments]=>comments associated with the property. + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * @return array list of component events. Array keys are event names. + * Each array element is of the following structure: + * [protected]=>whether the event is protected or not + * [class]=>the class where the event is inherited from. + * [comments]=>comments associated with the event. + */ + public function getEvents() + { + return $this->_events; + } + + /** + * @return array list of public/protected methods. Array keys are method names. + * Each array element is of the following structure: + * [protected]=>whether the method is protected or not + * [static]=>whether the method is static or not + * [class]=>the class where the property is inherited from, + * [comments]=>comments associated with the event. + */ + public function getMethods() + { + return $this->_methods; + } +}
\ No newline at end of file diff --git a/framework/TEnumerable.php b/framework/TEnumerable.php new file mode 100644 index 00000000..8dd42857 --- /dev/null +++ b/framework/TEnumerable.php @@ -0,0 +1,66 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + + +/** + * TEnumerable class. + * TEnumerable is the base class for all enumerable types. + * To define an enumerable type, extend TEnumberable and define string constants. + * Each constant represents an enumerable value. + * The constant name must be the same as the constant value. + * For example, + * <code> + * class TTextAlign extends TEnumerable + * { + * const Left='Left'; + * const Right='Right'; + * } + * </code> + * Then, one can use the enumerable values such as TTextAlign::Left and + * TTextAlign::Right. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +class TEnumerable implements Iterator +{ + private $_enums=array(); + + public function __construct() { + $reflection=new ReflectionClass($this); + $this->_enums=$reflection->getConstants(); + } + + public function current() { + return current($this->_enums); + } + + public function key() { + return key($this->_enums); + } + + public function next() { + return next($this->_enums); + } + + public function rewind() { + reset($this->_enums); + } + + public function valid() { + return $this->current()!==false; + } +}
\ No newline at end of file diff --git a/framework/TEventParameter.php b/framework/TEventParameter.php new file mode 100644 index 00000000..8ad896b3 --- /dev/null +++ b/framework/TEventParameter.php @@ -0,0 +1,26 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * TEventParameter class. + * TEventParameter is the base class for all event parameter classes. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +class TEventParameter extends TComponent +{ +}
\ No newline at end of file diff --git a/framework/TEventResults.php b/framework/TEventResults.php new file mode 100644 index 00000000..fb8a6074 --- /dev/null +++ b/framework/TEventResults.php @@ -0,0 +1,20 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +class TEventResults extends TEnumerable { + const EVENT_RESULT_FEED_FORWARD=1; + const EVENT_RESULT_FILTER=2; + const EVENT_RESULT_ALL=4; +}
\ No newline at end of file diff --git a/framework/TJavaScriptLiteral.php b/framework/TJavaScriptLiteral.php new file mode 100644 index 00000000..f38a42a0 --- /dev/null +++ b/framework/TJavaScriptLiteral.php @@ -0,0 +1,55 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * TJavaScriptLiteral class that encloses string literals that are not + * supposed to be escaped by {@link TJavaScript::encode() } + * + * Since Prado 3.2 all the data that gets sent clientside inside a javascript statement + * is encoded by default to avoid any kind of injection. + * Sometimes there's the need to bypass this encoding and send raw javascript code. + * To ensure that a string doesn't get encoded by {@link TJavaScript::encode() }, + * construct a new TJavaScriptLiteral: + * <code> + * // a javascript test string + * $js="alert('hello')"; + * // the string in $raw will not be encoded when sent clientside inside a javascript block + * $raw=new TJavaScriptLiteral($js); + * // shortened form + * $raw=_js($js); + * </code> + * + * @package System + * @since 3.2.0 + */ +class TJavaScriptLiteral +{ + protected $_s; + + public function __construct($s) + { + $this->_s = $s; + } + + public function __toString() + { + return (string)$this->_s; + } + + public function toJavaScriptLiteral() + { + return $this->__toString(); + } +}
\ No newline at end of file diff --git a/framework/TJavaScriptString.php b/framework/TJavaScriptString.php new file mode 100644 index 00000000..11e76ec5 --- /dev/null +++ b/framework/TJavaScriptString.php @@ -0,0 +1,29 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * TJavaScriptString class is an internal class that marks strings that will be + * forcibly encoded when rendered inside a javascript block + * + * @package System + * @since 3.2.0 + */ +class TJavaScriptString extends TJavaScriptLiteral +{ + public function toJavaScriptLiteral() + { + return TJavaScript::jsonEncode((string)$this->_s,JSON_HEX_QUOT | JSON_HEX_APOS | JSON_HEX_TAG); + } +}
\ No newline at end of file diff --git a/framework/TPropertyValue.php b/framework/TPropertyValue.php new file mode 100644 index 00000000..fab1c966 --- /dev/null +++ b/framework/TPropertyValue.php @@ -0,0 +1,190 @@ +<?php +/** + * TComponent, TPropertyValue classes + * + * @author Qiang Xue <qiang.xue@gmail.com> + * + * Global Events, intra-object events, Class behaviors, expanded behaviors + * @author Brad Anderson <javalizard@mac.com> + * + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System + */ + +/** + * TPropertyValue class + * + * TPropertyValue is a utility class that provides static methods + * to convert component property values to specific types. + * + * TPropertyValue is commonly used in component setter methods to ensure + * the new property value is of specific type. + * For example, a boolean-typed property setter method would be as follows, + * <code> + * function setPropertyName($value) { + * $value=TPropertyValue::ensureBoolean($value); + * // $value is now of boolean type + * } + * </code> + * + * Properties can be of the following types with specific type conversion rules: + * - string: a boolean value will be converted to 'true' or 'false'. + * - boolean: string 'true' (case-insensitive) will be converted to true, + * string 'false' (case-insensitive) will be converted to false. + * - integer + * - float + * - array: string starting with '(' and ending with ')' will be considered as + * as an array expression and will be evaluated. Otherwise, an array + * with the value to be ensured is returned. + * - object + * - enum: enumerable type, represented by an array of strings. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @package System + * @since 3.0 + */ +class TPropertyValue +{ + /** + * Converts a value to boolean type. + * Note, string 'true' (case-insensitive) will be converted to true, + * string 'false' (case-insensitive) will be converted to false. + * If a string represents a non-zero number, it will be treated as true. + * @param mixed the value to be converted. + * @return boolean + */ + public static function ensureBoolean($value) + { + if (is_string($value)) + return strcasecmp($value,'true')==0 || $value!=0; + else + return (boolean)$value; + } + + /** + * Converts a value to string type. + * Note, a boolean value will be converted to 'true' if it is true + * and 'false' if it is false. + * @param mixed the value to be converted. + * @return string + */ + public static function ensureString($value) + { + if (TJavaScript::isJsLiteral($value)) + return $value; + if (is_bool($value)) + return $value?'true':'false'; + else + return (string)$value; + } + + /** + * Converts a value to integer type. + * @param mixed the value to be converted. + * @return integer + */ + public static function ensureInteger($value) + { + return (integer)$value; + } + + /** + * Converts a value to float type. + * @param mixed the value to be converted. + * @return float + */ + public static function ensureFloat($value) + { + return (float)$value; + } + + /** + * Converts a value to array type. If the value is a string and it is + * in the form (a,b,c) then an array consisting of each of the elements + * will be returned. If the value is a string and it is not in this form + * then an array consisting of just the string will be returned. If the value + * is not a string then + * @param mixed the value to be converted. + * @return array + */ + public static function ensureArray($value) + { + if(is_string($value)) + { + $value = trim($value); + $len = strlen($value); + if ($len >= 2 && $value[0] == '(' && $value[$len-1] == ')') + { + eval('$array=array'.$value.';'); + return $array; + } + else + return $len>0?array($value):array(); + } + else + return (array)$value; + } + + /** + * Converts a value to object type. + * @param mixed the value to be converted. + * @return object + */ + public static function ensureObject($value) + { + return (object)$value; + } + + /** + * Converts a value to enum type. + * + * This method checks if the value is of the specified enumerable type. + * A value is a valid enumerable value if it is equal to the name of a constant + * in the specified enumerable type (class). + * For more details about enumerable, see {@link TEnumerable}. + * + * For backward compatibility, this method also supports sanity + * check of a string value to see if it is among the given list of strings. + * @param mixed the value to be converted. + * @param mixed class name of the enumerable type, or array of valid enumeration values. If this is not an array, + * the method considers its parameters are of variable length, and the second till the last parameters are enumeration values. + * @return string the valid enumeration value + * @throws TInvalidDataValueException if the original value is not in the string array. + */ + public static function ensureEnum($value,$enums) + { + static $types=array(); + if(func_num_args()===2 && is_string($enums)) + { + if(!isset($types[$enums])) + $types[$enums]=new ReflectionClass($enums); + if($types[$enums]->hasConstant($value)) + return $value; + else + throw new TInvalidDataValueException( + 'propertyvalue_enumvalue_invalid',$value, + implode(' | ',$types[$enums]->getConstants())); + } + else 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)); + } + + /** + * Converts the value to 'null' if the given value is empty + * @param mixed value to be converted + * @return mixed input or NULL if input is empty + */ + public static function ensureNullIfEmpty($value) + { + return empty($value)?null:$value; + } +}
\ No newline at end of file diff --git a/framework/pradolite.php b/framework/pradolite.php deleted file mode 100644 index fcf73364..00000000 --- a/framework/pradolite.php +++ /dev/null @@ -1,11147 +0,0 @@ -<?php -/** - * File Name: pradolite.php - * Last Update: 2014/02/02 21:38:53 - * Generated By: buildscripts/phpbuilder/build.php - * - * This file is used in lieu of prado.php to boost PRADO application performance. - * It is generated by expanding prado.php with included files. - * Comments and trace statements are stripped off. - * - * Do not modify this file manually. - */ - -if(!defined('PRADO_DIR')) - define('PRADO_DIR',dirname(__FILE__)); -if(!defined('PRADO_CHMOD')) - define('PRADO_CHMOD',0777); -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; - protected static $classExists = array(); - public static function getVersion() - { - return '3.2.3'; - } - public static function initErrorHandlers() - { - set_error_handler(array('PradoBase','phpErrorHandler')); - set_exception_handler(array('PradoBase','exceptionHandler')); - } - public static function autoload($className) - { - include_once($className.self::CLASS_FILE_EXT); - if(!class_exists($className,false) && !interface_exists($className,false)) - self::fatalError("Class file for '$className' cannot be found."); - } - public static function poweredByPrado($logoType=0) - { - $logoName=$logoType==1?'powered2':'powered'; - if(self::$_application!==null) - { - $am=self::$_application->getAssetManager(); - $url=$am->publishFilePath(self::getPathOfNamespace('System.'.$logoName,'.gif')); - } - else - $url='http://www.pradosoft.com/images/'.$logoName.'.gif'; - return '<a title="Powered by PRADO" href="http://www.pradosoft.com/" target="_blank"><img src="'.$url.'" style="border-width:0px;" alt="Powered by PRADO" /></a>'; - } - public static function phpErrorHandler($errno,$errstr,$errfile,$errline) - { - if(error_reporting() & $errno) - 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 && !defined('PRADO_TEST_RUN')) - 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 createComponent($type) - { - if(!isset(self::$classExists[$type])) - self::$classExists[$type] = class_exists($type, false); - if( !isset(self::$_usings[$type]) && !self::$classExists[$type]) { - self::using($type); - self::$classExists[$type] = class_exists($type, false); - } - if( ($pos = strrpos($type, '.')) !== false) - $type = substr($type,$pos+1); - if(($n=func_num_args())>1) - { - $args = func_get_args(); - switch($n) { - case 2: - return new $type($args[1]); - break; - case 3: - return new $type($args[1], $args[2]); - break; - case 4: - return new $type($args[1], $args[2], $args[3]); - break; - case 5: - return new $type($args[1], $args[2], $args[3], $args[4]); - break; - default: - $s='$args[1]'; - for($i=2;$i<$n;++$i) - $s.=",\$args[$i]"; - eval("\$component=new $type($s);"); - return $component; - break; - } - } - else - return new $type; - } - public static function using($namespace,$checkClassExistence=true) - { - if(isset(self::$_usings[$namespace]) || class_exists($namespace,false)) - return; - if(($pos=strrpos($namespace,'.'))===false) { - try - { - include_once($namespace.self::CLASS_FILE_EXT); - } - catch(Exception $e) - { - if($checkClassExistence && !class_exists($namespace,false)) - throw new TInvalidOperationException('prado_component_unknown',$namespace,$e->getMessage()); - else - throw $e; - } - } - else if(($path=self::getPathOfNamespace($namespace,self::CLASS_FILE_EXT))!==null) - { - $className=substr($namespace,$pos+1); - if($className==='*') { - self::$_usings[$namespace]=$path; - set_include_path(get_include_path().PATH_SEPARATOR.$path); - } - else { - self::$_usings[$namespace]=$path; - if(!$checkClassExistence || !class_exists($className,false)) - { - try - { - include_once($path); - } - catch(Exception $e) - { - if($checkClassExistence && !class_exists($className,false)) - throw new TInvalidOperationException('prado_component_unknown',$className,$e->getMessage()); - else - throw $e; - } - } - } - } - else - throw new TInvalidDataValueException('prado_using_invalid',$namespace); - } - public static function getPathOfNamespace($namespace, $ext='') - { - if(self::CLASS_FILE_EXT === $ext || empty($ext)) - { - if(isset(self::$_usings[$namespace])) - return self::$_usings[$namespace]; - if(isset(self::$_aliases[$namespace])) - return self::$_aliases[$namespace]; - } - $segs = explode('.',$namespace); - $alias = array_shift($segs); - if(null !== ($file = array_pop($segs)) && null !== ($root = self::getPathOfAlias($alias))) - return rtrim($root.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR ,$segs),'/\\').(($file === '*') ? '' : DIRECTORY_SEPARATOR.$file.$ext); - return null; - } - public static function getPathOfAlias($alias) - { - return isset(self::$_aliases[$alias])?self::$_aliases[$alias]:null; - } - protected static function getPathAliases() - { - return self::$_aliases; - } - public static function setPathOfAlias($alias,$path) - { - if(isset(self::$_aliases[$alias]) && !defined('PRADO_TEST_RUN')) - throw new TInvalidOperationException('prado_alias_redefined',$alias); - else if(($rp=realpath($path))!==false && is_dir($rp)) - { - if(strpos($alias,'.')===false) - self::$_aliases[$alias]=$rp; - else - throw new TInvalidDataValueException('prado_aliasname_invalid',$alias); - } - else - throw new TInvalidDataValueException('prado_alias_invalid',$alias,$path); - } - public static function fatalError($msg) - { - echo '<h1>Fatal Error</h1>'; - echo '<p>'.$msg.'</p>'; - if(!function_exists('debug_backtrace')) - return; - echo '<h2>Debug Backtrace</h2>'; - echo '<pre>'; - $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 '<PHP inner-code>'; - echo ' -- '; - if(isset($t['class'])) - echo $t['class'] . $t['type']; - echo $t['function'] . '('; - if(isset($t['args']) && sizeof($t['args']) > 0) - { - $count=0; - foreach($t['args'] as $item) - { - if(is_string($item)) - { - $str=htmlentities(str_replace("\r\n", "", $item), ENT_QUOTES); - if (strlen($item) > 70) - echo "'". substr($str, 0, 70) . "...'"; - else - echo "'" . $str . "'"; - } - else if (is_int($item) || is_float($item)) - echo $item; - else if (is_object($item)) - echo get_class($item); - else if (is_array($item)) - echo 'array(' . count($item) . ')'; - else if (is_bool($item)) - echo $item ? 'true' : 'false'; - else if ($item === null) - echo 'NULL'; - else if (is_resource($item)) - echo get_resource_type($item); - $count++; - if (count($t['args']) > $count) - echo ', '; - } - } - echo ")\n"; - } - echo '</pre>'; - exit(1); - } - public static function getUserLanguages() - { - static $languages=null; - if($languages===null) - { - if(!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) - $languages[0]='en'; - else - { - $languages=array(); - foreach(explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']) as $language) - { - $array=explode(';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',$ctl=null) - { - if(self::$_application && self::$_application->getMode()===TApplicationMode::Performance) - return; - if(!self::$_application || self::$_application->getMode()===TApplicationMode::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,$ctl); - } - public static function log($msg,$level=TLogger::INFO,$category='Uncategorized',$ctl=null) - { - if(self::$_logger===null) - self::$_logger=new TLogger; - self::$_logger->log($msg,$level,$category,$ctl); - } - public static function getLogger() - { - if(self::$_logger===null) - self::$_logger=new TLogger; - return self::$_logger; - } - public static function varDump($var,$depth=10,$highlight=false) - { - Prado::using('System.Util.TVarDumper'); - return TVarDumper::dump($var,$depth,$highlight); - } - public static function localize($text, $parameters=array(), $catalogue=null, $charset=null) - { - Prado::using('System.I18N.Translation'); - $app = Prado::getApplication()->getGlobalization(false); - $params = array(); - foreach($parameters as $key => $value) - $params['{'.$key.'}'] = $value; - if($app===null || ($config = $app->getTranslationConfiguration())===null) - return strtr($text, $params); - if ($catalogue===null) - $catalogue=isset($config['catalogue'])?$config['catalogue']:'messages'; - Translation::init($catalogue); - $appCharset = $app===null ? '' : $app->getCharset(); - $defaultCharset = ($app===null) ? 'UTF-8' : $app->getDefaultCharset(); - if(empty($charset)) $charset = $appCharset; - if(empty($charset)) $charset = $defaultCharset; - return Translation::formatter($catalogue)->format($text,$params,$catalogue,$charset); - } -} -PradoBase::using('System.TComponent'); -PradoBase::using('System.Exceptions.TException'); -PradoBase::using('System.Util.TLogger'); -if(!class_exists('Prado',false)) -{ - class Prado extends PradoBase - { - } -} -spl_autoload_register(array('Prado','autoload')); -Prado::initErrorHandlers(); -interface IModule -{ - public function init($config); - public function getID(); - public function setID($id); -} -interface IService -{ - public function init($config); - public function getID(); - public function setID($id); - public function getEnabled(); - public function setEnabled($value); - public function run(); -} -interface ITextWriter -{ - public function write($str); - public function flush(); -} -interface IUser -{ - public function getName(); - public function setName($value); - public function getIsGuest(); - public function setIsGuest($value); - public function getRoles(); - public function setRoles($value); - public function isInRole($role); - public function saveToString(); - public function loadFromString($string); -} -interface IStatePersister -{ - public function load(); - public function save($state); -} -interface ICache -{ - public function get($id); - public function set($id,$value,$expire=0,$dependency=null); - public function add($id,$value,$expire=0,$dependency=null); - public function delete($id); - public function flush(); -} -interface ICacheDependency -{ - public function getHasChanged(); -} -interface IRenderable -{ - public function render($writer); -} -interface IBindable -{ - public function dataBind(); -} -interface IStyleable -{ - public function getHasStyle(); - public function getStyle(); - public function clearStyle(); -} -interface IActiveControl -{ - public function getActiveControl(); -} -interface ICallbackEventHandler -{ - public function raiseCallbackEvent($eventArgument); -} -interface IDataRenderer -{ - public function getData(); - public function setData($value); -} -class TApplicationComponent extends TComponent -{ - 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(); - } - public function publishAsset($assetPath,$className=null) - { - if($className===null) - $className=get_class($this); - $class=new ReflectionClass($className); - $fullPath=dirname($class->getFileName()).DIRECTORY_SEPARATOR.$assetPath; - return $this->publishFilePath($fullPath); - } - public function publishFilePath($fullPath, $checkTimestamp=false) - { - return Prado::getApplication()->getAssetManager()->publishFilePath($fullPath, $checkTimestamp); - } -} -abstract class TModule extends TApplicationComponent implements IModule -{ - private $_id; - public function init($config) - { - } - public function getID() - { - return $this->_id; - } - public function setID($value) - { - $this->_id=$value; - } -} -abstract class TService extends TApplicationComponent implements IService -{ - private $_id; - private $_enabled=true; - public function init($config) - { - } - public function getID() - { - return $this->_id; - } - public function setID($value) - { - $this->_id=$value; - } - public function getEnabled() - { - return $this->_enabled; - } - public function setEnabled($value) - { - $this->_enabled=TPropertyValue::ensureBoolean($value); - } - public function run() - { - } -} -class TErrorHandler extends TModule -{ - const ERROR_FILE_NAME='error'; - const EXCEPTION_FILE_NAME='exception'; - const SOURCE_LINES=12; - private $_templatePath=null; - public function init($config) - { - $this->getApplication()->setErrorHandler($this); - } - public function getErrorTemplatePath() - { - if($this->_templatePath===null) - $this->_templatePath=Prado::getFrameworkPath().'/Exceptions/templates'; - return $this->_templatePath; - } - public function setErrorTemplatePath($value) - { - if(($templatePath=Prado::getPathOfNamespace($value))!==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()===TApplicationMode::Debug) - $this->displayException($param); - else - $this->handleExternalError(500,$param); - } - } - protected static function hideSecurityRelated($value, $exception=null) - { - $aRpl = array(); - if($exception !== null && $exception instanceof Exception) - { - $aTrace = $exception->getTrace(); - foreach($aTrace as $item) - { - if(isset($item['file'])) - $aRpl[dirname($item['file']) . DIRECTORY_SEPARATOR] = '<hidden>' . DIRECTORY_SEPARATOR; - } - } - $aRpl[$_SERVER['DOCUMENT_ROOT']] = '${DocumentRoot}'; - $aRpl[str_replace('/', DIRECTORY_SEPARATOR, $_SERVER['DOCUMENT_ROOT'])] = '${DocumentRoot}'; - $aRpl[PRADO_DIR . DIRECTORY_SEPARATOR] = '${PradoFramework}' . DIRECTORY_SEPARATOR; - if(isset($aRpl[DIRECTORY_SEPARATOR])) unset($aRpl[DIRECTORY_SEPARATOR]); - $aRpl = array_reverse($aRpl, true); - return str_replace(array_keys($aRpl), $aRpl, $value); - } - protected function handleExternalError($statusCode,$exception) - { - if(!($exception instanceof THttpException)) - error_log($exception->__toString()); - $content=$this->getErrorTemplate($statusCode,$exception); - $serverAdmin=isset($_SERVER['SERVER_ADMIN'])?$_SERVER['SERVER_ADMIN']:''; - $isDebug = $this->getApplication()->getMode()===TApplicationMode::Debug; - $errorMessage = $exception->getMessage(); - if($isDebug) - $version=$_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion(); - else - { - $version=''; - $errorMessage = self::hideSecurityRelated($errorMessage, $exception); - } - $tokens=array( - '%%StatusCode%%' => "$statusCode", - '%%ErrorMessage%%' => htmlspecialchars($errorMessage), - '%%ServerAdmin%%' => $serverAdmin, - '%%Version%%' => $version, - '%%Time%%' => @strftime('%Y-%m-%d %H:%M',time()) - ); - $CGI=substr(php_sapi_name(), 0, 3) == 'cgi'; if($isDebug) - { - if ($CGI) - header("Status: $statusCode ".$exception->getMessage(), true, TPropertyValue::ensureInteger($statusCode)); - else - header("HTTP/1.0 $statusCode ".$exception->getMessage(), true, TPropertyValue::ensureInteger($statusCode)); - } else { - if ($CGI) - header("Status: $statusCode", true, TPropertyValue::ensureInteger($statusCode)); - else - header("HTTP/1.0 $statusCode", true, TPropertyValue::ensureInteger($statusCode)); - } - echo strtr($content,$tokens); - } - protected function handleRecursiveError($exception) - { - if($this->getApplication()->getMode()===TApplicationMode::Debug) - { - echo "<html><head><title>Recursive Error</title></head>\n"; - echo "<body><h1>Recursive Error</h1>\n"; - echo "<pre>".$exception->__toString()."</pre>\n"; - echo "</body></html>"; - } - else - { - error_log("Error happened while processing an existing error:\n".$exception->__toString()); - header('HTTP/1.0 500 Internal Error'); - } - } - protected function displayException($exception) - { - if(php_sapi_name()==='cli') - { - echo $exception->getMessage()."\n"; - echo $exception->getTraceAsString(); - return; - } - if($exception instanceof TTemplateException) - { - $fileName=$exception->getTemplateFile(); - $lines=empty($fileName)?explode("\n",$exception->getTemplateSource()):@file($fileName); - $source=$this->getSourceCode($lines,$exception->getLineNumber()); - if($fileName==='') - $fileName='---embedded template---'; - $errorLine=$exception->getLineNumber(); - } - else - { - if(($trace=$this->getExactTrace($exception))!==null) - { - $fileName=$trace['file']; - $errorLine=$trace['line']; - } - else - { - $fileName=$exception->getFile(); - $errorLine=$exception->getLine(); - } - $source=$this->getSourceCode(@file($fileName),$errorLine); - } - if($this->getApplication()->getMode()===TApplicationMode::Debug) - $version=$_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion(); - else - $version=''; - $tokens=array( - '%%ErrorType%%' => get_class($exception), - '%%ErrorMessage%%' => $this->addLink(htmlspecialchars($exception->getMessage())), - '%%SourceFile%%' => htmlspecialchars($fileName).' ('.$errorLine.')', - '%%SourceCode%%' => $source, - '%%StackTrace%%' => htmlspecialchars($exception->getTraceAsString()), - '%%Version%%' => $version, - '%%Time%%' => @strftime('%Y-%m-%d %H:%M',time()) - ); - $content=$this->getExceptionTemplate($exception); - echo strtr($content,$tokens); - } - protected function getExceptionTemplate($exception) - { - $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'."); - return $content; - } - protected function getErrorTemplate($statusCode,$exception) - { - $base=$this->getErrorTemplatePath().DIRECTORY_SEPARATOR.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'."); - return $content; - } - private function getExactTrace($exception) - { - $trace=$exception->getTrace(); - $result=null; - if($exception instanceof TPhpErrorException) - $result=isset($trace[0]['file'])?$trace[0]:$trace[1]; - else if($exception instanceof TInvalidOperationException) - { - if(($result=$this->getPropertyAccessTrace($trace,'__get'))===null) - $result=$this->getPropertyAccessTrace($trace,'__set'); - } - if($result!==null && strpos($result['file'],': eval()\'d code')!==false) - return null; - return $result; - } - private function getPropertyAccessTrace($trace,$pattern) - { - $result=null; - foreach($trace as $t) - { - if(isset($t['function']) && $t['function']===$pattern) - $result=$t; - else - break; - } - return $result; - } - private function getSourceCode($lines,$errorLine) - { - $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;$i<$endLine;++$i) - { - if($i===$errorLine-1) - { - $line=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",' ',$lines[$i]))); - $source.="<div class=\"error\">".$line."</div>"; - } - else - $source.=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",' ',$lines[$i]))); - } - return $source; - } - private function addLink($message) - { - $baseUrl='http://www.pradosoft.com/docs/classdoc'; - return preg_replace('/\b(T[A-Z]\w+)\b/',"<a href=\"$baseUrl/\${1}\" target=\"_blank\">\${1}</a>",$message); - } -} -class TList extends TComponent implements IteratorAggregate,ArrayAccess,Countable -{ - private $_d=array(); - private $_c=0; - private $_r=false; - public function __construct($data=null,$readOnly=false) - { - if($data!==null) - $this->copyFrom($data); - $this->setReadOnly($readOnly); - } - public function getReadOnly() - { - return $this->_r; - } - protected function setReadOnly($value) - { - $this->_r=TPropertyValue::ensureBoolean($value); - } - public function getIterator() - { - return new ArrayIterator( $this->_d ); - } - public function count() - { - return $this->getCount(); - } - public function getCount() - { - return $this->_c; - } - public function itemAt($index) - { - if($index>=0 && $index<$this->_c) - return $this->_d[$index]; - else - throw new TInvalidDataValueException('list_index_invalid',$index); - } - public function add($item) - { - $this->insertAt($this->_c,$item); - return $this->_c-1; - } - public function insertAt($index,$item) - { - if(!$this->_r) - { - if($index===$this->_c) - $this->_d[$this->_c++]=$item; - else if($index>=0 && $index<$this->_c) - { - array_splice($this->_d,$index,0,array($item)); - $this->_c++; - } - else - throw new TInvalidDataValueException('list_index_invalid',$index); - } - else - throw new TInvalidOperationException('list_readonly',get_class($this)); - } - public function remove($item) - { - if(!$this->_r) - { - if(($index=$this->indexOf($item))>=0) - { - $this->removeAt($index); - return $index; - } - else - throw new TInvalidDataValueException('list_item_inexistent'); - } - else - throw new TInvalidOperationException('list_readonly',get_class($this)); - } - public function removeAt($index) - { - if(!$this->_r) - { - if($index>=0 && $index<$this->_c) - { - $this->_c--; - if($index===$this->_c) - return array_pop($this->_d); - else - { - $item=$this->_d[$index]; - array_splice($this->_d,$index,1); - return $item; - } - } - else - throw new TInvalidDataValueException('list_index_invalid',$index); - } - else - throw new TInvalidOperationException('list_readonly',get_class($this)); - } - 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 insertBefore($baseitem, $item) - { - if(!$this->_r) - { - if(($index = $this->indexOf($baseitem)) == -1) - throw new TInvalidDataValueException('list_item_inexistent'); - $this->insertAt($index, $item); - return $index; - } - else - throw new TInvalidOperationException('list_readonly',get_class($this)); - } - public function insertAfter($baseitem, $item) - { - if(!$this->_r) - { - if(($index = $this->indexOf($baseitem)) == -1) - throw new TInvalidDataValueException('list_item_inexistent'); - $this->insertAt($index + 1, $item); - return $index + 1; - } - else - throw new TInvalidOperationException('list_readonly',get_class($this)); - } - 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 ($offset>=0 && $offset<$this->_c); - } - public function offsetGet($offset) - { - return $this->itemAt($offset); - } - public function offsetSet($offset,$item) - { - if($offset===null || $offset===$this->_c) - $this->insertAt($this->_c,$item); - else - { - $this->removeAt($offset); - $this->insertAt($offset,$item); - } - } - public function offsetUnset($offset) - { - $this->removeAt($offset); - } -} -class TListIterator implements Iterator -{ - private $_d; - private $_i; - private $_c; - public function __construct(&$data) - { - $this->_d=&$data; - $this->_i=0; - $this->_c=count($this->_d); - } - 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 $this->_i<$this->_c; - } -} -abstract class TCache extends TModule implements ICache, ArrayAccess -{ - private $_prefix=null; - private $_primary=true; - public function init($config) - { - if($this->_prefix===null) - $this->_prefix=$this->getApplication()->getUniqueID(); - if($this->_primary) - { - if($this->getApplication()->getCache()===null) - $this->getApplication()->setCache($this); - else - throw new TConfigurationException('cache_primary_duplicated',get_class($this)); - } - } - public function getPrimaryCache() - { - return $this->_primary; - } - public function setPrimaryCache($value) - { - $this->_primary=TPropertyValue::ensureBoolean($value); - } - public function getKeyPrefix() - { - return $this->_prefix; - } - public function setKeyPrefix($value) - { - $this->_prefix=$value; - } - protected function generateUniqueKey($key) - { - return md5($this->_prefix.$key); - } - public function get($id) - { - if(($data=$this->getValue($this->generateUniqueKey($id)))!==false) - { - if(!is_array($data)) - return false; - if(!($data[1] instanceof ICacheDependency) || !$data[1]->getHasChanged()) - return $data[0]; - } - return false; - } - public function set($id,$value,$expire=0,$dependency=null) - { - if(empty($value) && $expire === 0) - $this->delete($id); - else - { - $data=array($value,$dependency); - return $this->setValue($this->generateUniqueKey($id),$data,$expire); - } - } - public function add($id,$value,$expire=0,$dependency=null) - { - if(empty($value) && $expire === 0) - return false; - $data=array($value,$dependency); - return $this->addValue($this->generateUniqueKey($id),$data,$expire); - } - public function delete($id) - { - return $this->deleteValue($this->generateUniqueKey($id)); - } - public function flush() - { - throw new TNotSupportedException('cache_flush_unsupported'); - } - abstract protected function getValue($key); - abstract protected function setValue($key,$value,$expire); - abstract protected function addValue($key,$value,$expire); - abstract protected function deleteValue($key); - public function offsetExists($id) - { - return $this->get($id) !== false; - } - public function offsetGet($id) - { - return $this->get($id); - } - public function offsetSet($id, $value) - { - $this->set($id, $value); - } - public function offsetUnset($id) - { - $this->delete($id); - } -} -abstract class TCacheDependency extends TComponent implements ICacheDependency -{ -} -class TFileCacheDependency extends TCacheDependency -{ - private $_fileName; - private $_timestamp; - public function __construct($fileName) - { - $this->setFileName($fileName); - } - public function getFileName() - { - return $this->_fileName; - } - public function setFileName($value) - { - $this->_fileName=$value; - $this->_timestamp=@filemtime($value); - } - public function getTimestamp() - { - return $this->_timestamp; - } - public function getHasChanged() - { - return @filemtime($this->_fileName)!==$this->_timestamp; - } -} -class TDirectoryCacheDependency extends TCacheDependency -{ - private $_recursiveCheck=true; - private $_recursiveLevel=-1; - private $_timestamps; - private $_directory; - public function __construct($directory) - { - $this->setDirectory($directory); - } - public function getDirectory() - { - return $this->_directory; - } - public function setDirectory($directory) - { - if(($path=realpath($directory))===false || !is_dir($path)) - throw new TInvalidDataValueException('directorycachedependency_directory_invalid',$directory); - $this->_directory=$path; - $this->_timestamps=$this->generateTimestamps($path); - } - public function getRecursiveCheck() - { - return $this->_recursiveCheck; - } - public function setRecursiveCheck($value) - { - $this->_recursiveCheck=TPropertyValue::ensureBoolean($value); - } - public function getRecursiveLevel() - { - return $this->_recursiveLevel; - } - public function setRecursiveLevel($value) - { - $this->_recursiveLevel=TPropertyValue::ensureInteger($value); - } - public function getHasChanged() - { - return $this->generateTimestamps($this->_directory)!=$this->_timestamps; - } - protected function validateFile($fileName) - { - return true; - } - protected function validateDirectory($directory) - { - return true; - } - protected function generateTimestamps($directory,$level=0) - { - if(($dir=opendir($directory))===false) - throw new TIOException('directorycachedependency_directory_invalid',$directory); - $timestamps=array(); - while(($file=readdir($dir))!==false) - { - $path=$directory.DIRECTORY_SEPARATOR.$file; - if($file==='.' || $file==='..') - continue; - else if(is_dir($path)) - { - if(($this->_recursiveLevel<0 || $level<$this->_recursiveLevel) && $this->validateDirectory($path)) - $timestamps=array_merge($this->generateTimestamps($path,$level+1)); - } - else if($this->validateFile($path)) - $timestamps[$path]=filemtime($path); - } - closedir($dir); - return $timestamps; - } -} -class TGlobalStateCacheDependency extends TCacheDependency -{ - private $_stateName; - private $_stateValue; - public function __construct($name) - { - $this->setStateName($name); - } - public function getStateName() - { - return $this->_stateName; - } - public function setStateName($value) - { - $this->_stateName=$value; - $this->_stateValue=Prado::getApplication()->getGlobalState($value); - } - public function getHasChanged() - { - return $this->_stateValue!==Prado::getApplication()->getGlobalState($this->_stateName); - } -} -class TChainedCacheDependency extends TCacheDependency -{ - private $_dependencies=null; - public function getDependencies() - { - if($this->_dependencies===null) - $this->_dependencies=new TCacheDependencyList; - return $this->_dependencies; - } - public function getHasChanged() - { - if($this->_dependencies!==null) - { - foreach($this->_dependencies as $dependency) - if($dependency->getHasChanged()) - return true; - } - return false; - } -} -class TApplicationStateCacheDependency extends TCacheDependency -{ - public function getHasChanged() - { - return Prado::getApplication()->getMode()!==TApplicationMode::Performance; - } -} -class TCacheDependencyList extends TList -{ - public function insertAt($index,$item) - { - if($item instanceof ICacheDependency) - parent::insertAt($index,$item); - else - throw new TInvalidDataTypeException('cachedependencylist_cachedependency_required'); - } -} -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 TPriorityList extends TList -{ - private $_d=array(); - private $_o=false; - private $_fd=null; - private $_c=0; - private $_dp=10; - private $_p=8; - public function __construct($data=null,$readOnly=false,$defaultPriority=10,$precision=8) - { - parent::__construct(); - if($data!==null) - $this->copyFrom($data); - $this->setReadOnly($readOnly); - $this->setPrecision($precision); - $this->setDefaultPriority($defaultPriority); - } - public function count() - { - return $this->getCount(); - } - public function getCount() - { - return $this->_c; - } - public function getPriorityCount($priority=null) - { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - if(!isset($this->_d[$priority]) || !is_array($this->_d[$priority])) - return false; - return count($this->_d[$priority]); - } - public function getDefaultPriority() - { - return $this->_dp; - } - protected function setDefaultPriority($value) - { - $this->_dp=(string)round(TPropertyValue::ensureFloat($value),$this->_p); - } - public function getPrecision() - { - return $this->_p; - } - protected function setPrecision($value) - { - $this->_p=TPropertyValue::ensureInteger($value); - } - public function getIterator() - { - return new ArrayIterator($this->flattenPriorities()); - } - public function getPriorities() - { - $this->sortPriorities(); - return array_keys($this->_d); - } - protected function sortPriorities() { - if(!$this->_o) { - ksort($this->_d,SORT_NUMERIC); - $this->_o=true; - } - } - protected function flattenPriorities() { - if(is_array($this->_fd)) - return $this->_fd; - $this->sortPriorities(); - $this->_fd=array(); - foreach($this->_d as $priority => $itemsatpriority) - $this->_fd=array_merge($this->_fd,$itemsatpriority); - return $this->_fd; - } - public function itemAt($index) - { - if($index>=0&&$index<$this->getCount()) { - $arr=$this->flattenPriorities(); - return $arr[$index]; - } else - throw new TInvalidDataValueException('list_index_invalid',$index); - } - public function itemsAtPriority($priority=null) - { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - return isset($this->_d[$priority])?$this->_d[$priority]:null; - } - public function itemAtIndexInPriority($index,$priority=null) - { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority), $this->_p); - return !isset($this->_d[$priority])?false:( - isset($this->_d[$priority][$index])?$this->_d[$priority][$index]:false - ); - } - public function add($item,$priority=null) - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - return $this->insertAtIndexInPriority($item,false,$priority,true); - } - public function insertAt($index,$item) - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - if(($priority=$this->priorityAt($index,true))!==false) - $this->insertAtIndexInPriority($item,$priority[1],$priority[0]); - else - throw new TInvalidDataValueException('list_index_invalid',$index); - } - public function insertAtIndexInPriority($item,$index=false,$priority=null,$preserveCache=false) - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority), $this->_p); - if($preserveCache) { - $this->sortPriorities(); - $cc=0; - foreach($this->_d as $prioritykey=>$items) - if($prioritykey>=$priority) - break; - else - $cc+=count($items); - if($index===false&&isset($this->_d[$priority])) { - $c=count($this->_d[$priority]); - $c+=$cc; - $this->_d[$priority][]=$item; - } else if(isset($this->_d[$priority])) { - $c=$index+$cc; - array_splice($this->_d[$priority],$index,0,array($item)); - } else { - $c = $cc; - $this->_o = false; - $this->_d[$priority]=array($item); - } - if($this->_fd&&is_array($this->_fd)) array_splice($this->_fd,$c,0,array($item)); - } else { - $c=null; - if($index===false&&isset($this->_d[$priority])) { - $cc=count($this->_d[$priority]); - $this->_d[$priority][]=$item; - } else if(isset($this->_d[$priority])) { - $cc=$index; - array_splice($this->_d[$priority],$index,0,array($item)); - } else { - $cc=0; - $this->_o=false; - $this->_d[$priority]=array($item); - } - if($this->_fd&&is_array($this->_fd)&&count($this->_d)==1) - array_splice($this->_fd,$cc,0,array($item)); - else - $this->_fd=null; - } - $this->_c++; - return $c; - } - public function remove($item,$priority=false) - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - if(($p=$this->priorityOf($item,true))!==false) - { - if($priority!==false) { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - if($p[0]!=$priority) - throw new TInvalidDataValueException('list_item_inexistent'); - } - $this->removeAtIndexInPriority($p[1],$p[0]); - return $p[2]; - } - else - throw new TInvalidDataValueException('list_item_inexistent'); - } - public function removeAt($index) - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - if(($priority=$this->priorityAt($index, true))!==false) - return $this->removeAtIndexInPriority($priority[1],$priority[0]); - throw new TInvalidDataValueException('list_index_invalid',$index); - } - public function removeAtIndexInPriority($index, $priority=null) - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - if(!isset($this->_d[$priority])||$index<0||$index>=count($this->_d[$priority])) - throw new TInvalidDataValueException('list_item_inexistent'); - $value=array_splice($this->_d[$priority],$index,1); - $value=$value[0]; - if(!count($this->_d[$priority])) - unset($this->_d[$priority]); - $this->_c--; - $this->_fd=null; - return $value; - } - public function clear() - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - $d=array_reverse($this->_d,true); - foreach($this->_d as $priority=>$items) { - for($index=count($items)-1;$index>=0;$index--) - $this->removeAtIndexInPriority($index,$priority); - unset($this->_d[$priority]); - } - } - public function contains($item) - { - return $this->indexOf($item)>=0; - } - public function indexOf($item) - { - if(($index=array_search($item,$this->flattenPriorities(),true))===false) - return -1; - else - return $index; - } - public function priorityOf($item,$withindex = false) - { - $this->sortPriorities(); - $absindex = 0; - foreach($this->_d as $priority=>$items) { - if(($index=array_search($item,$items,true))!==false) { - $absindex+=$index; - return $withindex?array($priority,$index,$absindex, - 'priority'=>$priority,'index'=>$index,'absindex'=>$absindex):$priority; - } else - $absindex+=count($items); - } - return false; - } - public function priorityAt($index,$withindex = false) - { - if($index<0||$index>=$this->getCount()) - throw new TInvalidDataValueException('list_index_invalid',$index); - $absindex=$index; - $this->sortPriorities(); - foreach($this->_d as $priority=>$items) { - if($index>=($c=count($items))) - $index-=$c; - else - return $withindex?array($priority,$index,$absindex, - 'priority'=>$priority,'index'=>$index,'absindex'=>$absindex):$priority; - } - return false; - } - public function insertBefore($indexitem, $item) - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - if(($priority=$this->priorityOf($indexitem,true))===false) - throw new TInvalidDataValueException('list_item_inexistent'); - $this->insertAtIndexInPriority($item,$priority[1],$priority[0]); - return $priority[2]; - } - public function insertAfter($indexitem, $item) - { - if($this->getReadOnly()) - throw new TInvalidOperationException('list_readonly',get_class($this)); - if(($priority=$this->priorityOf($indexitem,true))===false) - throw new TInvalidDataValueException('list_item_inexistent'); - $this->insertAtIndexInPriority($item,$priority[1]+1,$priority[0]); - return $priority[2]+1; - } - public function toArray() - { - return $this->flattenPriorities(); - } - public function toPriorityArray() - { - $this->sortPriorities(); - return $this->_d; - } - public function toArrayBelowPriority($priority,$inclusive=false) - { - $this->sortPriorities(); - $items=array(); - foreach($this->_d as $itemspriority=>$itemsatpriority) - { - if((!$inclusive&&$itemspriority>=$priority)||$itemspriority>$priority) - break; - $items=array_merge($items,$itemsatpriority); - } - return $items; - } - public function toArrayAbovePriority($priority,$inclusive=true) - { - $this->sortPriorities(); - $items=array(); - foreach($this->_d as $itemspriority=>$itemsatpriority) - { - if((!$inclusive&&$itemspriority<=$priority)||$itemspriority<$priority) - continue; - $items=array_merge($items,$itemsatpriority); - } - return $items; - } - public function copyFrom($data) - { - if($data instanceof TPriorityList) - { - if($this->getCount()>0) - $this->clear(); - foreach($data->getPriorities() as $priority) - { - foreach($data->itemsAtPriority($priority) as $index=>$item) - $this->insertAtIndexInPriority($item,$index,$priority); - } - } else if(is_array($data)||$data instanceof Traversable) { - if($this->getCount()>0) - $this->clear(); - foreach($data as $key=>$item) - $this->add($item); - } else if($data!==null) - throw new TInvalidDataTypeException('map_data_not_iterable'); - } - public function mergeWith($data) - { - if($data instanceof TPriorityList) - { - foreach($data->getPriorities() as $priority) - { - foreach($data->itemsAtPriority($priority) as $index=>$item) - $this->insertAtIndexInPriority($item,false,$priority); - } - } - else if(is_array($data)||$data instanceof Traversable) - { - foreach($data as $priority=>$item) - $this->add($item); - } - else if($data!==null) - throw new TInvalidDataTypeException('map_data_not_iterable'); - } - public function offsetExists($offset) - { - return ($offset>=0&&$offset<$this->getCount()); - } - public function offsetGet($offset) - { - return $this->itemAt($offset); - } - public function offsetSet($offset,$item) - { - if($offset===null) - return $this->add($item); - if($offset===$this->getCount()) { - $priority=$this->priorityAt($offset-1,true); - $priority[1]++; - } else { - $priority=$this->priorityAt($offset,true); - $this->removeAtIndexInPriority($priority[1],$priority[0]); - } - $this->insertAtIndexInPriority($item,$priority[1],$priority[0]); - } - public function offsetUnset($offset) - { - $this->removeAt($offset); - } -} -class TMap extends TComponent implements IteratorAggregate,ArrayAccess,Countable -{ - private $_d=array(); - private $_r=false; - public function __construct($data=null,$readOnly=false) - { - if($data!==null) - $this->copyFrom($data); - $this->setReadOnly($readOnly); - } - public function getReadOnly() - { - return $this->_r; - } - protected function setReadOnly($value) - { - $this->_r=TPropertyValue::ensureBoolean($value); - } - public function getIterator() - { - return new ArrayIterator( $this->_d ); - } - public function count() - { - return $this->getCount(); - } - 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->_r) - $this->_d[$key]=$value; - else - throw new TInvalidOperationException('map_readonly',get_class($this)); - } - public function remove($key) - { - if(!$this->_r) - { - if(isset($this->_d[$key]) || array_key_exists($key,$this->_d)) - { - $value=$this->_d[$key]; - unset($this->_d[$key]); - return $value; - } - else - return null; - } - else - throw new TInvalidOperationException('map_readonly',get_class($this)); - } - public function clear() - { - foreach(array_keys($this->_d) as $key) - $this->remove($key); - } - public function contains($key) - { - return isset($this->_d[$key]) || array_key_exists($key,$this->_d); - } - 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 $this->itemAt($offset); - } - public function offsetSet($offset,$item) - { - $this->add($offset,$item); - } - public function offsetUnset($offset) - { - $this->remove($offset); - } -} -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() - { - $this->_key=next($this->_keys); - } - public function valid() - { - return $this->_key!==false; - } -} -class TPriorityMap extends TMap -{ - private $_d=array(); - private $_r=false; - private $_o=false; - private $_fd=null; - private $_c=0; - private $_dp=10; - private $_p=8; - public function __construct($data=null,$readOnly=false,$defaultPriority=10,$precision=8) - { - if($data!==null) - $this->copyFrom($data); - $this->setReadOnly($readOnly); - $this->setPrecision($precision); - $this->setDefaultPriority($defaultPriority); - } - public function getReadOnly() - { - return $this->_r; - } - protected function setReadOnly($value) - { - $this->_r=TPropertyValue::ensureBoolean($value); - } - public function getDefaultPriority() - { - return $this->_dp; - } - protected function setDefaultPriority($value) - { - $this->_dp = (string)round(TPropertyValue::ensureFloat($value), $this->_p); - } - public function getPrecision() - { - return $this->_p; - } - protected function setPrecision($value) - { - $this->_p=TPropertyValue::ensureInteger($value); - } - public function getIterator() - { - return new ArrayIterator($this->flattenPriorities()); - } - protected function sortPriorities() { - if(!$this->_o) { - ksort($this->_d, SORT_NUMERIC); - $this->_o=true; - } - } - protected function flattenPriorities() { - if(is_array($this->_fd)) - return $this->_fd; - $this->sortPriorities(); - $this->_fd = array(); - foreach($this->_d as $priority => $itemsatpriority) - $this->_fd = array_merge($this->_fd, $itemsatpriority); - return $this->_fd; - } - public function count() - { - return $this->getCount(); - } - public function getCount() - { - return $this->_c; - } - public function getPriorityCount($priority=null) - { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - if(!isset($this->_d[$priority])||!is_array($this->_d[$priority])) - return false; - return count($this->_d[$priority]); - } - public function getPriorities() - { - $this->sortPriorities(); - return array_keys($this->_d); - } - public function getKeys() - { - return array_keys($this->flattenPriorities()); - } - public function itemAt($key,$priority=false) - { - if($priority===false){ - $map=$this->flattenPriorities(); - return isset($map[$key])?$map[$key]:null; - } else { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - return (isset($this->_d[$priority])&&isset($this->_d[$priority][$key]))?$this->_d[$priority][$key]:null; - } - } - public function setPriorityAt($key,$priority=null) - { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - $oldpriority=$this->priorityAt($key); - if($oldpriority!==false&&$oldpriority!=$priority) { - $value=$this->remove($key,$oldpriority); - $this->add($key,$value,$priority); - } - return $oldpriority; - } - public function itemsAtPriority($priority=null) - { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - return isset($this->_d[$priority])?$this->_d[$priority]:null; - } - public function priorityOf($item) - { - $this->sortPriorities(); - foreach($this->_d as $priority=>$items) - if(($index=array_search($item,$items,true))!==false) - return $priority; - return false; - } - public function priorityAt($key) - { - $this->sortPriorities(); - foreach($this->_d as $priority=>$items) - if(array_key_exists($key,$items)) - return $priority; - return false; - } - public function add($key,$value,$priority=null) - { - if($priority===null) - $priority=$this->getDefaultPriority(); - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - if(!$this->_r) - { - foreach($this->_d as $innerpriority=>$items) - if(array_key_exists($key,$items)) - { - unset($this->_d[$innerpriority][$key]); - $this->_c--; - if(count($this->_d[$innerpriority])===0) - unset($this->_d[$innerpriority]); - } - if(!isset($this->_d[$priority])) { - $this->_d[$priority]=array($key=>$value); - $this->_o=false; - } - else - $this->_d[$priority][$key]=$value; - $this->_c++; - $this->_fd=null; - } - else - throw new TInvalidOperationException('map_readonly',get_class($this)); - return $priority; - } - public function remove($key,$priority=false) - { - if(!$this->_r) - { - if($priority===null) - $priority=$this->getDefaultPriority(); - if($priority===false) - { - $this->sortPriorities(); - foreach($this->_d as $priority=>$items) - if(array_key_exists($key,$items)) - { - $value=$this->_d[$priority][$key]; - unset($this->_d[$priority][$key]); - $this->_c--; - if(count($this->_d[$priority])===0) - { - unset($this->_d[$priority]); - $this->_o=false; - } - $this->_fd=null; - return $value; - } - return null; - } - else - { - $priority=(string)round(TPropertyValue::ensureFloat($priority),$this->_p); - if(isset($this->_d[$priority])&&(isset($this->_d[$priority][$key])||array_key_exists($key,$this->_d[$priority]))) - { - $value=$this->_d[$priority][$key]; - unset($this->_d[$priority][$key]); - $this->_c--; - if(count($this->_d[$priority])===0) { - unset($this->_d[$priority]); - $this->_o=false; - } - $this->_fd=null; - return $value; - } - else - return null; - } - } - else - throw new TInvalidOperationException('map_readonly',get_class($this)); - } - public function clear() - { - foreach($this->_d as $priority=>$items) - foreach(array_keys($items) as $key) - $this->remove($key); - } - public function contains($key) - { - $map=$this->flattenPriorities(); - return isset($map[$key])||array_key_exists($key,$map); - } - public function toArray() - { - return $this->flattenPriorities(); - } - public function toArrayBelowPriority($priority,$inclusive=false) - { - $this->sortPriorities(); - $items=array(); - foreach($this->_d as $itemspriority=>$itemsatpriority) - { - if((!$inclusive&&$itemspriority>=$priority)||$itemspriority>$priority) - break; - $items=array_merge($items,$itemsatpriority); - } - return $items; - } - public function toArrayAbovePriority($priority,$inclusive=true) - { - $this->sortPriorities(); - $items=array(); - foreach($this->_d as $itemspriority=>$itemsatpriority) - { - if((!$inclusive&&$itemspriority<=$priority)||$itemspriority<$priority) - continue; - $items=array_merge($items,$itemsatpriority); - } - return $items; - } - public function copyFrom($data) - { - if($data instanceof TPriorityMap) - { - if($this->getCount()>0) - $this->clear(); - foreach($data->getPriorities() as $priority) { - foreach($data->itemsAtPriority($priority) as $key => $value) { - $this->add($key,$value,$priority); - } - } - } - else 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($data instanceof TPriorityMap) - { - foreach($data->getPriorities() as $priority) - { - foreach($data->itemsAtPriority($priority) as $key => $value) - $this->add($key,$value,$priority); - } - } - else 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 $this->itemAt($offset); - } - public function offsetSet($offset,$item) - { - $this->add($offset,$item); - } - public function offsetUnset($offset) - { - $this->remove($offset); - } -} -class TStack extends TComponent implements IteratorAggregate,Countable -{ - private $_d=array(); - private $_c=0; - public function __construct($data=null) - { - if($data!==null) - $this->copyFrom($data); - } - public function toArray() - { - return $this->_d; - } - public function copyFrom($data) - { - if(is_array($data) || ($data instanceof Traversable)) - { - $this->clear(); - foreach($data as $item) - { - $this->_d[]=$item; - ++$this->_c; - } - } - else if($data!==null) - throw new TInvalidDataTypeException('stack_data_not_iterable'); - } - public function clear() - { - $this->_c=0; - $this->_d=array(); - } - public function contains($item) - { - return array_search($item,$this->_d,true)!==false; - } - public function peek() - { - if($this->_c===0) - throw new TInvalidOperationException('stack_empty'); - else - return $this->_d[$this->_c-1]; - } - public function pop() - { - if($this->_c===0) - throw new TInvalidOperationException('stack_empty'); - else - { - --$this->_c; - return array_pop($this->_d); - } - } - public function push($item) - { - ++$this->_c; - $this->_d[] = $item; - } - public function getIterator() - { - return new ArrayIterator( $this->_d ); - } - public function getCount() - { - return $this->_c; - } - public function count() - { - return $this->getCount(); - } -} -class TStackIterator implements Iterator -{ - private $_d; - private $_i; - private $_c; - public function __construct(&$data) - { - $this->_d=&$data; - $this->_i=0; - $this->_c=count($this->_d); - } - 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 $this->_i<$this->_c; - } -} -class TXmlElement extends TComponent -{ - private $_parent=null; - private $_tagName='unknown'; - private $_value=''; - private $_elements=null; - private $_attributes=null; - public function __construct($tagName) - { - $this->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=TPropertyValue::ensureString($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 setAttribute($name,$value) - { - $this->getAttributes()->add($name,TPropertyValue::ensureString($value)); - } - 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) - { - $value=$this->xmlEncode($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(($value=$this->getValue())!=='') - { - $value=$this->xmlEncode($value); - return $prefix."<{$this->_tagName}$attr>$value</{$this->_tagName}>"; - } - else - return $prefix."<{$this->_tagName}$attr />"; - } - public function __toString() - { - return $this->toString(); - } - private function xmlEncode($str) - { - return strtr($str,array( - '>'=>'>', - '<'=>'<', - '&'=>'&', - '"'=>'"', - "\r"=>'
', - "\t"=>'	', - "\n"=>'
')); - } -} -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(); - static $bSimpleXml; - if($bSimpleXml === null) - $bSimpleXml = (boolean)function_exists('simplexml_load_string'); - if($bSimpleXml) - { - $simpleDoc = simplexml_load_string($string); - $docNamespaces = $simpleDoc->getDocNamespaces(false); - $simpleDoc = null; - foreach($docNamespaces as $prefix => $uri) - { - if($prefix === '') - $attributes->add('xmlns', $uri); - else - $attributes->add('xmlns:'.$prefix, $uri); - } - } - foreach($element->attributes as $name=>$attr) - $attributes->add(($attr->prefix === '' ? '' : $attr->prefix . ':') .$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 "<?xml{$version}{$encoding}?>\n".$this->toString(0); - } - public function __toString() - { - return $this->saveToString(); - } - private function buildElement($node) - { - $element=new TXmlElement($node->tagName); - $element->setValue($node->nodeValue); - foreach($node->attributes as $name=>$attr) - $element->getAttributes()->add(($attr->prefix === '' ? '' : $attr->prefix . ':') . $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) - { - $this->_o=$owner; - } - protected function getOwner() - { - return $this->_o; - } - public function insertAt($index,$item) - { - if($item instanceof TXmlElement) - { - parent::insertAt($index,$item); - if($item->getParent()!==null) - $item->getParent()->getElements()->remove($item); - $item->setParent($this->_o); - } - else - throw new TInvalidDataTypeException('xmlelementlist_xmlelement_required'); - } - public function removeAt($index) - { - $item=parent::removeAt($index); - if($item instanceof TXmlElement) - $item->setParent(null); - return $item; - } -} -class TAuthorizationRule extends TComponent -{ - private $_action; - private $_users; - private $_roles; - private $_verb; - private $_ipRules; - private $_everyone; - private $_guest; - private $_authenticated; - public function __construct($action,$users,$roles,$verb='',$ipRules='') - { - $action=strtolower(trim($action)); - if($action==='allow' || $action==='deny') - $this->_action=$action; - else - throw new TInvalidDataValueException('authorizationrule_action_invalid',$action); - $this->_users=array(); - $this->_roles=array(); - $this->_ipRules=array(); - $this->_everyone=false; - $this->_guest=false; - $this->_authenticated=false; - if(trim($users)==='') - $users='*'; - foreach(explode(',',$users) as $user) - { - if(($user=trim(strtolower($user)))!=='') - { - if($user==='*') - { - $this->_everyone=true; - break; - } - else if($user==='?') - $this->_guest=true; - else if($user==='@') - $this->_authenticated=true; - else - $this->_users[]=$user; - } - } - if(trim($roles)==='') - $roles='*'; - foreach(explode(',',$roles) as $role) - { - if(($role=trim(strtolower($role)))!=='') - $this->_roles[]=$role; - } - if(($verb=trim(strtolower($verb)))==='') - $verb='*'; - if($verb==='*' || $verb==='get' || $verb==='post') - $this->_verb=$verb; - else - throw new TInvalidDataValueException('authorizationrule_verb_invalid',$verb); - if(trim($ipRules)==='') - $ipRules='*'; - foreach(explode(',',$ipRules) as $ipRule) - { - if(($ipRule=trim($ipRule))!=='') - $this->_ipRules[]=$ipRule; - } - } - 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 getIPRules() - { - return $this->_ipRules; - } - public function getGuestApplied() - { - return $this->_guest || $this->_everyone; - } - public function getEveryoneApplied() - { - return $this->_everyone; - } - public function getAuthenticatedApplied() - { - return $this->_authenticated || $this->_everyone; - } - public function isUserAllowed(IUser $user,$verb,$ip) - { - if($this->isVerbMatched($verb) && $this->isIpMatched($ip) && $this->isUserMatched($user) && $this->isRoleMatched($user)) - return ($this->_action==='allow')?1:-1; - else - return 0; - } - private function isIpMatched($ip) - { - if(empty($this->_ipRules)) - return 1; - foreach($this->_ipRules as $rule) - { - if($rule==='*' || $rule===$ip || (($pos=strpos($rule,'*'))!==false && strncmp($ip,$rule,$pos)===0)) - return 1; - } - return 0; - } - private function isUserMatched($user) - { - return ($this->_everyone || ($this->_guest && $user->getIsGuest()) || ($this->_authenticated && !$user->getIsGuest()) || in_array(strtolower($user->getName()),$this->_users)); - } - private function isRoleMatched($user) - { - foreach($this->_roles as $role) - { - if($role==='*' || $user->isInRole($role)) - return true; - } - return false; - } - private function isVerbMatched($verb) - { - return ($this->_verb==='*' || strcasecmp($verb,$this->_verb)===0); - } -} -class TAuthorizationRuleCollection extends TList -{ - public function isUserAllowed($user,$verb,$ip) - { - if($user instanceof IUser) - { - $verb=strtolower(trim($verb)); - foreach($this as $rule) - { - if(($decision=$rule->isUserAllowed($user,$verb,$ip))!==0) - return ($decision>0); - } - return true; - } - else - return false; - } - public function insertAt($index,$item) - { - if($item instanceof TAuthorizationRule) - parent::insertAt($index,$item); - else - throw new TInvalidDataTypeException('authorizationrulecollection_authorizationrule_required'); - } -} -class TSecurityManager extends TModule -{ - const STATE_VALIDATION_KEY = 'prado:securitymanager:validationkey'; - const STATE_ENCRYPTION_KEY = 'prado:securitymanager:encryptionkey'; - private $_validationKey = null; - private $_encryptionKey = null; - private $_hashAlgorithm = 'sha1'; - private $_cryptAlgorithm = 'rijndael-256'; - private $_mbstring; - public function init($config) - { - $this->_mbstring=extension_loaded('mbstring'); - $this->getApplication()->setSecurityManager($this); - } - protected function generateRandomKey() - { - return sprintf('%08x%08x%08x%08x',mt_rand(),mt_rand(),mt_rand(),mt_rand()); - } - public function getValidationKey() - { - if(null === $this->_validationKey) { - if(null === ($this->_validationKey = $this->getApplication()->getGlobalState(self::STATE_VALIDATION_KEY))) { - $this->_validationKey = $this->generateRandomKey(); - $this->getApplication()->setGlobalState(self::STATE_VALIDATION_KEY, $this->_validationKey, null, true); - } - } - return $this->_validationKey; - } - public function setValidationKey($value) - { - if('' === $value) - throw new TInvalidDataValueException('securitymanager_validationkey_invalid'); - $this->_validationKey = $value; - } - public function getEncryptionKey() - { - if(null === $this->_encryptionKey) { - if(null === ($this->_encryptionKey = $this->getApplication()->getGlobalState(self::STATE_ENCRYPTION_KEY))) { - $this->_encryptionKey = $this->generateRandomKey(); - $this->getApplication()->setGlobalState(self::STATE_ENCRYPTION_KEY, $this->_encryptionKey, null, true); - } - } - return $this->_encryptionKey; - } - public function setEncryptionKey($value) - { - if('' === $value) - throw new TInvalidDataValueException('securitymanager_encryptionkey_invalid'); - $this->_encryptionKey = $value; - } - public function getValidation() - { - return $this->_hashAlgorithm; - } - public function getHashAlgorithm() - { - return $this->_hashAlgorithm; - } - public function setValidation($value) - { - $this->_hashAlgorithm = TPropertyValue::ensureEnum($value, 'TSecurityManagerValidationMode'); - } - public function setHashAlgorithm($value) - { - $this->_hashAlgorithm = TPropertyValue::ensureString($value); - } - public function getEncryption() - { - if(is_string($this->_cryptAlgorithm)) - return $this->_cryptAlgorithm; - return "3DES"; - } - public function setEncryption($value) - { - $this->_cryptAlgorithm = $value; - } - public function getCryptAlgorithm() - { - return $this->_cryptAlgorithm; - } - public function setCryptAlgorithm($value) - { - $this->_cryptAlgorithm = $value; - } - public function encrypt($data) - { - $module=$this->openCryptModule(); - $key = $this->substr(md5($this->getEncryptionKey()), 0, mcrypt_enc_get_key_size($module)); - srand(); - $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($module), MCRYPT_RAND); - mcrypt_generic_init($module, $key, $iv); - $encrypted = $iv.mcrypt_generic($module, $data); - mcrypt_generic_deinit($module); - mcrypt_module_close($module); - return $encrypted; - } - public function decrypt($data) - { - $module=$this->openCryptModule(); - $key = $this->substr(md5($this->getEncryptionKey()), 0, mcrypt_enc_get_key_size($module)); - $ivSize = mcrypt_enc_get_iv_size($module); - $iv = $this->substr($data, 0, $ivSize); - mcrypt_generic_init($module, $key, $iv); - $decrypted = mdecrypt_generic($module, $this->substr($data, $ivSize, $this->strlen($data))); - mcrypt_generic_deinit($module); - mcrypt_module_close($module); - return $decrypted; - } - protected function openCryptModule() - { - if(extension_loaded('mcrypt')) - { - if(is_array($this->_cryptAlgorithm)) - $module=@call_user_func_array('mcrypt_module_open',$this->_cryptAlgorithm); - else - $module=@mcrypt_module_open($this->_cryptAlgorithm,'', MCRYPT_MODE_CBC,''); - if($module===false) - throw new TNotSupportedException('securitymanager_mcryptextension_initfailed'); - return $module; - } - else - throw new TNotSupportedException('securitymanager_mcryptextension_required'); - } - public function hashData($data) - { - $hmac = $this->computeHMAC($data); - return $hmac.$data; - } - public function validateData($data) - { - $len=$this->strlen($this->computeHMAC('test')); - if($this->strlen($data) < $len) - return false; - $hmac = $this->substr($data, 0, $len); - $data2=$this->substr($data, $len, $this->strlen($data)); - return $hmac === $this->computeHMAC($data2) ? $data2 : false; - } - protected function computeHMAC($data) - { - $key = $this->getValidationKey(); - if(function_exists('hash_hmac')) - return hash_hmac($this->_hashAlgorithm, $data, $key); - if(!strcasecmp($this->_hashAlgorithm,'sha1')) - { - $pack = 'H40'; - $func = 'sha1'; - } else { - $pack = 'H32'; - $func = 'md5'; - } - $key = str_pad($func($key), 64, chr(0)); - return $func((str_repeat(chr(0x5C), 64) ^ substr($key, 0, 64)) . pack($pack, $func((str_repeat(chr(0x36), 64) ^ substr($key, 0, 64)) . $data))); - } - private function strlen($string) - { - return $this->_mbstring ? mb_strlen($string,'8bit') : strlen($string); - } - private function substr($string,$start,$length) - { - return $this->_mbstring ? mb_substr($string,$start,$length,'8bit') : substr($string,$start,$length); - } -} -class TSecurityManagerValidationMode extends TEnumerable -{ - const MD5 = 'MD5'; - const SHA1 = 'SHA1'; -} -class THttpUtility -{ - private static $_encodeTable=array('<'=>'<','>'=>'>','"'=>'"'); - private static $_decodeTable=array('<'=>'<','>'=>'>','"'=>'"'); - private static $_stripTable=array('<'=>'','>'=>'','"'=>''); - public static function htmlEncode($s) - { - return strtr($s,self::$_encodeTable); - } - public static function htmlDecode($s) - { - return strtr($s,self::$_decodeTable); - } - public static function htmlStrip($s) - { - return strtr($s,self::$_stripTable); - } -} -class TJavaScript -{ - public static function renderScriptFiles($files) - { - $str=''; - foreach($files as $file) - $str.= self::renderScriptFile($file); - return $str; - } - public static function renderScriptFile($file) - { - return '<script type="text/javascript" src="'.THttpUtility::htmlEncode($file)."\"></script>\n"; - } - public static function renderScriptBlocks($scripts) - { - if(count($scripts)) - return "<script type=\"text/javascript\">\n/*<![CDATA[*/\n".implode("\n",$scripts)."\n/*]]>*/\n</script>\n"; - else - return ''; - } - public static function renderScriptBlocksCallback($scripts) - { - if(count($scripts)) - return implode("\n",$scripts)."\n"; - else - return ''; - } - public static function renderScriptBlock($script) - { - return "<script type=\"text/javascript\">\n/*<![CDATA[*/\n{$script}\n/*]]>*/\n</script>\n"; - } - public static function quoteString($js) - { - return self::jsonEncode($js,JSON_HEX_QUOT | JSON_HEX_APOS | JSON_HEX_TAG); - } - public static function quoteJsLiteral($js) - { - if($js instanceof TJavaScriptLiteral) - return $js; - else - return new TJavaScriptLiteral($js); - } - public static function quoteFunction($js) - { - return self::quoteJsLiteral($js); - } - public static function isJsLiteral($js) - { - return ($js instanceof TJavaScriptLiteral); - } - public static function isFunction($js) - { - return self::isJsLiteral($js); - } - public static function encode($value,$toMap=true,$encodeEmptyStrings=false) - { - if(is_string($value)) - return self::quoteString($value); - else if(is_bool($value)) - return $value?'true':'false'; - else if(is_array($value)) - { - $results=''; - if(($n=count($value))>0 && array_keys($value)!==range(0,$n-1)) - { - foreach($value as $k=>$v) - { - if($v!=='' || $encodeEmptyStrings) - { - if($results!=='') - $results.=','; - $results.="'$k':".self::encode($v,$toMap,$encodeEmptyStrings); - } - } - return '{'.$results.'}'; - } - else - { - foreach($value as $v) - { - if($v!=='' || $encodeEmptyStrings) - { - if($results!=='') - $results.=','; - $results.=self::encode($v,$toMap, $encodeEmptyStrings); - } - } - return '['.$results.']'; - } - } - else if(is_integer($value)) - return "$value"; - else if(is_float($value)) - { - switch($value) - { - case -INF: - return 'Number.NEGATIVE_INFINITY'; - break; - case INF: - return 'Number.POSITIVE_INFINITY'; - break; - default: - $locale=localeConv(); - if($locale['decimal_point']=='.') - return "$value"; - else - return str_replace($locale['decimal_point'], '.', "$value"); - break; - } - } - else if(is_object($value)) - if ($value instanceof TJavaScriptLiteral) - return $value->toJavaScriptLiteral(); - else - return self::encode(get_object_vars($value),$toMap); - else if($value===null) - return 'null'; - else - return ''; - } - public static function jsonEncode($value, $options = 0) - { - if (is_string($value) && - ($g=Prado::getApplication()->getGlobalization(false))!==null && - strtoupper($enc=$g->getCharset())!='UTF-8') - $value=iconv($enc, 'UTF-8', $value); - $s = @json_encode($value,$options); - self::checkJsonError(); - return $s; - } - public static function jsonDecode($value, $assoc = false, $depth = 512) - { - $s= @json_decode($value, $assoc, $depth); - self::checkJsonError(); - return $s; - } - private static function checkJsonError() - { - switch ($err = json_last_error()) - { - case JSON_ERROR_NONE: - return; - break; - case JSON_ERROR_DEPTH: - $msg = 'Maximum stack depth exceeded'; - break; - case JSON_ERROR_STATE_MISMATCH: - $msg = 'Underflow or the modes mismatch'; - break; - case JSON_ERROR_CTRL_CHAR: - $msg = 'Unexpected control character found'; - break; - case JSON_ERROR_SYNTAX: - $msg = 'Syntax error, malformed JSON'; - break; - case JSON_ERROR_UTF8: - $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded'; - break; - default: - $msg = 'Unknown error'; - break; - } - throw new Exception("JSON error ($err): $msg"); - } - public static function JSMin($code) - { - Prado::using('System.Web.Javascripts.JSMin'); - return JSMin::minify($code); - } -} -class TUrlManager extends TModule -{ - public function constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems) - { - $url=$serviceID.'='.urlencode($serviceParam); - $amp=$encodeAmpersand?'&':'&'; - $request=$this->getRequest(); - if(is_array($getItems) || $getItems instanceof Traversable) - { - if($encodeGetItems) - { - foreach($getItems as $name=>$value) - { - if(is_array($value)) - { - $name=urlencode($name.'[]'); - foreach($value as $v) - $url.=$amp.$name.'='.urlencode($v); - } - else - $url.=$amp.urlencode($name).'='.urlencode($value); - } - } - else - { - foreach($getItems as $name=>$value) - { - if(is_array($value)) - { - foreach($value as $v) - $url.=$amp.$name.'[]='.$v; - } - else - $url.=$amp.$name.'='.$value; - } - } - } - switch($request->getUrlFormat()) - { - case THttpRequestUrlFormat::Path: - return $request->getApplicationUrl().'/'.strtr($url,array($amp=>'/','?'=>'/','='=>$request->getUrlParamSeparator())); - case THttpRequestUrlFormat::HiddenPath: - return rtrim(dirname($request->getApplicationUrl()), '/').'/'.strtr($url,array($amp=>'/','?'=>'/','='=>$request->getUrlParamSeparator())); - default: - return $request->getApplicationUrl().'?'.$url; - } - } - public function parseUrl() - { - $request=$this->getRequest(); - $pathInfo=trim($request->getPathInfo(),'/'); - if(($request->getUrlFormat()===THttpRequestUrlFormat::Path || - $request->getUrlFormat()===THttpRequestUrlFormat::HiddenPath) && - $pathInfo!=='') - { - $separator=$request->getUrlParamSeparator(); - $paths=explode('/',$pathInfo); - $getVariables=array(); - foreach($paths as $path) - { - if(($path=trim($path))!=='') - { - if(($pos=strpos($path,$separator))!==false) - { - $name=substr($path,0,$pos); - $value=substr($path,$pos+1); - if(($pos=strpos($name,'[]'))!==false) - $getVariables[substr($name,0,$pos)][]=$value; - else - $getVariables[$name]=$value; - } - else - $getVariables[$path]=''; - } - } - return $getVariables; - } - else - return array(); - } -} -class THttpRequest extends TApplicationComponent implements IteratorAggregate,ArrayAccess,Countable,IModule -{ - const CGIFIX__PATH_INFO = 1; - const CGIFIX__SCRIPT_NAME = 2; - private $_urlManager=null; - private $_urlManagerID=''; - private $_separator=','; - private $_serviceID=null; - private $_serviceParam=null; - private $_cookies=null; - private $_requestUri; - private $_pathInfo; - private $_cookieOnly=null; - private $_urlFormat=THttpRequestUrlFormat::Get; - private $_services; - private $_requestResolved=false; - private $_enableCookieValidation=false; - private $_cgiFix=0; - private $_enableCache=false; - private $_url=null; - private $_id; - private $_items=array(); - public function getID() - { - return $this->_id; - } - public function setID($value) - { - $this->_id=$value; - } - public function init($config) - { - if(php_sapi_name()==='cli') - { - $_SERVER['REMOTE_ADDR']='127.0.0.1'; - $_SERVER['REQUEST_METHOD']='GET'; - $_SERVER['SERVER_NAME']='localhost'; - $_SERVER['SERVER_PORT']=80; - $_SERVER['HTTP_USER_AGENT']=''; - } - if(isset($_SERVER['REQUEST_URI'])) - $this->_requestUri=$_SERVER['REQUEST_URI']; - else $this->_requestUri=$_SERVER['SCRIPT_NAME'].(empty($_SERVER['QUERY_STRING'])?'':'?'.$_SERVER['QUERY_STRING']); - if($this->_cgiFix&self::CGIFIX__PATH_INFO && isset($_SERVER['ORIG_PATH_INFO'])) - $this->_pathInfo=substr($_SERVER['ORIG_PATH_INFO'], strlen($_SERVER['SCRIPT_NAME'])); - elseif(isset($_SERVER['PATH_INFO'])) - $this->_pathInfo=$_SERVER['PATH_INFO']; - else if(strpos($_SERVER['PHP_SELF'],$_SERVER['SCRIPT_NAME'])===0 && $_SERVER['PHP_SELF']!==$_SERVER['SCRIPT_NAME']) - $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->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 setEnableCache($value) - { - $this->_enableCache = TPropertyValue::ensureBoolean($value); - } - public function getEnableCache() - { - return $this->_enableCache; - } - protected function getCacheKey() - { - return $this->getID(); - } - protected function cacheUrlManager($manager) - { - if($this->getEnableCache()) - { - $cache = $this->getApplication()->getCache(); - if($cache !== null) - { - $dependencies = null; - if($this->getApplication()->getMode() !== TApplicationMode::Performance) - if ($manager instanceof TUrlMapping && $fn = $manager->getConfigFile()) - { - $fn = Prado::getPathOfNamespace($fn,$this->getApplication()->getConfigurationFileExt()); - $dependencies = new TFileCacheDependency($fn); - } - return $cache->set($this->getCacheKey(), $manager, 0, $dependencies); - } - } - return false; - } - protected function loadCachedUrlManager() - { - if($this->getEnableCache()) - { - $cache = $this->getApplication()->getCache(); - if($cache !== null) - { - $manager = $cache->get($this->getCacheKey()); - if($manager instanceof TUrlManager) - return $manager; - } - } - return null; - } - public function getUrlManager() - { - return $this->_urlManagerID; - } - public function setUrlManager($value) - { - $this->_urlManagerID=$value; - } - public function getUrlManagerModule() - { - if($this->_urlManager===null) - { - if(($this->_urlManager = $this->loadCachedUrlManager())===null) - { - if(empty($this->_urlManagerID)) - { - $this->_urlManager=new TUrlManager; - $this->_urlManager->init(null); - } - else - { - $this->_urlManager=$this->getApplication()->getModule($this->_urlManagerID); - if($this->_urlManager===null) - throw new TConfigurationException('httprequest_urlmanager_inexist',$this->_urlManagerID); - if(!($this->_urlManager instanceof TUrlManager)) - throw new TConfigurationException('httprequest_urlmanager_invalid',$this->_urlManagerID); - } - $this->cacheUrlManager($this->_urlManager); - } - } - return $this->_urlManager; - } - public function getUrlFormat() - { - return $this->_urlFormat; - } - public function setUrlFormat($value) - { - $this->_urlFormat=TPropertyValue::ensureEnum($value,'THttpRequestUrlFormat'); - } - public function getUrlParamSeparator() - { - return $this->_separator; - } - public function setUrlParamSeparator($value) - { - if(strlen($value)===1) - $this->_separator=$value; - else - throw new TInvalidDataValueException('httprequest_separator_invalid'); - } - public function getRequestType() - { - return isset($_SERVER['REQUEST_METHOD'])?$_SERVER['REQUEST_METHOD']:null; - } - public function getContentType($mimetypeOnly = true) - { - if(!isset($_SERVER['CONTENT_TYPE'])) - return null; - if($mimetypeOnly === true && ($_pos = strpos(';', $_SERVER['CONTENT_TYPE'])) !== false) - return substr($_SERVER['CONTENT_TYPE'], 0, $_pos); - return $_SERVER['CONTENT_TYPE']; - } - public function getIsSecureConnection() - { - return isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'],'off'); - } - public function getPathInfo() - { - return $this->_pathInfo; - } - public function getQueryString() - { - return isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:null; - } - public function getHttpProtocolVersion() - { - return isset($_SERVER['SERVER_PROTOCOL'])?$_SERVER['SERVER_PROTOCOL']:null; - } - public function getHeaders($case=null) - { - static $result; - if($result === null && function_exists('apache_request_headers')) { - $result = apache_request_headers(); - } - elseif($result === null) { - $result = array(); - foreach($_SERVER as $key=>$value) { - if(strncasecmp($key, 'HTTP_', 5) !== 0) continue; - $key = str_replace(' ','-', ucwords(strtolower(str_replace('_',' ', substr($key, 5))))); - $result[$key] = $value; - } - } - if($case !== null) - return array_change_key_case($result, $case); - return $result; - } - public function getRequestUri() - { - return $this->_requestUri; - } - public function getBaseUrl($forceSecureConnection=null) - { - $url=$this->getUrl(); - $scheme=($forceSecureConnection)?"https": (($forceSecureConnection === null)?$url->getScheme():'http'); - $host=$url->getHost(); - if (($port=$url->getPort())) $host.=':'.$port; - return $scheme.'://'.$host; - } - public function getApplicationUrl() - { - if($this->_cgiFix&self::CGIFIX__SCRIPT_NAME && isset($_SERVER['ORIG_SCRIPT_NAME'])) - return $_SERVER['ORIG_SCRIPT_NAME']; - return isset($_SERVER['SCRIPT_NAME'])?$_SERVER['SCRIPT_NAME']:null; - } - public function getAbsoluteApplicationUrl($forceSecureConnection=null) - { - return $this->getBaseUrl($forceSecureConnection) . $this->getApplicationUrl(); - } - public function getApplicationFilePath() - { - return realpath(isset($_SERVER['SCRIPT_FILENAME'])?$_SERVER['SCRIPT_FILENAME']:null); - } - public function getServerName() - { - return isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:null; - } - public function getServerPort() - { - return isset($_SERVER['SERVER_PORT'])?$_SERVER['SERVER_PORT']:null; - } - public function getUrlReferrer() - { - return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null; - } - public function getBrowser() - { - try - { - return get_browser(); - } - catch(TPhpErrorException $e) - { - throw new TConfigurationException('httprequest_browscap_required'); - } - } - public function getUserAgent() - { - return isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:null; - } - public function getUserHostAddress() - { - return isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:null; - } - public function getUserHost() - { - return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null; - } - public function getAcceptTypes() - { - return isset($_SERVER['HTTP_ACCEPT'])?$_SERVER['HTTP_ACCEPT']:null; - } - public function getUserLanguages() - { - return Prado::getUserLanguages(); - } - public function getEnableCookieValidation() - { - return $this->_enableCookieValidation; - } - public function setEnableCookieValidation($value) - { - $this->_enableCookieValidation=TPropertyValue::ensureBoolean($value); - } - public function getCgiFix() - { - return $this->_cgiFix; - } - public function setCgiFix($value) - { - $this->_cgiFix=TPropertyValue::ensureInteger($value); - } - public function getCookies() - { - if($this->_cookies===null) - { - $this->_cookies=new THttpCookieCollection; - if($this->getEnableCookieValidation()) - { - $sm=$this->getApplication()->getSecurityManager(); - foreach($_COOKIE as $key=>$value) - { - if(($value=$sm->validateData($value))!==false) - $this->_cookies->add(new THttpCookie($key,$value)); - } - } - else - { - 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=true,$encodeGetItems=true) - { - if ($this->_cookieOnly===null) - $this->_cookieOnly=(int)ini_get('session.use_cookies') && (int)ini_get('session.use_only_cookies'); - $url=$this->getUrlManagerModule()->constructUrl($serviceID,$serviceParam,$getItems,$encodeAmpersand,$encodeGetItems); - if(defined('SID') && SID != '' && !$this->_cookieOnly) - return $url . (strpos($url,'?')===false? '?' : ($encodeAmpersand?'&':'&')) . SID; - else - return $url; - } - protected function parseUrl() - { - return $this->getUrlManagerModule()->parseUrl(); - } - public function resolveRequest($serviceIDs) - { - $getParams=$this->parseUrl(); - foreach($getParams as $name=>$value) - $_GET[$name]=$value; - $this->_items=array_merge($_GET,$_POST); - $this->_requestResolved=true; - foreach($serviceIDs as $serviceID) - { - if($this->contains($serviceID)) - { - $this->setServiceID($serviceID); - $this->setServiceParameter($this->itemAt($serviceID)); - return $serviceID; - } - } - return null; - } - public function getRequestResolved() - { - return $this->_requestResolved; - } - public function getServiceID() - { - return $this->_serviceID; - } - public function setServiceID($value) - { - $this->_serviceID=$value; - } - public function getServiceParameter() - { - return $this->_serviceParam; - } - public function setServiceParameter($value) - { - $this->_serviceParam=$value; - } - public function getIterator() - { - return new TMapIterator($this->_items); - } - public function getCount() - { - return count($this->_items); - } - public function count() - { - return $this->getCount(); - } - public function getKeys() - { - return array_keys($this->_items); - } - public function itemAt($key) - { - return isset($this->_items[$key]) ? $this->_items[$key] : null; - } - public function add($key,$value) - { - $this->_items[$key]=$value; - } - public function remove($key) - { - if(isset($this->_items[$key]) || array_key_exists($key,$this->_items)) - { - $value=$this->_items[$key]; - unset($this->_items[$key]); - return $value; - } - else - return null; - } - public function clear() - { - foreach(array_keys($this->_items) as $key) - $this->remove($key); - } - public function contains($key) - { - return isset($this->_items[$key]) || array_key_exists($key,$this->_items); - } - public function toArray() - { - return $this->_items; - } - public function offsetExists($offset) - { - return $this->contains($offset); - } - public function offsetGet($offset) - { - return $this->itemAt($offset); - } - public function offsetSet($offset,$item) - { - $this->add($offset,$item); - } - public function offsetUnset($offset) - { - $this->remove($offset); - } -} -class THttpCookieCollection extends TList -{ - private $_o; - public function __construct($owner=null) - { - $this->_o=$owner; - } - public function insertAt($index,$item) - { - if($item instanceof THttpCookie) - { - parent::insertAt($index,$item); - if($this->_o instanceof THttpResponse) - $this->_o->addCookie($item); - } - else - throw new TInvalidDataTypeException('httpcookiecollection_httpcookie_required'); - } - public function removeAt($index) - { - $item=parent::removeAt($index); - if($this->_o instanceof THttpResponse) - $this->_o->removeCookie($item); - return $item; - } - public function itemAt($index) - { - if(is_integer($index)) - return parent::itemAt($index); - else - return $this->findCookieByName($index); - } - public function findCookieByName($name) - { - foreach($this as $cookie) - if($cookie->getName()===$name) - return $cookie; - return null; - } -} -class THttpCookie extends TComponent -{ - private $_domain=''; - private $_name; - private $_value=''; - private $_expire=0; - private $_path='/'; - private $_secure=false; - private $_httpOnly=false; - public function __construct($name,$value) - { - $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 getHttpOnly() - { - return $this->_httpOnly; - } - public function setHttpOnly($value) - { - $this->_httpOnly = TPropertyValue::ensureBoolean($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) - { - if(($ret=@parse_url($uri))!==false) - { - $this->_scheme=isset($ret['scheme'])?$ret['scheme']:''; - $this->_host=isset($ret['host'])?$ret['host']:''; - $this->_port=isset($ret['port'])?$ret['port']:''; - $this->_user=isset($ret['user'])?$ret['user']:''; - $this->_pass=isset($ret['pass'])?$ret['pass']:''; - $this->_path=isset($ret['path'])?$ret['path']:''; - $this->_query=isset($ret['query'])?$ret['query']:''; - $this->_fragment=isset($ret['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; - } -} -class THttpRequestUrlFormat extends TEnumerable -{ - const Get='Get'; - const Path='Path'; - const HiddenPath='HiddenPath'; -} -class THttpResponseAdapter extends TApplicationComponent -{ - private $_response; - public function __construct($response) - { - $this->_response=$response; - } - public function getResponse() - { - return $this->_response; - } - public function flushContent() - { - $this->_response->flushContent(); - } - public function httpRedirect($url) - { - $this->_response->httpRedirect($url); - } - public function createNewHtmlWriter($type, $writer) - { - return $this->_response->createNewHtmlWriter($type,$writer); - } -} -class THttpResponse extends TModule implements ITextWriter -{ - const DEFAULT_CONTENTTYPE = 'text/html'; - const DEFAULT_CHARSET = 'UTF-8'; - private static $HTTP_STATUS_CODES = array( - 100 => 'Continue', 101 => 'Switching Protocols', - 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', - 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', - 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed', - 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported' - ); - private $_bufferOutput=true; - private $_initialized=false; - private $_cookies=null; - private $_status=200; - private $_reason='OK'; - private $_htmlWriterType='System.Web.UI.THtmlWriter'; - private $_contentType=null; - private $_charset=''; - private $_adapter; - private $_httpHeaderSent; - private $_contentTypeHeaderSent; - public function __destruct() - { - } - public function setAdapter(THttpResponseAdapter $adapter) - { - $this->_adapter=$adapter; - } - public function getAdapter() - { - return $this->_adapter; - } - public function getHasAdapter() - { - return $this->_adapter!==null; - } - 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) - { - if ($this->_contentTypeHeaderSent) - throw new Exception('Unable to alter content-type as it has been already sent'); - $this->_contentType = $type; - } - public function getContentType() - { - return $this->_contentType; - } - public function getCharset() - { - return $this->_charset; - } - public function setCharset($charset) - { - $this->_charset = (strToLower($charset) === 'false') ? false : (string)$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, $reason=null) - { - if ($this->_httpHeaderSent) - throw new Exception('Unable to alter response as HTTP header already sent'); - $status=TPropertyValue::ensureInteger($status); - if(isset(self::$HTTP_STATUS_CODES[$status])) { - $this->_reason=self::$HTTP_STATUS_CODES[$status]; - }else{ - if($reason===null || $reason==='') { - throw new TInvalidDataValueException("response_status_reason_missing"); - } - $reason=TPropertyValue::ensureString($reason); - if(strpos($reason, "\r")!=false || strpos($reason, "\n")!=false) { - throw new TInvalidDataValueException("response_status_reason_barchars"); - } - $this->_reason=$reason; - } - $this->_status=$status; - } - public function getStatusReason() { - return $this->_reason; - } - public function getCookies() - { - if($this->_cookies===null) - $this->_cookies=new THttpCookieCollection($this); - return $this->_cookies; - } - public function write($str) - { - if (!$this->_bufferOutput and !$this->_httpHeaderSent) - $this->ensureHeadersSent(); - echo $str; - } - public function writeFile($fileName,$content=null,$mimeType=null,$headers=null,$forceDownload=true,$clientFileName=null,$fileSize=null) - { - static $defaultMimeTypes=array( - 'css'=>'text/css', - 'gif'=>'image/gif', - 'png'=>'image/png', - 'jpg'=>'image/jpeg', - 'jpeg'=>'image/jpeg', - 'htm'=>'text/html', - 'html'=>'text/html', - 'js'=>'javascript/js', - 'pdf'=>'application/pdf', - 'xls'=>'application/vnd.ms-excel', - ); - if($mimeType===null) - { - $mimeType='text/plain'; - if(function_exists('mime_content_type')) - $mimeType=mime_content_type($fileName); - else if(($ext=strrchr($fileName,'.'))!==false) - { - $ext=substr($ext,1); - if(isset($defaultMimeTypes[$ext])) - $mimeType=$defaultMimeTypes[$ext]; - } - } - if($clientFileName===null) - $clientFileName=basename($fileName); - else - $clientFileName=basename($clientFileName); - if($fileSize===null || $fileSize < 0) - $fileSize = ($content===null?filesize($fileName):strlen($content)); - $this->sendHttpHeader(); - if(is_array($headers)) - { - foreach($headers as $h) - header($h); - } - else - { - header('Pragma: public'); - header('Expires: 0'); - header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); - header("Content-Type: $mimeType"); - $this->_contentTypeHeaderSent = true; - } - header('Content-Length: '.$fileSize); - header("Content-Disposition: " . ($forceDownload ? 'attachment' : 'inline') . "; filename=\"$clientFileName\""); - header('Content-Transfer-Encoding: binary'); - if($content===null) - readfile($fileName); - else - echo $content; - } - public function redirect($url) - { - if($this->getHasAdapter()) - $this->_adapter->httpRedirect($url); - else - $this->httpRedirect($url); - } - public function httpRedirect($url) - { - $this->ensureHeadersSent(); - if($url[0]==='/') - $url=$this->getRequest()->getBaseUrl().$url; - if ($this->_status >= 300 && $this->_status < 400) - header('Location: '.str_replace('&','&',$url), true, $this->_status); - else - header('Location: '.str_replace('&','&',$url)); - if(!$this->getApplication()->getRequestCompleted()) - $this->getApplication()->onEndRequest(); - exit(); - } - public function reload() - { - $this->redirect($this->getRequest()->getRequestUri()); - } - public function flush($continueBuffering = true) - { - if($this->getHasAdapter()) - $this->_adapter->flushContent($continueBuffering); - else - $this->flushContent($continueBuffering); - } - public function ensureHeadersSent() - { - $this->ensureHttpHeaderSent(); - $this->ensureContentTypeHeaderSent(); - } - public function flushContent($continueBuffering = true) - { - $this->ensureHeadersSent(); - if($this->_bufferOutput) - { - if (ob_get_length()>0) - { - if (!$continueBuffering) - { - $this->_bufferOutput = false; - ob_end_flush(); - } - else - ob_flush(); - flush(); - } - } - else - flush(); - } - protected function ensureHttpHeaderSent() - { - if (!$this->_httpHeaderSent) - $this->sendHttpHeader(); - } - protected function sendHttpHeader() - { - if (($version=$this->getRequest()->getHttpProtocolVersion())==='') - header (' ', true, $this->_status); - else - header($version.' '.$this->_status.' '.$this->_reason, true, $this->_status); - $this->_httpHeaderSent = true; - } - protected function ensureContentTypeHeaderSent() - { - if (!$this->_contentTypeHeaderSent) - $this->sendContentTypeHeader(); - } - protected function sendContentTypeHeader() - { - $contentType=$this->_contentType===null?self::DEFAULT_CONTENTTYPE:$this->_contentType; - $charset=$this->getCharset(); - if($charset === false) { - $this->appendHeader('Content-Type: '.$contentType); - return; - } - if($charset==='' && ($globalization=$this->getApplication()->getGlobalization(false))!==null) - $charset=$globalization->getCharset(); - if($charset==='') $charset = self::DEFAULT_CHARSET; - $this->appendHeader('Content-Type: '.$contentType.';charset='.$charset); - $this->_contentTypeHeaderSent = true; - } - public function getContents() - { - return $this->_bufferOutput?ob_get_contents():''; - } - public function clear() - { - if($this->_bufferOutput) - ob_clean(); - } - public function getHeaders($case=null) - { - $result = array(); - $headers = headers_list(); - foreach($headers as $header) { - $tmp = explode(':', $header); - $key = trim(array_shift($tmp)); - $value = trim(implode(':', $tmp)); - if(isset($result[$key])) - $result[$key] .= ', ' . $value; - else - $result[$key] = $value; - } - if($case !== null) - return array_change_key_case($result, $case); - return $result; - } - public function appendHeader($value, $replace=true) - { - header($value, $replace); - } - public function appendLog($message,$messageType=0,$destination='',$extraHeaders='') - { - error_log($message,$messageType,$destination,$extraHeaders); - } - public function addCookie($cookie) - { - $request=$this->getRequest(); - if($request->getEnableCookieValidation()) - { - $value=$this->getApplication()->getSecurityManager()->hashData($cookie->getValue()); - setcookie( - $cookie->getName(), - $value, - $cookie->getExpire(), - $cookie->getPath(), - $cookie->getDomain(), - $cookie->getSecure(), - $cookie->getHttpOnly() - ); - } - else { - setcookie( - $cookie->getName(), - $cookie->getValue(), - $cookie->getExpire(), - $cookie->getPath(), - $cookie->getDomain(), - $cookie->getSecure(), - $cookie->getHttpOnly() - ); - } - } - public function removeCookie($cookie) - { - setcookie( - $cookie->getName(), - null, - 0, - $cookie->getPath(), - $cookie->getDomain(), - $cookie->getSecure(), - $cookie->getHttpOnly() - ); - } - public function getHtmlWriterType() - { - return $this->_htmlWriterType; - } - public function setHtmlWriterType($value) - { - $this->_htmlWriterType=$value; - } - public function createHtmlWriter($type=null) - { - if($type===null) - $type=$this->getHtmlWriterType(); - if($this->getHasAdapter()) - return $this->_adapter->createNewHtmlWriter($type, $this); - else - return $this->createNewHtmlWriter($type, $this); - } - public function createNewHtmlWriter($type, $writer) - { - return Prado::createComponent($type, $writer); - } -} -class THttpSession extends TApplicationComponent implements IteratorAggregate,ArrayAccess,Countable,IModule -{ - private $_initialized=false; - private $_started=false; - private $_autoStart=false; - private $_cookie=null; - private $_id; - private $_customStorage=false; - public function getID() - { - return $this->_id; - } - public function setID($value) - { - $this->_id=$value; - } - public function init($config) - { - if($this->_autoStart) - $this->open(); - $this->_initialized=true; - $this->getApplication()->setSession($this); - register_shutdown_function(array($this, "close")); - } - public function open() - { - if(!$this->_started) - { - if($this->_customStorage) - session_set_save_handler(array($this,'_open'),array($this,'_close'),array($this,'_read'),array($this,'_write'),array($this,'_destroy'),array($this,'_gc')); - if($this->_cookie!==null) - session_set_cookie_params($this->_cookie->getExpire(),$this->_cookie->getPath(),$this->_cookie->getDomain(),$this->_cookie->getSecure()); - if(ini_get('session.auto_start')!=='1') - 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 regenerate($deleteOld=false) - { - $old = $this->getSessionID(); - session_regenerate_id($deleteOld); - return $old; - } - 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',$value); - } - 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 getUseCustomStorage() - { - return $this->_customStorage; - } - public function setUseCustomStorage($value) - { - $this->_customStorage=TPropertyValue::ensureBoolean($value); - } - 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 THttpSessionCookieMode::None; - else if(ini_get('session.use_only_cookies')==='0') - return THttpSessionCookieMode::Allow; - else - return THttpSessionCookieMode::Only; - } - public function setCookieMode($value) - { - if($this->_started) - throw new TInvalidOperationException('httpsession_cookiemode_unchangeable'); - else - { - $value=TPropertyValue::ensureEnum($value,'THttpSessionCookieMode'); - if($value===THttpSessionCookieMode::None) - ini_set('session.use_cookies','0'); - else if($value===THttpSessionCookieMode::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'); - ini_set('session.use_trans_sid', 0); - } - } - } - 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 - { - $value=TPropertyValue::ensureBoolean($value); - if ($value && $this->getCookieMode()==THttpSessionCookieMode::Only) - throw new TInvalidOperationException('httpsession_transid_cookieonly'); - ini_set('session.use_trans_sid',$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; - } - public function getIterator() - { - return new TSessionIterator; - } - public function getCount() - { - return count($_SESSION); - } - public function count() - { - return $this->getCount(); - } - public function getKeys() - { - return array_keys($_SESSION); - } - public function itemAt($key) - { - return isset($_SESSION[$key]) ? $_SESSION[$key] : null; - } - public function add($key,$value) - { - $_SESSION[$key]=$value; - } - public function remove($key) - { - if(isset($_SESSION[$key])) - { - $value=$_SESSION[$key]; - unset($_SESSION[$key]); - return $value; - } - else - return null; - } - public function clear() - { - foreach(array_keys($_SESSION) as $key) - unset($_SESSION[$key]); - } - public function contains($key) - { - return isset($_SESSION[$key]); - } - public function toArray() - { - return $_SESSION; - } - public function offsetExists($offset) - { - return isset($_SESSION[$offset]); - } - public function offsetGet($offset) - { - return isset($_SESSION[$offset]) ? $_SESSION[$offset] : null; - } - public function offsetSet($offset,$item) - { - $_SESSION[$offset]=$item; - } - public function offsetUnset($offset) - { - unset($_SESSION[$offset]); - } -} -class TSessionIterator implements Iterator -{ - private $_keys; - private $_key; - public function __construct() - { - $this->_keys=array_keys($_SESSION); - } - public function rewind() - { - $this->_key=reset($this->_keys); - } - public function key() - { - return $this->_key; - } - public function current() - { - return isset($_SESSION[$this->_key])?$_SESSION[$this->_key]:null; - } - public function next() - { - do - { - $this->_key=next($this->_keys); - } - while(!isset($_SESSION[$this->_key]) && $this->_key!==false); - } - public function valid() - { - return $this->_key!==false; - } -} -class THttpSessionCookieMode extends TEnumerable -{ - const None='None'; - const Allow='Allow'; - const Only='Only'; -} -Prado::using('System.Web.UI.WebControls.*'); -class TAttributeCollection extends TMap -{ - private $_caseSensitive=false; - public function __get($name) - { - return $this->contains($name)?$this->itemAt($name):parent::__get($name); - } - public function __set($name,$value) - { - $this->add($name,$value); - } - public function getCaseSensitive() - { - return $this->_caseSensitive; - } - public function setCaseSensitive($value) - { - $this->_caseSensitive=TPropertyValue::ensureBoolean($value); - } - public function itemAt($key) - { - return parent::itemAt($this->_caseSensitive?$key:strtolower($key)); - } - public function add($key,$value) - { - parent::add($this->_caseSensitive?$key:strtolower($key),$value); - } - public function remove($key) - { - return parent::remove($this->_caseSensitive?$key:strtolower($key)); - } - public function contains($key) - { - return parent::contains($this->_caseSensitive?$key:strtolower($key)); - } - public function hasProperty($name) - { - return $this->contains($name) || parent::canGetProperty($name) || parent::canSetProperty($name); - } - public function canGetProperty($name) - { - return $this->contains($name) || parent::canGetProperty($name); - } - public function canSetProperty($name) - { - return true; - } -} -class TControlAdapter extends TApplicationComponent -{ - protected $_control; - public function __construct($control) - { - $this->_control=$control; - } - public function getControl() - { - return $this->_control; - } - public function getPage() - { - return $this->_control?$this->_control->getPage():null; - } - public function createChildControls() - { - $this->_control->createChildControls(); - } - public function loadState() - { - $this->_control->loadState(); - } - public function saveState() - { - $this->_control->saveState(); - } - public function onInit($param) - { - $this->_control->onInit($param); - } - public function onLoad($param) - { - $this->_control->onLoad($param); - } - public function onPreRender($param) - { - $this->_control->onPreRender($param); - } - public function onUnload($param) - { - $this->_control->onUnload($param); - } - public function render($writer) - { - $this->_control->render($writer); - } - public function renderChildren($writer) - { - $this->_control->renderChildren($writer); - } -} -class TControl extends TApplicationComponent implements IRenderable, IBindable -{ - const ID_FORMAT='/^[a-zA-Z_]\\w*$/'; - const ID_SEPARATOR='$'; - const CLIENT_ID_SEPARATOR='_'; - const AUTOMATIC_ID_PREFIX='ctl'; - const CS_CONSTRUCTED=0; - const CS_CHILD_INITIALIZED=1; - const CS_INITIALIZED=2; - const CS_STATE_LOADED=3; - const CS_LOADED=4; - const CS_PRERENDERED=5; - const IS_ID_SET=0x01; - const IS_DISABLE_VIEWSTATE=0x02; - const IS_SKIN_APPLIED=0x04; - const IS_STYLESHEET_APPLIED=0x08; - const IS_DISABLE_THEMING=0x10; - const IS_CHILD_CREATED=0x20; - const IS_CREATING_CHILD=0x40; - const RF_CONTROLS=0; const RF_CHILD_STATE=1; const RF_NAMED_CONTROLS=2; const RF_NAMED_CONTROLS_ID=3; const RF_SKIN_ID=4; const RF_DATA_BINDINGS=5; const RF_EVENTS=6; const RF_CONTROLSTATE=7; const RF_NAMED_OBJECTS=8; const RF_ADAPTER=9; const RF_AUTO_BINDINGS=10; - private $_id=''; - private $_uid; - private $_parent; - private $_page; - private $_namingContainer; - private $_tplControl; - private $_viewState=array(); - private $_tempState=array(); - private $_trackViewState=true; - private $_stage=0; - private $_flags=0; - private $_rf=array(); - public function __construct() - { - } - public function __get($name) - { - if(isset($this->_rf[self::RF_NAMED_OBJECTS][$name])) - return $this->_rf[self::RF_NAMED_OBJECTS][$name]; - else - return parent::__get($name); - } - public function getHasAdapter() - { - return isset($this->_rf[self::RF_ADAPTER]); - } - public function getAdapter() - { - return isset($this->_rf[self::RF_ADAPTER])?$this->_rf[self::RF_ADAPTER]:null; - } - public function setAdapter(TControlAdapter $adapter) - { - $this->_rf[self::RF_ADAPTER]=$adapter; - } - public function getParent() - { - return $this->_parent; - } - public function getNamingContainer() - { - if(!$this->_namingContainer && $this->_parent) - { - if($this->_parent instanceof INamingContainer) - $this->_namingContainer=$this->_parent; - else - $this->_namingContainer=$this->_parent->getNamingContainer(); - } - return $this->_namingContainer; - } - public function getPage() - { - if(!$this->_page) - { - if($this->_parent) - $this->_page=$this->_parent->getPage(); - else if($this->_tplControl) - $this->_page=$this->_tplControl->getPage(); - } - return $this->_page; - } - public function setPage($page) - { - $this->_page=$page; - } - public function setTemplateControl($control) - { - $this->_tplControl=$control; - } - public function getTemplateControl() - { - if(!$this->_tplControl && $this->_parent) - $this->_tplControl=$this->_parent->getTemplateControl(); - return $this->_tplControl; - } - public function getSourceTemplateControl() - { - $control=$this; - while(($control instanceof TControl) && ($control=$control->getTemplateControl())!==null) - { - if(($control instanceof TTemplateControl) && $control->getIsSourceTemplateControl()) - return $control; - } - return $this->getPage(); - } - protected function getControlStage() - { - return $this->_stage; - } - protected function setControlStage($value) - { - $this->_stage=$value; - } - public function getID($hideAutoID=true) - { - if($hideAutoID) - return ($this->_flags & self::IS_ID_SET) ? $this->_id : ''; - else - return $this->_id; - } - public function setID($id) - { - if(!preg_match(self::ID_FORMAT,$id)) - throw new TInvalidDataValueException('control_id_invalid',get_class($this),$id); - $this->_id=$id; - $this->_flags |= self::IS_ID_SET; - $this->clearCachedUniqueID($this instanceof INamingContainer); - if($this->_namingContainer) - $this->_namingContainer->clearNameTable(); - } - public function getUniqueID() - { - if($this->_uid==='' || $this->_uid===null) { - $this->_uid=''; if($namingContainer=$this->getNamingContainer()) - { - if($this->getPage()===$namingContainer) - return ($this->_uid=$this->_id); - else if(($prefix=$namingContainer->getUniqueID())==='') - return $this->_id; - else - return ($this->_uid=$prefix.self::ID_SEPARATOR.$this->_id); - } - else return $this->_id; - } - else - return $this->_uid; - } - public function focus() - { - $this->getPage()->setFocus($this); - } - public function getClientID() - { - return strtr($this->getUniqueID(),self::ID_SEPARATOR,self::CLIENT_ID_SEPARATOR); - } - public static function convertUniqueIdToClientId($uniqueID) - { - return strtr($uniqueID,self::ID_SEPARATOR,self::CLIENT_ID_SEPARATOR); - } - public function getSkinID() - { - return isset($this->_rf[self::RF_SKIN_ID])?$this->_rf[self::RF_SKIN_ID]:''; - } - public function setSkinID($value) - { - if(($this->_flags & self::IS_SKIN_APPLIED) || $this->_stage>=self::CS_CHILD_INITIALIZED) - throw new TInvalidOperationException('control_skinid_unchangeable',get_class($this)); - else - $this->_rf[self::RF_SKIN_ID]=$value; - } - public function getIsSkinApplied() - { - return ($this->_flags & self::IS_SKIN_APPLIED); - } - public function getEnableTheming() - { - if($this->_flags & self::IS_DISABLE_THEMING) - return false; - else - return $this->_parent?$this->_parent->getEnableTheming():true; - } - public function setEnableTheming($value) - { - if($this->_stage>=self::CS_CHILD_INITIALIZED) - throw new TInvalidOperationException('control_enabletheming_unchangeable',get_class($this),$this->getUniqueID()); - else if(TPropertyValue::ensureBoolean($value)) - $this->_flags &= ~self::IS_DISABLE_THEMING; - else - $this->_flags |= self::IS_DISABLE_THEMING; - } - public function getCustomData() - { - return $this->getViewState('CustomData',null); - } - public function setCustomData($value) - { - $this->setViewState('CustomData',$value,null); - } - public function getHasControls() - { - return isset($this->_rf[self::RF_CONTROLS]) && $this->_rf[self::RF_CONTROLS]->getCount()>0; - } - public function getControls() - { - if(!isset($this->_rf[self::RF_CONTROLS])) - $this->_rf[self::RF_CONTROLS]=$this->createControlCollection(); - return $this->_rf[self::RF_CONTROLS]; - } - protected function createControlCollection() - { - return $this->getAllowChildControls()?new TControlCollection($this):new TEmptyControlCollection($this); - } - public function getVisible($checkParents=true) - { - if($checkParents) - { - for($control=$this;$control;$control=$control->_parent) - if(!$control->getVisible(false)) - return false; - return true; - } - else - return $this->getViewState('Visible',true); - } - public function setVisible($value) - { - $this->setViewState('Visible',TPropertyValue::ensureBoolean($value),true); - } - public function getEnabled($checkParents=false) - { - if($checkParents) - { - for($control=$this;$control;$control=$control->_parent) - if(!$control->getViewState('Enabled',true)) - return false; - return true; - } - else - return $this->getViewState('Enabled',true); - } - public function setEnabled($value) - { - $this->setViewState('Enabled',TPropertyValue::ensureBoolean($value),true); - } - public function getHasAttributes() - { - if($attributes=$this->getViewState('Attributes',null)) - return $attributes->getCount()>0; - else - return false; - } - public function getAttributes() - { - if($attributes=$this->getViewState('Attributes',null)) - return $attributes; - else - { - $attributes=new TAttributeCollection; - $this->setViewState('Attributes',$attributes,null); - return $attributes; - } - } - public function hasAttribute($name) - { - if($attributes=$this->getViewState('Attributes',null)) - return $attributes->contains($name); - else - return false; - } - public function getAttribute($name) - { - if($attributes=$this->getViewState('Attributes',null)) - return $attributes->itemAt($name); - else - return null; - } - public function setAttribute($name,$value) - { - $this->getAttributes()->add($name,$value); - } - public function removeAttribute($name) - { - if($attributes=$this->getViewState('Attributes',null)) - return $attributes->remove($name); - else - return null; - } - public function getEnableViewState($checkParents=false) - { - if($checkParents) - { - for($control=$this;$control!==null;$control=$control->getParent()) - if($control->_flags & self::IS_DISABLE_VIEWSTATE) - return false; - return true; - } - else - return !($this->_flags & self::IS_DISABLE_VIEWSTATE); - } - public function setEnableViewState($value) - { - if(TPropertyValue::ensureBoolean($value)) - $this->_flags &= ~self::IS_DISABLE_VIEWSTATE; - else - $this->_flags |= self::IS_DISABLE_VIEWSTATE; - } - protected function getControlState($key,$defaultValue=null) - { - return isset($this->_rf[self::RF_CONTROLSTATE][$key])?$this->_rf[self::RF_CONTROLSTATE][$key]:$defaultValue; - } - protected function setControlState($key,$value,$defaultValue=null) - { - if($value===$defaultValue) - unset($this->_rf[self::RF_CONTROLSTATE][$key]); - else - $this->_rf[self::RF_CONTROLSTATE][$key]=$value; - } - protected function clearControlState($key) - { - unset($this->_rf[self::RF_CONTROLSTATE][$key]); - } - public function trackViewState($enabled) - { - $this->_trackViewState=TPropertyValue::ensureBoolean($enabled); - } - public function getViewState($key,$defaultValue=null) - { - if(isset($this->_viewState[$key])) - return $this->_viewState[$key]!==null?$this->_viewState[$key]:$defaultValue; - else if(isset($this->_tempState[$key])) - { - if(is_object($this->_tempState[$key]) && $this->_trackViewState) - $this->_viewState[$key]=$this->_tempState[$key]; - return $this->_tempState[$key]; - } - else - return $defaultValue; - } - public function setViewState($key,$value,$defaultValue=null) - { - if($this->_trackViewState) - { - $this->_viewState[$key]=$value; - unset($this->_tempState[$key]); - } - else - { - unset($this->_viewState[$key]); - $this->_tempState[$key]=$value; - } - } - public function clearViewState($key) - { - unset($this->_viewState[$key]); - unset($this->_tempState[$key]); - } - public function bindProperty($name,$expression) - { - $this->_rf[self::RF_DATA_BINDINGS][$name]=$expression; - } - public function unbindProperty($name) - { - unset($this->_rf[self::RF_DATA_BINDINGS][$name]); - } - public function autoBindProperty($name,$expression) - { - $this->_rf[self::RF_AUTO_BINDINGS][$name]=$expression; - } - public function dataBind() - { - $this->dataBindProperties(); - $this->onDataBinding(null); - $this->dataBindChildren(); - } - protected function dataBindProperties() - { - if(isset($this->_rf[self::RF_DATA_BINDINGS])) - { - if(($context=$this->getTemplateControl())===null) - $context=$this; - foreach($this->_rf[self::RF_DATA_BINDINGS] as $property=>$expression) - $this->setSubProperty($property,$context->evaluateExpression($expression)); - } - } - protected function autoDataBindProperties() - { - if(isset($this->_rf[self::RF_AUTO_BINDINGS])) - { - if(($context=$this->getTemplateControl())===null) - $context=$this; - foreach($this->_rf[self::RF_AUTO_BINDINGS] as $property=>$expression) - $this->setSubProperty($property,$context->evaluateExpression($expression)); - } - } - protected function dataBindChildren() - { - if(isset($this->_rf[self::RF_CONTROLS])) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - if($control instanceof IBindable) - $control->dataBind(); - } - } - final protected function getChildControlsCreated() - { - return ($this->_flags & self::IS_CHILD_CREATED)!==0; - } - final protected function setChildControlsCreated($value) - { - if($value) - $this->_flags |= self::IS_CHILD_CREATED; - else - { - if($this->getHasControls() && ($this->_flags & self::IS_CHILD_CREATED)) - $this->getControls()->clear(); - $this->_flags &= ~self::IS_CHILD_CREATED; - } - } - public function ensureChildControls() - { - if(!($this->_flags & self::IS_CHILD_CREATED) && !($this->_flags & self::IS_CREATING_CHILD)) - { - try - { - $this->_flags |= self::IS_CREATING_CHILD; - if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->createChildControls(); - else - $this->createChildControls(); - $this->_flags &= ~self::IS_CREATING_CHILD; - $this->_flags |= self::IS_CHILD_CREATED; - } - catch(Exception $e) - { - $this->_flags &= ~self::IS_CREATING_CHILD; - $this->_flags |= self::IS_CHILD_CREATED; - throw $e; - } - } - } - public function createChildControls() - { - } - public function findControl($id) - { - $id=strtr($id,'.',self::ID_SEPARATOR); - $container=($this instanceof INamingContainer)?$this:$this->getNamingContainer(); - if(!$container || !$container->getHasControls()) - return null; - if(!isset($container->_rf[self::RF_NAMED_CONTROLS])) - { - $container->_rf[self::RF_NAMED_CONTROLS]=array(); - $container->fillNameTable($container,$container->_rf[self::RF_CONTROLS]); - } - if(($pos=strpos($id,self::ID_SEPARATOR))===false) - return isset($container->_rf[self::RF_NAMED_CONTROLS][$id])?$container->_rf[self::RF_NAMED_CONTROLS][$id]:null; - else - { - $cid=substr($id,0,$pos); - $sid=substr($id,$pos+1); - if(isset($container->_rf[self::RF_NAMED_CONTROLS][$cid])) - return $container->_rf[self::RF_NAMED_CONTROLS][$cid]->findControl($sid); - else - return null; - } - } - public function findControlsByType($type,$strict=true) - { - $controls=array(); - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if(is_object($control) && (get_class($control)===$type || (!$strict && ($control instanceof $type)))) - $controls[]=$control; - if(($control instanceof TControl) && $control->getHasControls()) - $controls=array_merge($controls,$control->findControlsByType($type,$strict)); - } - } - return $controls; - } - public function findControlsByID($id) - { - $controls=array(); - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if($control instanceof TControl) - { - if($control->_id===$id) - $controls[]=$control; - $controls=array_merge($controls,$control->findControlsByID($id)); - } - } - } - return $controls; - } - public function clearNamingContainer() - { - unset($this->_rf[self::RF_NAMED_CONTROLS_ID]); - $this->clearNameTable(); - } - public function registerObject($name,$object) - { - if(isset($this->_rf[self::RF_NAMED_OBJECTS][$name])) - throw new TInvalidOperationException('control_object_reregistered',$name); - $this->_rf[self::RF_NAMED_OBJECTS][$name]=$object; - } - public function unregisterObject($name) - { - unset($this->_rf[self::RF_NAMED_OBJECTS][$name]); - } - public function isObjectRegistered($name) - { - return isset($this->_rf[self::RF_NAMED_OBJECTS][$name]); - } - public function getHasChildInitialized() - { - return $this->getControlStage() >= self::CS_CHILD_INITIALIZED; - } - public function getHasInitialized() - { - return $this->getControlStage() >= self::CS_INITIALIZED; - } - public function getHasLoadedPostData() - { - return $this->getControlStage() >= self::CS_STATE_LOADED; - } - public function getHasLoaded() - { - return $this->getControlStage() >= self::CS_LOADED; - } - public function getHasPreRendered() - { - return $this->getControlStage() >= self::CS_PRERENDERED; - } - public function getRegisteredObject($name) - { - return isset($this->_rf[self::RF_NAMED_OBJECTS][$name])?$this->_rf[self::RF_NAMED_OBJECTS][$name]:null; - } - public function getAllowChildControls() - { - return true; - } - public function addParsedObject($object) - { - $this->getControls()->add($object); - } - final protected function clearChildState() - { - unset($this->_rf[self::RF_CHILD_STATE]); - } - final protected function isDescendentOf($ancestor) - { - $control=$this; - while($control!==$ancestor && $control->_parent) - $control=$control->_parent; - return $control===$ancestor; - } - public function addedControl($control) - { - if($control->_parent) - $control->_parent->getControls()->remove($control); - $control->_parent=$this; - $control->_page=$this->getPage(); - $namingContainer=($this instanceof INamingContainer)?$this:$this->_namingContainer; - if($namingContainer) - { - $control->_namingContainer=$namingContainer; - if($control->_id==='') - $control->generateAutomaticID(); - else - $namingContainer->clearNameTable(); - $control->clearCachedUniqueID($control instanceof INamingContainer); - } - if($this->_stage>=self::CS_CHILD_INITIALIZED) - { - $control->initRecursive($namingContainer); - if($this->_stage>=self::CS_STATE_LOADED) - { - if(isset($this->_rf[self::RF_CHILD_STATE][$control->_id])) - { - $state=$this->_rf[self::RF_CHILD_STATE][$control->_id]; - unset($this->_rf[self::RF_CHILD_STATE][$control->_id]); - } - else - $state=null; - $control->loadStateRecursive($state,!($this->_flags & self::IS_DISABLE_VIEWSTATE)); - if($this->_stage>=self::CS_LOADED) - { - $control->loadRecursive(); - if($this->_stage>=self::CS_PRERENDERED) - $control->preRenderRecursive(); - } - } - } - } - public function removedControl($control) - { - if($this->_namingContainer) - $this->_namingContainer->clearNameTable(); - $control->unloadRecursive(); - $control->_parent=null; - $control->_page=null; - $control->_namingContainer=null; - $control->_tplControl=null; - if(!($control->_flags & self::IS_ID_SET)) - $control->_id=''; - else - unset($this->_rf[self::RF_NAMED_OBJECTS][$control->_id]); - $control->clearCachedUniqueID(true); - } - protected function initRecursive($namingContainer=null) - { - $this->ensureChildControls(); - if($this->getHasControls()) - { - if($this instanceof INamingContainer) - $namingContainer=$this; - $page=$this->getPage(); - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if($control instanceof TControl) - { - $control->_namingContainer=$namingContainer; - $control->_page=$page; - if($control->_id==='' && $namingContainer) - $control->generateAutomaticID(); - $control->initRecursive($namingContainer); - } - } - } - if($this->_stage<self::CS_INITIALIZED) - { - $this->_stage=self::CS_CHILD_INITIALIZED; - if(($page=$this->getPage()) && $this->getEnableTheming() && !($this->_flags & self::IS_SKIN_APPLIED)) - { - $page->applyControlSkin($this); - $this->_flags |= self::IS_SKIN_APPLIED; - } - if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->onInit(null); - else - $this->onInit(null); - $this->_stage=self::CS_INITIALIZED; - } - } - protected function loadRecursive() - { - if($this->_stage<self::CS_LOADED) - { - if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->onLoad(null); - else - $this->onLoad(null); - } - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if($control instanceof TControl) - $control->loadRecursive(); - } - } - if($this->_stage<self::CS_LOADED) - $this->_stage=self::CS_LOADED; - } - protected function preRenderRecursive() - { - $this->autoDataBindProperties(); - if($this->getVisible(false)) - { - if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->onPreRender(null); - else - $this->onPreRender(null); - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if($control instanceof TControl) - $control->preRenderRecursive(); - else if($control instanceof TCompositeLiteral) - $control->evaluateDynamicContent(); - } - } - } - $this->_stage=self::CS_PRERENDERED; - } - protected function unloadRecursive() - { - if(!($this->_flags & self::IS_ID_SET)) - $this->_id=''; - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - if($control instanceof TControl) - $control->unloadRecursive(); - } - if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->onUnload(null); - else - $this->onUnload(null); - } - public function onInit($param) - { - $this->raiseEvent('OnInit',$this,$param); - } - public function onLoad($param) - { - $this->raiseEvent('OnLoad',$this,$param); - } - public function onDataBinding($param) - { - $this->raiseEvent('OnDataBinding',$this,$param); - } - public function onUnload($param) - { - $this->raiseEvent('OnUnload',$this,$param); - } - public function onPreRender($param) - { - $this->raiseEvent('OnPreRender',$this,$param); - } - protected function raiseBubbleEvent($sender,$param) - { - $control=$this; - while($control=$control->_parent) - { - if($control->bubbleEvent($sender,$param)) - break; - } - } - public function bubbleEvent($sender,$param) - { - return false; - } - public function broadcastEvent($name,$sender,$param) - { - $rootControl=(($page=$this->getPage())===null)?$this:$page; - $rootControl->broadcastEventInternal($name,$sender,new TBroadcastEventParameter($name,$param)); - } - private function broadcastEventInternal($name,$sender,$param) - { - if($this->hasEvent($name)) - $this->raiseEvent($name,$sender,$param->getParameter()); - if($this instanceof IBroadcastEventReceiver) - $this->broadcastEventReceived($sender,$param); - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if($control instanceof TControl) - $control->broadcastEventInternal($name,$sender,$param); - } - } - } - protected function traverseChildControls($param,$preCallback=null,$postCallback=null) - { - if($preCallback!==null) - call_user_func($preCallback,$this,$param); - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if($control instanceof TControl) - { - $control->traverseChildControls($param,$preCallback,$postCallback); - } - } - } - if($postCallback!==null) - call_user_func($postCallback,$this,$param); - } - public function renderControl($writer) - { - if($this instanceof IActiveControl || $this->getVisible(false)) - { - if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->render($writer); - else - $this->render($writer); - } - } - public function render($writer) - { - $this->renderChildren($writer); - } - public function renderChildren($writer) - { - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if(is_string($control)) - $writer->write($control); - else if($control instanceof TControl) - $control->renderControl($writer); - else if($control instanceof IRenderable) - $control->render($writer); - } - } - } - public function saveState() - { - } - public function loadState() - { - } - protected function loadStateRecursive(&$state,$needViewState=true) - { - if(is_array($state)) - { - $needViewState=($needViewState && !($this->_flags & self::IS_DISABLE_VIEWSTATE)); - if(isset($state[1])) - { - $this->_rf[self::RF_CONTROLSTATE]=&$state[1]; - unset($state[1]); - } - else - unset($this->_rf[self::RF_CONTROLSTATE]); - if($needViewState) - { - if(isset($state[0])) - $this->_viewState=&$state[0]; - else - $this->_viewState=array(); - } - unset($state[0]); - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if($control instanceof TControl) - { - if(isset($state[$control->_id])) - { - $control->loadStateRecursive($state[$control->_id],$needViewState); - unset($state[$control->_id]); - } - } - } - } - if(!empty($state)) - $this->_rf[self::RF_CHILD_STATE]=&$state; - } - $this->_stage=self::CS_STATE_LOADED; - if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->loadState(); - else - $this->loadState(); - } - protected function &saveStateRecursive($needViewState=true) - { - if(isset($this->_rf[self::RF_ADAPTER])) - $this->_rf[self::RF_ADAPTER]->saveState(); - else - $this->saveState(); - $needViewState=($needViewState && !($this->_flags & self::IS_DISABLE_VIEWSTATE)); - $state=array(); - if($this->getHasControls()) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - { - if($control instanceof TControl) - $state[$control->_id]=&$control->saveStateRecursive($needViewState); - } - } - if($needViewState && !empty($this->_viewState)) - $state[0]=&$this->_viewState; - if(isset($this->_rf[self::RF_CONTROLSTATE])) - $state[1]=&$this->_rf[self::RF_CONTROLSTATE]; - return $state; - } - public function applyStyleSheetSkin($page) - { - if($page && !($this->_flags & self::IS_STYLESHEET_APPLIED)) - { - $page->applyControlStyleSheet($this); - $this->_flags |= self::IS_STYLESHEET_APPLIED; - } - else if($this->_flags & self::IS_STYLESHEET_APPLIED) - throw new TInvalidOperationException('control_stylesheet_applied',get_class($this)); - } - private function clearCachedUniqueID($recursive) - { - if($recursive && $this->_uid!==null && isset($this->_rf[self::RF_CONTROLS])) - { - foreach($this->_rf[self::RF_CONTROLS] as $control) - if($control instanceof TControl) - $control->clearCachedUniqueID($recursive); - } - $this->_uid=null; - } - private function generateAutomaticID() - { - $this->_flags &= ~self::IS_ID_SET; - if(!isset($this->_namingContainer->_rf[self::RF_NAMED_CONTROLS_ID])) - $this->_namingContainer->_rf[self::RF_NAMED_CONTROLS_ID]=0; - $id=$this->_namingContainer->_rf[self::RF_NAMED_CONTROLS_ID]++; - $this->_id=self::AUTOMATIC_ID_PREFIX . $id; - $this->_namingContainer->clearNameTable(); - } - private function clearNameTable() - { - unset($this->_rf[self::RF_NAMED_CONTROLS]); - } - private function fillNameTable($container,$controls) - { - foreach($controls as $control) - { - if($control instanceof TControl) - { - if($control->_id!=='') - { - if(isset($container->_rf[self::RF_NAMED_CONTROLS][$control->_id])) - throw new TInvalidDataValueException('control_id_nonunique',get_class($control),$control->_id); - else - $container->_rf[self::RF_NAMED_CONTROLS][$control->_id]=$control; - } - if(!($control instanceof INamingContainer) && $control->getHasControls()) - $this->fillNameTable($container,$control->_rf[self::RF_CONTROLS]); - } - } - } -} -class TControlCollection extends TList -{ - private $_o; - public function __construct(TControl $owner,$readOnly=false) - { - $this->_o=$owner; - parent::__construct(null,$readOnly); - } - protected function getOwner() - { - return $this->_o; - } - public function insertAt($index,$item) - { - if($item instanceof TControl) - { - parent::insertAt($index,$item); - $this->_o->addedControl($item); - } - else if(is_string($item) || ($item instanceof IRenderable)) - parent::insertAt($index,$item); - else - throw new TInvalidDataTypeException('controlcollection_control_required'); - } - public function removeAt($index) - { - $item=parent::removeAt($index); - if($item instanceof TControl) - $this->_o->removedControl($item); - return $item; - } - public function clear() - { - parent::clear(); - if($this->_o instanceof INamingContainer) - $this->_o->clearNamingContainer(); - } -} -class TEmptyControlCollection extends TControlCollection -{ - public function __construct(TControl $owner) - { - parent::__construct($owner,true); - } - public function insertAt($index,$item) - { - if(!is_string($item)) parent::insertAt($index,$item); } -} -interface INamingContainer -{ -} -interface IPostBackEventHandler -{ - public function raisePostBackEvent($param); -} -interface IPostBackDataHandler -{ - public function loadPostData($key,$values); - public function raisePostDataChangedEvent(); - public function getDataChanged(); -} -interface IValidator -{ - public function validate(); - public function getIsValid(); - public function setIsValid($value); - public function getErrorMessage(); - public function setErrorMessage($value); -} -interface IValidatable -{ - public function getValidationPropertyValue(); - public function getIsValid(); - public function setIsValid($value); -} -interface IBroadcastEventReceiver -{ - public function broadcastEventReceived($sender,$param); -} -interface ITheme -{ - public function applySkin($control); -} -interface ITemplate -{ - public function instantiateIn($parent); -} -interface IButtonControl -{ - public function getText(); - public function setText($value); - public function getCausesValidation(); - public function setCausesValidation($value); - public function getCommandName(); - public function setCommandName($value); - public function getCommandParameter(); - public function setCommandParameter($value); - public function getValidationGroup(); - public function setValidationGroup($value); - public function onClick($param); - public function onCommand($param); - public function setIsDefaultButton($value); - public function getIsDefaultButton(); -} -interface ISurroundable -{ - public function getSurroundingTagID(); -} -class TBroadcastEventParameter extends TEventParameter -{ - private $_name; - private $_param; - public function __construct($name='',$parameter=null) - { - $this->_name=$name; - $this->_param=$parameter; - } - public function getName() - { - return $this->_name; - } - public function setName($value) - { - $this->_name=$value; - } - public function getParameter() - { - return $this->_param; - } - public function setParameter($value) - { - $this->_param=$value; - } -} -class TCommandEventParameter extends TEventParameter -{ - private $_name; - private $_param; - public function __construct($name='',$parameter='') - { - $this->_name=$name; - $this->_param=$parameter; - } - public function getCommandName() - { - return $this->_name; - } - public function getCommandParameter() - { - return $this->_param; - } -} -class TCompositeLiteral extends TComponent implements IRenderable, IBindable -{ - const TYPE_EXPRESSION=0; - const TYPE_STATEMENTS=1; - const TYPE_DATABINDING=2; - private $_container=null; - private $_items=array(); - private $_expressions=array(); - private $_statements=array(); - private $_bindings=array(); - public function __construct($items) - { - $this->_items=array(); - $this->_expressions=array(); - $this->_statements=array(); - foreach($items as $id=>$item) - { - if(is_array($item)) - { - if($item[0]===self::TYPE_EXPRESSION) - $this->_expressions[$id]=$item[1]; - else if($item[0]===self::TYPE_STATEMENTS) - $this->_statements[$id]=$item[1]; - else if($item[0]===self::TYPE_DATABINDING) - $this->_bindings[$id]=$item[1]; - $this->_items[$id]=''; - } - else - $this->_items[$id]=$item; - } - } - public function getContainer() - { - return $this->_container; - } - public function setContainer(TComponent $value) - { - $this->_container=$value; - } - public function evaluateDynamicContent() - { - $context=$this->_container===null?$this:$this->_container; - foreach($this->_expressions as $id=>$expression) - $this->_items[$id]=$context->evaluateExpression($expression); - foreach($this->_statements as $id=>$statement) - $this->_items[$id]=$context->evaluateStatements($statement); - } - public function dataBind() - { - $context=$this->_container===null?$this:$this->_container; - foreach($this->_bindings as $id=>$binding) - $this->_items[$id]=$context->evaluateExpression($binding); - } - public function render($writer) - { - $writer->write(implode('',$this->_items)); - } -} -class TFont extends TComponent -{ - const IS_BOLD=0x01; - const IS_ITALIC=0x02; - const IS_OVERLINE=0x04; - const IS_STRIKEOUT=0x08; - const IS_UNDERLINE=0x10; - const IS_SET_BOLD=0x01000; - const IS_SET_ITALIC=0x02000; - const IS_SET_OVERLINE=0x04000; - const IS_SET_STRIKEOUT=0x08000; - const IS_SET_UNDERLINE=0x10000; - const IS_SET_SIZE=0x20000; - const IS_SET_NAME=0x40000; - private $_flags=0; - private $_name=''; - private $_size=''; - public function getBold() - { - return ($this->_flags & self::IS_BOLD)!==0; - } - public function setBold($value) - { - $this->_flags |= self::IS_SET_BOLD; - if(TPropertyValue::ensureBoolean($value)) - $this->_flags |= self::IS_BOLD; - else - $this->_flags &= ~self::IS_BOLD; - } - public function getItalic() - { - return ($this->_flags & self::IS_ITALIC)!==0; - } - public function setItalic($value) - { - $this->_flags |= self::IS_SET_ITALIC; - if(TPropertyValue::ensureBoolean($value)) - $this->_flags |= self::IS_ITALIC; - else - $this->_flags &= ~self::IS_ITALIC; - } - public function getOverline() - { - return ($this->_flags & self::IS_OVERLINE)!==0; - } - public function setOverline($value) - { - $this->_flags |= self::IS_SET_OVERLINE; - if(TPropertyValue::ensureBoolean($value)) - $this->_flags |= self::IS_OVERLINE; - else - $this->_flags &= ~self::IS_OVERLINE; - } - public function getSize() - { - return $this->_size; - } - public function setSize($value) - { - $this->_flags |= self::IS_SET_SIZE; - $this->_size=$value; - } - public function getStrikeout() - { - return ($this->_flags & self::IS_STRIKEOUT)!==0; - } - public function setStrikeout($value) - { - $this->_flags |= self::IS_SET_STRIKEOUT; - if(TPropertyValue::ensureBoolean($value)) - $this->_flags |= self::IS_STRIKEOUT; - else - $this->_flags &= ~self::IS_STRIKEOUT; - } - public function getUnderline() - { - return ($this->_flags & self::IS_UNDERLINE)!==0; - } - public function setUnderline($value) - { - $this->_flags |= self::IS_SET_UNDERLINE; - if(TPropertyValue::ensureBoolean($value)) - $this->_flags |= self::IS_UNDERLINE; - else - $this->_flags &= ~self::IS_UNDERLINE; - } - public function getName() - { - return $this->_name; - } - public function setName($value) - { - $this->_flags |= self::IS_SET_NAME; - $this->_name=$value; - } - public function getIsEmpty() - { - return !$this->_flags; - } - public function reset() - { - $this->_flags=0; - $this->_name=''; - $this->_size=''; - } - public function mergeWith($font) - { - if($font===null || $font->_flags===0) - return; - if(!($this->_flags & self::IS_SET_BOLD) && ($font->_flags & self::IS_SET_BOLD)) - $this->setBold($font->getBold()); - if(!($this->_flags & self::IS_SET_ITALIC) && ($font->_flags & self::IS_SET_ITALIC)) - $this->setItalic($font->getItalic()); - if(!($this->_flags & self::IS_SET_OVERLINE) && ($font->_flags & self::IS_SET_OVERLINE)) - $this->setOverline($font->getOverline()); - if(!($this->_flags & self::IS_SET_STRIKEOUT) && ($font->_flags & self::IS_SET_STRIKEOUT)) - $this->setStrikeout($font->getStrikeout()); - if(!($this->_flags & self::IS_SET_UNDERLINE) && ($font->_flags & self::IS_SET_UNDERLINE)) - $this->setUnderline($font->getUnderline()); - if(!($this->_flags & self::IS_SET_SIZE) && ($font->_flags & self::IS_SET_SIZE)) - $this->setSize($font->getSize()); - if(!($this->_flags & self::IS_SET_NAME) && ($font->_flags & self::IS_SET_NAME)) - $this->setName($font->getName()); - } - public function copyFrom($font) - { - if($font===null || $font->_flags===0) - return; - if($font->_flags & self::IS_SET_BOLD) - $this->setBold($font->getBold()); - if($font->_flags & self::IS_SET_ITALIC) - $this->setItalic($font->getItalic()); - if($font->_flags & self::IS_SET_OVERLINE) - $this->setOverline($font->getOverline()); - if($font->_flags & self::IS_SET_STRIKEOUT) - $this->setStrikeout($font->getStrikeout()); - if($font->_flags & self::IS_SET_UNDERLINE) - $this->setUnderline($font->getUnderline()); - if($font->_flags & self::IS_SET_SIZE) - $this->setSize($font->getSize()); - if($font->_flags & self::IS_SET_NAME) - $this->setName($font->getName()); - } - public function toString() - { - if($this->_flags===0) - return ''; - $str=''; - if($this->_flags & self::IS_SET_BOLD) - $str.='font-weight:'.(($this->_flags & self::IS_BOLD)?'bold;':'normal;'); - if($this->_flags & self::IS_SET_ITALIC) - $str.='font-style:'.(($this->_flags & self::IS_ITALIC)?'italic;':'normal;'); - $textDec=''; - if($this->_flags & self::IS_UNDERLINE) - $textDec.='underline'; - if($this->_flags & self::IS_OVERLINE) - $textDec.=' overline'; - if($this->_flags & self::IS_STRIKEOUT) - $textDec.=' line-through'; - $textDec=ltrim($textDec); - if($textDec!=='') - $str.='text-decoration:'.$textDec.';'; - if($this->_size!=='') - $str.='font-size:'.$this->_size.';'; - if($this->_name!=='') - $str.='font-family:'.$this->_name.';'; - return $str; - } - public function addAttributesToRender($writer) - { - if($this->_flags===0) - return; - if($this->_flags & self::IS_SET_BOLD) - $writer->addStyleAttribute('font-weight',(($this->_flags & self::IS_BOLD)?'bold':'normal')); - if($this->_flags & self::IS_SET_ITALIC) - $writer->addStyleAttribute('font-style',(($this->_flags & self::IS_ITALIC)?'italic':'normal')); - $textDec=''; - if($this->_flags & self::IS_UNDERLINE) - $textDec.='underline'; - if($this->_flags & self::IS_OVERLINE) - $textDec.=' overline'; - if($this->_flags & self::IS_STRIKEOUT) - $textDec.=' line-through'; - $textDec=ltrim($textDec); - if($textDec!=='') - $writer->addStyleAttribute('text-decoration',$textDec); - if($this->_size!=='') - $writer->addStyleAttribute('font-size',$this->_size); - if($this->_name!=='') - $writer->addStyleAttribute('font-family',$this->_name); - } -} -class TStyle extends TComponent -{ - private $_fields=array(); - private $_font=null; - private $_class=null; - private $_customStyle=null; - private $_displayStyle='Fixed'; - public function __construct($style=null) - { - if($style!==null) - $this->copyFrom($style); - } - public function __clone() - { - if($this->_font!==null) - $this->_font = clone($this->_font); - } - public function getBackColor() - { - return isset($this->_fields['background-color'])?$this->_fields['background-color']:''; - } - public function setBackColor($value) - { - if(trim($value)==='') - unset($this->_fields['background-color']); - else - $this->_fields['background-color']=$value; - } - public function getBorderColor() - { - return isset($this->_fields['border-color'])?$this->_fields['border-color']:''; - } - public function setBorderColor($value) - { - if(trim($value)==='') - unset($this->_fields['border-color']); - else - $this->_fields['border-color']=$value; - } - public function getBorderStyle() - { - return isset($this->_fields['border-style'])?$this->_fields['border-style']:''; - } - public function setBorderStyle($value) - { - if(trim($value)==='') - unset($this->_fields['border-style']); - else - $this->_fields['border-style']=$value; - } - public function getBorderWidth() - { - return isset($this->_fields['border-width'])?$this->_fields['border-width']:''; - } - public function setBorderWidth($value) - { - if(trim($value)==='') - unset($this->_fields['border-width']); - else - $this->_fields['border-width']=$value; - } - public function getCssClass() - { - return $this->_class===null?'':$this->_class; - } - public function hasCssClass() - { - return ($this->_class!==null); - } - public function setCssClass($value) - { - $this->_class=$value; - } - public function getFont() - { - if($this->_font===null) - $this->_font=new TFont; - return $this->_font; - } - public function hasFont() - { - return $this->_font !== null; - } - public function setDisplayStyle($value) - { - $this->_displayStyle = TPropertyValue::ensureEnum($value, 'TDisplayStyle'); - switch($this->_displayStyle) - { - case TDisplayStyle::None: - $this->_fields['display'] = 'none'; - break; - case TDisplayStyle::Dynamic: - $this->_fields['display'] = ''; break; - case TDisplayStyle::Fixed: - $this->_fields['visibility'] = 'visible'; - break; - case TDisplayStyle::Hidden: - $this->_fields['visibility'] = 'hidden'; - break; - } - } - public function getDisplayStyle() - { - return $this->_displayStyle; - } - public function getForeColor() - { - return isset($this->_fields['color'])?$this->_fields['color']:''; - } - public function setForeColor($value) - { - if(trim($value)==='') - unset($this->_fields['color']); - else - $this->_fields['color']=$value; - } - public function getHeight() - { - return isset($this->_fields['height'])?$this->_fields['height']:''; - } - public function setHeight($value) - { - if(trim($value)==='') - unset($this->_fields['height']); - else - $this->_fields['height']=$value; - } - public function getCustomStyle() - { - return $this->_customStyle===null?'':$this->_customStyle; - } - public function setCustomStyle($value) - { - $this->_customStyle=$value; - } - public function getStyleField($name) - { - return isset($this->_fields[$name])?$this->_fields[$name]:''; - } - public function setStyleField($name,$value) - { - $this->_fields[$name]=$value; - } - public function clearStyleField($name) - { - unset($this->_fields[$name]); - } - public function hasStyleField($name) - { - return isset($this->_fields[$name]); - } - public function getWidth() - { - return isset($this->_fields['width'])?$this->_fields['width']:''; - } - public function setWidth($value) - { - $this->_fields['width']=$value; - } - public function reset() - { - $this->_fields=array(); - $this->_font=null; - $this->_class=null; - $this->_customStyle=null; - } - public function copyFrom($style) - { - if($style instanceof TStyle) - { - $this->_fields=array_merge($this->_fields,$style->_fields); - if($style->_class!==null) - $this->_class=$style->_class; - if($style->_customStyle!==null) - $this->_customStyle=$style->_customStyle; - if($style->_font!==null) - $this->getFont()->copyFrom($style->_font); - } - } - public function mergeWith($style) - { - if($style instanceof TStyle) - { - $this->_fields=array_merge($style->_fields,$this->_fields); - if($this->_class===null) - $this->_class=$style->_class; - if($this->_customStyle===null) - $this->_customStyle=$style->_customStyle; - if($style->_font!==null) - $this->getFont()->mergeWith($style->_font); - } - } - public function addAttributesToRender($writer) - { - if($this->_customStyle!==null) - { - foreach(explode(';',$this->_customStyle) as $style) - { - $arr=explode(':',$style,2); - if(isset($arr[1]) && trim($arr[0])!=='') - $writer->addStyleAttribute(trim($arr[0]),trim($arr[1])); - } - } - $writer->addStyleAttributes($this->_fields); - if($this->_font!==null) - $this->_font->addAttributesToRender($writer); - if($this->_class!==null) - $writer->addAttribute('class',$this->_class); - } - public function getStyleFields() - { - return $this->_fields; - } -} -class TDisplayStyle extends TEnumerable -{ - const None='None'; - const Dynamic='Dynamic'; - const Fixed='Fixed'; - const Hidden='Hidden'; -} -class TTableStyle extends TStyle -{ - private $_backImageUrl=null; - private $_horizontalAlign=null; - private $_cellPadding=null; - private $_cellSpacing=null; - private $_gridLines=null; - private $_borderCollapse=null; - public function reset() - { - $this->_backImageUrl=null; - $this->_horizontalAlign=null; - $this->_cellPadding=null; - $this->_cellSpacing=null; - $this->_gridLines=null; - $this->_borderCollapse=null; - } - public function copyFrom($style) - { - parent::copyFrom($style); - if($style instanceof TTableStyle) - { - if($style->_backImageUrl!==null) - $this->_backImageUrl=$style->_backImageUrl; - if($style->_horizontalAlign!==null) - $this->_horizontalAlign=$style->_horizontalAlign; - if($style->_cellPadding!==null) - $this->_cellPadding=$style->_cellPadding; - if($style->_cellSpacing!==null) - $this->_cellSpacing=$style->_cellSpacing; - if($style->_gridLines!==null) - $this->_gridLines=$style->_gridLines; - if($style->_borderCollapse!==null) - $this->_borderCollapse=$style->_borderCollapse; - } - } - public function mergeWith($style) - { - parent::mergeWith($style); - if($style instanceof TTableStyle) - { - if($this->_backImageUrl===null && $style->_backImageUrl!==null) - $this->_backImageUrl=$style->_backImageUrl; - if($this->_horizontalAlign===null && $style->_horizontalAlign!==null) - $this->_horizontalAlign=$style->_horizontalAlign; - if($this->_cellPadding===null && $style->_cellPadding!==null) - $this->_cellPadding=$style->_cellPadding; - if($this->_cellSpacing===null && $style->_cellSpacing!==null) - $this->_cellSpacing=$style->_cellSpacing; - if($this->_gridLines===null && $style->_gridLines!==null) - $this->_gridLines=$style->_gridLines; - if($this->_borderCollapse===null && $style->_borderCollapse!==null) - $this->_borderCollapse=$style->_borderCollapse; - } - } - public function addAttributesToRender($writer) - { - if(($url=trim($this->getBackImageUrl()))!=='') - $writer->addStyleAttribute('background-image','url('.$url.')'); - if(($horizontalAlign=$this->getHorizontalAlign())!==THorizontalAlign::NotSet) - $writer->addStyleAttribute('text-align',strtolower($horizontalAlign)); - if(($cellPadding=$this->getCellPadding())>=0) - $writer->addAttribute('cellpadding',"$cellPadding"); - if(($cellSpacing=$this->getCellSpacing())>=0) - $writer->addAttribute('cellspacing',"$cellSpacing"); - if($this->getBorderCollapse()) - $writer->addStyleAttribute('border-collapse','collapse'); - switch($this->getGridLines()) - { - case TTableGridLines::Horizontal : $writer->addAttribute('rules','rows'); break; - case TTableGridLines::Vertical : $writer->addAttribute('rules','cols'); break; - case TTableGridLines::Both : $writer->addAttribute('rules','all'); break; - } - parent::addAttributesToRender($writer); - } - public function getBackImageUrl() - { - return $this->_backImageUrl===null?'':$this->_backImageUrl; - } - public function setBackImageUrl($value) - { - $this->_backImageUrl=$value; - } - public function getHorizontalAlign() - { - return $this->_horizontalAlign===null?THorizontalAlign::NotSet:$this->_horizontalAlign; - } - public function setHorizontalAlign($value) - { - $this->_horizontalAlign=TPropertyValue::ensureEnum($value,'THorizontalAlign'); - } - public function getCellPadding() - { - return $this->_cellPadding===null?-1:$this->_cellPadding; - } - public function setCellPadding($value) - { - if(($this->_cellPadding=TPropertyValue::ensureInteger($value))<-1) - throw new TInvalidDataValueException('tablestyle_cellpadding_invalid'); - } - public function getCellSpacing() - { - return $this->_cellSpacing===null?-1:$this->_cellSpacing; - } - public function setCellSpacing($value) - { - if(($this->_cellSpacing=TPropertyValue::ensureInteger($value))<-1) - throw new TInvalidDataValueException('tablestyle_cellspacing_invalid'); - } - public function getGridLines() - { - return $this->_gridLines===null?TTableGridLines::None:$this->_gridLines; - } - public function setGridLines($value) - { - $this->_gridLines=TPropertyValue::ensureEnum($value,'TTableGridLines'); - } - public function getBorderCollapse() - { - return $this->_borderCollapse===null?false:$this->_borderCollapse; - } - public function setBorderCollapse($value) - { - $this->_borderCollapse=TPropertyValue::ensureBoolean($value); - } -} -class TTableItemStyle extends TStyle -{ - private $_horizontalAlign=null; - private $_verticalAlign=null; - private $_wrap=null; - public function reset() - { - parent::reset(); - $this->_verticalAlign=null; - $this->_horizontalAlign=null; - $this->_wrap=null; - } - public function copyFrom($style) - { - parent::copyFrom($style); - if($style instanceof TTableItemStyle) - { - if($this->_verticalAlign===null && $style->_verticalAlign!==null) - $this->_verticalAlign=$style->_verticalAlign; - if($this->_horizontalAlign===null && $style->_horizontalAlign!==null) - $this->_horizontalAlign=$style->_horizontalAlign; - if($this->_wrap===null && $style->_wrap!==null) - $this->_wrap=$style->_wrap; - } - } - public function mergeWith($style) - { - parent::mergeWith($style); - if($style instanceof TTableItemStyle) - { - if($style->_verticalAlign!==null) - $this->_verticalAlign=$style->_verticalAlign; - if($style->_horizontalAlign!==null) - $this->_horizontalAlign=$style->_horizontalAlign; - if($style->_wrap!==null) - $this->_wrap=$style->_wrap; - } - } - public function addAttributesToRender($writer) - { - if(!$this->getWrap()) - $writer->addStyleAttribute('white-space','nowrap'); - if(($horizontalAlign=$this->getHorizontalAlign())!==THorizontalAlign::NotSet) - $writer->addAttribute('align',strtolower($horizontalAlign)); - if(($verticalAlign=$this->getVerticalAlign())!==TVerticalAlign::NotSet) - $writer->addAttribute('valign',strtolower($verticalAlign)); - parent::addAttributesToRender($writer); - } - public function getHorizontalAlign() - { - return $this->_horizontalAlign===null?THorizontalAlign::NotSet:$this->_horizontalAlign; - } - public function setHorizontalAlign($value) - { - $this->_horizontalAlign=TPropertyValue::ensureEnum($value,'THorizontalAlign'); - } - public function getVerticalAlign() - { - return $this->_verticalAlign===null?TVerticalAlign::NotSet:$this->_verticalAlign; - } - public function setVerticalAlign($value) - { - $this->_verticalAlign=TPropertyValue::ensureEnum($value,'TVerticalAlign'); - } - public function getWrap() - { - return $this->_wrap===null?true:$this->_wrap; - } - public function setWrap($value) - { - $this->_wrap=TPropertyValue::ensureBoolean($value); - } -} -class THorizontalAlign extends TEnumerable -{ - const NotSet='NotSet'; - const Left='Left'; - const Right='Right'; - const Center='Center'; - const Justify='Justify'; -} -class TVerticalAlign extends TEnumerable -{ - const NotSet='NotSet'; - const Top='Top'; - const Bottom='Bottom'; - const Middle='Middle'; -} -class TTableGridLines extends TEnumerable -{ - const None='None'; - const Horizontal='Horizontal'; - const Vertical='Vertical'; - const Both='Both'; -} -class TWebControlAdapter extends TControlAdapter -{ - public function render($writer) - { - $this->renderBeginTag($writer); - $this->renderContents($writer); - $this->renderEndTag($writer); - } - public function renderBeginTag($writer) - { - $this->getControl()->renderBeginTag($writer); - } - public function renderContents($writer) - { - $this->getControl()->renderContents($writer); - } - public function renderEndTag($writer) - { - $this->getControl()->renderEndTag($writer); - } -} -class TWebControlDecorator extends TComponent { - private $_internalonly; - private $_usestate = false; - private $_control; - private $_outercontrol; - private $_addedTemplateDecoration=false; - private $_pretagtext = ''; - private $_precontentstext = ''; - private $_postcontentstext = ''; - private $_posttagtext = ''; - private $_pretagtemplate; - private $_precontentstemplate; - private $_postcontentstemplate; - private $_posttagtemplate; - public function __construct($control, $onlyinternal = false) { - $this->_control = $control; - $this->_internalonly = $onlyinternal; - } - public function getUseState() - { - return $this->_usestate; - } - public function setUseState($value) - { - $this->_usestate = TPropertyValue::ensureBoolean($value); - } - public function getPreTagText() { - return $this->_pretagtext; - } - public function setPreTagText($value) { - if(!$this->_internalonly && !$this->_control->getIsSkinApplied()) - $this->_pretagtext = TPropertyValue::ensureString($value); - } - public function getPreContentsText() { - return $this->_precontentstext; - } - public function setPreContentsText($value) { - if(!$this->_control->getIsSkinApplied()) - $this->_precontentstext = TPropertyValue::ensureString($value); - } - public function getPostContentsText() { - return $this->_postcontentstext; - } - public function setPostContentsText($value) { - if(!$this->_control->getIsSkinApplied()) - $this->_postcontentstext = TPropertyValue::ensureString($value); - } - public function getPostTagText() { - return $this->_posttagtext; - } - public function setPostTagText($value) { - if(!$this->_internalonly && !$this->_control->getIsSkinApplied()) - $this->_posttagtext = TPropertyValue::ensureString($value); - } - public function getPreTagTemplate() { - return $this->_pretagtemplate; - } - public function setPreTagTemplate($value) { - if(!$this->_internalonly && !$this->_control->getIsSkinApplied()) - $this->_pretagtemplate = $value; - } - public function getPreContentsTemplate() { - return $this->_precontentstemplate; - } - public function setPreContentsTemplate($value) { - if(!$this->_control->getIsSkinApplied()) - $this->_precontentstemplate = $value; - } - public function getPostContentsTemplate() { - return $this->_postcontentstemplate; - } - public function setPostContentsTemplate($value) { - if(!$this->_control->getIsSkinApplied()) - $this->_postcontentstemplate = $value; - } - public function getPostTagTemplate() { - return $this->_posttagtemplate; - } - public function setPostTagTemplate($value) { - if(!$this->_internalonly && !$this->_control->getIsSkinApplied()) - $this->_posttagtemplate = $value; - } - public function instantiate($outercontrol = null) { - if($this->getPreTagTemplate() || $this->getPreContentsTemplate() || - $this->getPostContentsTemplate() || $this->getPostTagTemplate()) { - $this->_outercontrol = $outercontrol; - if($this->getUseState()) - $this->ensureTemplateDecoration(); - else - $this->_control->getPage()->onSaveStateComplete[] = array($this, 'ensureTemplateDecoration'); - } - } - public function ensureTemplateDecoration($sender=null, $param=null) { - $control = $this->_control; - $outercontrol = $this->_outercontrol; - if($outercontrol === null) - $outercontrol = $control; - if($this->_addedTemplateDecoration) - return $this->_addedTemplateDecoration; - $this->_addedTemplateDecoration = true; - if($this->getPreContentsTemplate()) - { - $precontents = Prado::createComponent('TCompositeControl'); - $this->getPreContentsTemplate()->instantiateIn($precontents); - $control->getControls()->insertAt(0, $precontents); - } - if($this->getPostContentsTemplate()) - { - $postcontents = Prado::createComponent('TCompositeControl'); - $this->getPostContentsTemplate()->instantiateIn($postcontents); - $control->getControls()->add($postcontents); - } - if(!$outercontrol->getParent()) - return $this->_addedTemplateDecoration; - if($this->getPreTagTemplate()) - { - $pretag = Prado::createComponent('TCompositeControl'); - $this->getPreTagTemplate()->instantiateIn($pretag); - $outercontrol->getParent()->getControls()->insertBefore($outercontrol, $pretag); - } - if($this->getPostTagTemplate()) - { - $posttag = Prado::createComponent('TCompositeControl'); - $this->getPostTagTemplate()->instantiateIn($posttag); - $outercontrol->getParent()->getControls()->insertAfter($outercontrol, $posttag); - } - return true; - } - public function renderPreTagText($writer) { - $writer->write($this->getPreTagText()); - } - public function renderPreContentsText($writer) { - $writer->write($this->getPreContentsText()); - } - public function renderPostContentsText($writer) { - $writer->write($this->getPostContentsText()); - } - public function renderPostTagText($writer) { - $writer->write($this->getPostTagText()); - } -} -class TWebControl extends TControl implements IStyleable -{ - private $_ensureid=false; - protected $_decorator; - public function setEnsureId($value) - { - $this->_ensureid |= TPropertyValue::ensureBoolean($value); - } - public function getEnsureId() - { - return $this->_ensureid; - } - public function getDecorator($create=true) - { - if($create && !$this->_decorator) - $this->_decorator = Prado::createComponent('TWebControlDecorator', $this); - return $this->_decorator; - } - public function copyBaseAttributes(TWebControl $control) - { - $this->setAccessKey($control->getAccessKey()); - $this->setToolTip($control->getToolTip()); - $this->setTabIndex($control->getTabIndex()); - if(!$control->getEnabled()) - $this->setEnabled(false); - if($control->getHasAttributes()) - $this->getAttributes()->copyFrom($control->getAttributes()); - } - public function getAccessKey() - { - return $this->getViewState('AccessKey',''); - } - public function setAccessKey($value) - { - if(strlen($value)>1) - throw new TInvalidDataValueException('webcontrol_accesskey_invalid',get_class($this),$value); - $this->setViewState('AccessKey',$value,''); - } - public function getBackColor() - { - if($style=$this->getViewState('Style',null)) - return $style->getBackColor(); - else - return ''; - } - public function setBackColor($value) - { - $this->getStyle()->setBackColor($value); - } - public function getBorderColor() - { - if($style=$this->getViewState('Style',null)) - return $style->getBorderColor(); - else - return ''; - } - public function setBorderColor($value) - { - $this->getStyle()->setBorderColor($value); - } - public function getBorderStyle() - { - if($style=$this->getViewState('Style',null)) - return $style->getBorderStyle(); - else - return ''; - } - public function setBorderStyle($value) - { - $this->getStyle()->setBorderStyle($value); - } - public function getBorderWidth() - { - if($style=$this->getViewState('Style',null)) - return $style->getBorderWidth(); - else - return ''; - } - public function setBorderWidth($value) - { - $this->getStyle()->setBorderWidth($value); - } - public function getFont() - { - return $this->getStyle()->getFont(); - } - public function getForeColor() - { - if($style=$this->getViewState('Style',null)) - return $style->getForeColor(); - else - return ''; - } - public function setForeColor($value) - { - $this->getStyle()->setForeColor($value); - } - public function getHeight() - { - if($style=$this->getViewState('Style',null)) - return $style->getHeight(); - else - return ''; - } - public function setDisplay($value) - { - $this->getStyle()->setDisplayStyle($value); - } - public function getDisplay() - { - return $this->getStyle()->getDisplayStyle(); - } - public function setCssClass($value) - { - $this->getStyle()->setCssClass($value); - } - public function getCssClass() - { - if($style=$this->getViewState('Style',null)) - return $style->getCssClass(); - else - return ''; - } - public function setHeight($value) - { - $this->getStyle()->setHeight($value); - } - public function getHasStyle() - { - return $this->getViewState('Style',null)!==null; - } - protected function createStyle() - { - return new TStyle; - } - public function getStyle() - { - if($style=$this->getViewState('Style',null)) - return $style; - else - { - $style=$this->createStyle(); - $this->setViewState('Style',$style,null); - return $style; - } - } - public function setStyle($value) - { - if(is_string($value)) - $this->getStyle()->setCustomStyle($value); - else - throw new TInvalidDataValueException('webcontrol_style_invalid',get_class($this)); - } - public function clearStyle() - { - $this->clearViewState('Style'); - } - public function getTabIndex() - { - return $this->getViewState('TabIndex',0); - } - public function setTabIndex($value) - { - $this->setViewState('TabIndex',TPropertyValue::ensureInteger($value),0); - } - protected function getTagName() - { - return 'span'; - } - public function getToolTip() - { - return $this->getViewState('ToolTip',''); - } - public function setToolTip($value) - { - $this->setViewState('ToolTip',$value,''); - } - public function getWidth() - { - if($style=$this->getViewState('Style',null)) - return $style->getWidth(); - else - return ''; - } - public function setWidth($value) - { - $this->getStyle()->setWidth($value); - } - public function onPreRender($param) { - if($decorator = $this->getDecorator(false)) - $decorator->instantiate(); - parent::onPreRender($param); - } - protected function addAttributesToRender($writer) - { - if($this->getID()!=='' || $this->getEnsureId()) - $writer->addAttribute('id',$this->getClientID()); - if(($accessKey=$this->getAccessKey())!=='') - $writer->addAttribute('accesskey',$accessKey); - if(!$this->getEnabled()) - $writer->addAttribute('disabled','disabled'); - if(($tabIndex=$this->getTabIndex())>0) - $writer->addAttribute('tabindex',"$tabIndex"); - if(($toolTip=$this->getToolTip())!=='') - $writer->addAttribute('title',$toolTip); - if($style=$this->getViewState('Style',null)) - $style->addAttributesToRender($writer); - if($this->getHasAttributes()) - { - foreach($this->getAttributes() as $name=>$value) - $writer->addAttribute($name,$value); - } - } - public function render($writer) - { - $this->renderBeginTag($writer); - $this->renderContents($writer); - $this->renderEndTag($writer); - } - public function renderBeginTag($writer) - { - if($decorator = $this->getDecorator(false)) { - $decorator->renderPreTagText($writer); - $this->addAttributesToRender($writer); - $writer->renderBeginTag($this->getTagName()); - $decorator->renderPreContentsText($writer); - } else { - $this->addAttributesToRender($writer); - $writer->renderBeginTag($this->getTagName()); - } - } - public function renderContents($writer) - { - parent::renderChildren($writer); - } - public function renderEndTag($writer) - { - if($decorator = $this->getDecorator(false)) { - $decorator->renderPostContentsText($writer); - $writer->renderEndTag(); - $decorator->renderPostTagText($writer); - } else - $writer->renderEndTag($writer); - } -} -class TCompositeControl extends TControl implements INamingContainer -{ - protected function initRecursive($namingContainer=null) - { - $this->ensureChildControls(); - parent::initRecursive($namingContainer); - } -} -class TTemplateControl extends TCompositeControl -{ - const EXT_TEMPLATE='.tpl'; - private static $_template=array(); - private $_localTemplate=null; - private $_master=null; - private $_masterClass=''; - private $_contents=array(); - private $_placeholders=array(); - public function getTemplate() - { - if($this->_localTemplate===null) - { - $class=get_class($this); - if(!isset(self::$_template[$class])) - self::$_template[$class]=$this->loadTemplate(); - return self::$_template[$class]; - } - else - return $this->_localTemplate; - } - public function setTemplate($value) - { - $this->_localTemplate=$value; - } - public function getIsSourceTemplateControl() - { - if(($template=$this->getTemplate())!==null) - return $template->getIsSourceTemplate(); - else - return false; - } - public function getTemplateDirectory() - { - if(($template=$this->getTemplate())!==null) - return $template->getContextPath(); - else - return ''; - } - protected function loadTemplate() - { - $template=$this->getService()->getTemplateManager()->getTemplateByClassName(get_class($this)); - return $template; - } - public function createChildControls() - { - if($tpl=$this->getTemplate()) - { - foreach($tpl->getDirective() as $name=>$value) - { - if(is_string($value)) - $this->setSubProperty($name,$value); - else - throw new TConfigurationException('templatecontrol_directive_invalid',get_class($this),$name); - } - $tpl->instantiateIn($this); - } - } - public function registerContent($id,TContent $object) - { - if(isset($this->_contents[$id])) - throw new TConfigurationException('templatecontrol_contentid_duplicated',$id); - else - $this->_contents[$id]=$object; - } - public function registerContentPlaceHolder($id,TContentPlaceHolder $object) - { - if(isset($this->_placeholders[$id])) - throw new TConfigurationException('templatecontrol_placeholderid_duplicated',$id); - else - $this->_placeholders[$id]=$object; - } - public function getMasterClass() - { - return $this->_masterClass; - } - public function setMasterClass($value) - { - $this->_masterClass=$value; - } - public function getMaster() - { - return $this->_master; - } - public function injectContent($id,$content) - { - if(isset($this->_placeholders[$id])) - { - $placeholder=$this->_placeholders[$id]; - $controls=$placeholder->getParent()->getControls(); - $loc=$controls->remove($placeholder); - $controls->insertAt($loc,$content); - } - else - throw new TConfigurationException('templatecontrol_placeholder_inexistent',$id); - } - protected function initRecursive($namingContainer=null) - { - $this->ensureChildControls(); - if($this->_masterClass!=='') - { - $master=Prado::createComponent($this->_masterClass); - if(!($master instanceof TTemplateControl)) - throw new TInvalidDataValueException('templatecontrol_mastercontrol_invalid'); - $this->_master=$master; - $this->getControls()->clear(); - $this->getControls()->add($master); - $master->ensureChildControls(); - foreach($this->_contents as $id=>$content) - $master->injectContent($id,$content); - } - else if(!empty($this->_contents)) - throw new TConfigurationException('templatecontrol_mastercontrol_required',get_class($this)); - parent::initRecursive($namingContainer); - } -} -class TForm extends TControl -{ - public function onInit($param) - { - parent::onInit($param); - $this->getPage()->setForm($this); - } - protected function addAttributesToRender($writer) - { - $writer->addAttribute('id',$this->getClientID()); - $writer->addAttribute('method',$this->getMethod()); - $uri=$this->getRequest()->getRequestURI(); - $writer->addAttribute('action',str_replace('&','&',str_replace('&','&',$uri))); - if(($enctype=$this->getEnctype())!=='') - $writer->addAttribute('enctype',$enctype); - $attributes=$this->getAttributes(); - $attributes->remove('action'); - $writer->addAttributes($attributes); - if(($butt=$this->getDefaultButton())!=='') - { - if(($button=$this->findControl($butt))!==null) - $this->getPage()->getClientScript()->registerDefaultButton($this, $button); - else - throw new TInvalidDataValueException('form_defaultbutton_invalid',$butt); - } - } - public function render($writer) - { - $page=$this->getPage(); - $this->addAttributesToRender($writer); - $writer->renderBeginTag('form'); - $cs=$page->getClientScript(); - if($page->getClientSupportsJavaScript()) - { - $cs->renderHiddenFieldsBegin($writer); - $cs->renderScriptFilesBegin($writer); - $cs->renderBeginScripts($writer); - $page->beginFormRender($writer); - $this->renderChildren($writer); - $cs->renderHiddenFieldsEnd($writer); - $page->endFormRender($writer); - $cs->renderScriptFilesEnd($writer); - $cs->renderEndScripts($writer); - } - else - { - $cs->renderHiddenFieldsBegin($writer); - $page->beginFormRender($writer); - $this->renderChildren($writer); - $page->endFormRender($writer); - $cs->renderHiddenFieldsEnd($writer); - } - $writer->renderEndTag(); - } - public function getDefaultButton() - { - return $this->getViewState('DefaultButton',''); - } - public function setDefaultButton($value) - { - $this->setViewState('DefaultButton',$value,''); - } - public function getMethod() - { - return $this->getViewState('Method','post'); - } - public function setMethod($value) - { - $this->setViewState('Method',TPropertyValue::ensureEnum($value,'post','get'),'post'); - } - public function getEnctype() - { - return $this->getViewState('Enctype',''); - } - public function setEnctype($value) - { - $this->setViewState('Enctype',$value,''); - } - public function getName() - { - return $this->getUniqueID(); - } -} -class TClientScriptManager extends TApplicationComponent -{ - const SCRIPT_PATH='Web/Javascripts/source'; - const PACKAGES_FILE='Web/Javascripts/packages.php'; - private $_page; - private $_hiddenFields=array(); - private $_beginScripts=array(); - private $_endScripts=array(); - private $_scriptFiles=array(); - private $_headScriptFiles=array(); - private $_headScripts=array(); - private $_styleSheetFiles=array(); - private $_styleSheets=array(); - private $_registeredPradoScripts=array(); - private static $_pradoScripts; - private static $_pradoPackages; - private $_renderedHiddenFields; - private $_renderedScriptFiles=array(); - private $_expandedPradoScripts; - public function __construct(TPage $owner) - { - $this->_page=$owner; - } - public function getRequiresHead() - { - return count($this->_styleSheetFiles) || count($this->_styleSheets) - || count($this->_headScriptFiles) || count($this->_headScripts); - } - public static function getPradoPackages() - { - return self::$_pradoPackages; - } - public static function getPradoScripts() - { - return self::$_pradoScripts; - } - public function registerPradoScript($name) - { - $this->registerPradoScriptInternal($name); - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerPradoScript',$params); - } - protected function registerPradoScriptInternal($name) - { - if(!isset($this->_registeredPradoScripts[$name])) - { - if(self::$_pradoScripts === null) - { - $packageFile = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::PACKAGES_FILE; - list($packages,$deps)= include($packageFile); - self::$_pradoScripts = $deps; - self::$_pradoPackages = $packages; - } - if (isset(self::$_pradoScripts[$name])) - $this->_registeredPradoScripts[$name]=true; - else - throw new TInvalidOperationException('csmanager_pradoscript_invalid',$name); - if(($packages=array_keys($this->_registeredPradoScripts))!==array()) - { - $base = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::SCRIPT_PATH; - list($path,$baseUrl)=$this->getPackagePathUrl($base); - $packagesUrl=array(); - $isDebug=$this->getApplication()->getMode()===TApplicationMode::Debug; - foreach ($packages as $p) - { - foreach (self::$_pradoScripts[$p] as $dep) - { - foreach (self::$_pradoPackages[$dep] as $script) - if (!isset($this->_expandedPradoScripts[$script])) - { - $this->_expandedPradoScripts[$script] = true; - if($isDebug) - { - if (!in_array($url=$baseUrl.'/'.$script,$packagesUrl)) - $packagesUrl[]=$url; - } else { - if (!in_array($url=$baseUrl.'/min/'.$script,$packagesUrl)) - { - if(!is_file($filePath=$path.'/min/'.$script)) - { - $dirPath=dirname($filePath); - if(!is_dir($dirPath)) - mkdir($dirPath, PRADO_CHMOD, true); - file_put_contents($filePath, TJavaScript::JSMin(file_get_contents($base.'/'.$script))); - chmod($filePath, PRADO_CHMOD); - } - $packagesUrl[]=$url; - } - } - } - } - } - foreach($packagesUrl as $url) - $this->registerScriptFile($url,$url); - } - } - } - public function getPradoScriptAssetUrl() - { - $base = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::SCRIPT_PATH; - $assets = Prado::getApplication()->getAssetManager(); - return $assets->getPublishedUrl($base); - } - public function getScriptUrls() - { - $scripts = array_values($this->_headScriptFiles); - $scripts = array_merge($scripts, array_values($this->_scriptFiles)); - $scripts = array_unique($scripts); - return $scripts; - } - protected function getPackagePathUrl($base) - { - $assets = Prado::getApplication()->getAssetManager(); - if(strpos($base, $assets->getBaseUrl())===false) - { - if(($dir = Prado::getPathOfNameSpace($base)) !== null) { - $base = $dir; - } - return array($assets->getPublishedPath($base), $assets->publishFilePath($base)); - } - else - { - return array($assets->getBasePath().str_replace($assets->getBaseUrl(),'',$base), $base); - } - } - public function getCallbackReference(ICallbackEventHandler $callbackHandler, $options=null) - { - $options = !is_array($options) ? array() : $options; - $class = new ReflectionClass($callbackHandler); - $clientSide = $callbackHandler->getActiveControl()->getClientSide(); - $options = array_merge($options, $clientSide->getOptions()->toArray()); - $optionString = TJavaScript::encode($options); - $this->registerPradoScriptInternal('ajax'); - $id = $callbackHandler->getUniqueID(); - return "new Prado.CallbackRequest('{$id}',{$optionString})"; - } - public function registerCallbackControl($class, $options) - { - $optionString=TJavaScript::encode($options); - $code="new {$class}({$optionString});"; - $this->_endScripts[sprintf('%08X', crc32($code))]=$code; - $this->registerPradoScriptInternal('ajax'); - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerCallbackControl',$params); - } - public function registerPostBackControl($class,$options) - { - if($class === null) { - return; - } - if(!isset($options['FormID']) && ($form=$this->_page->getForm())!==null) - $options['FormID']=$form->getClientID(); - $optionString=TJavaScript::encode($options); - $code="new {$class}({$optionString});"; - $this->_endScripts[sprintf('%08X', crc32($code))]=$code; - $this->registerPradoScriptInternal('prado'); - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerPostBackControl',$params); - } - public function registerDefaultButton($panel, $button) - { - $panelID=is_string($panel)?$panel:$panel->getUniqueID(); - if(is_string($button)) - $buttonID=$button; - else - { - $button->setIsDefaultButton(true); - $buttonID=$button->getUniqueID(); - } - $options = TJavaScript::encode($this->getDefaultButtonOptions($panelID, $buttonID)); - $code = "new Prado.WebUI.DefaultButton($options);"; - $this->_endScripts['prado:'.$panelID]=$code; - $this->registerPradoScriptInternal('prado'); - $params=array($panelID,$buttonID); - $this->_page->registerCachingAction('Page.ClientScript','registerDefaultButton',$params); - } - protected function getDefaultButtonOptions($panelID, $buttonID) - { - $options['ID'] = TControl::convertUniqueIdToClientId($panelID); - $options['Panel'] = TControl::convertUniqueIdToClientId($panelID); - $options['Target'] = TControl::convertUniqueIdToClientId($buttonID); - $options['EventTarget'] = $buttonID; - $options['Event'] = 'click'; - return $options; - } - public function registerFocusControl($target) - { - $this->registerPradoScriptInternal('jquery'); - if($target instanceof TControl) - $target=$target->getClientID(); - $this->_endScripts['prado:focus'] = 'new Prado.Element.scrollTo(\''.$target.'\'); jQuery(\'#'.$target.'\').focus();'; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerFocusControl',$params); - } - public function registerStyleSheetFile($key,$url,$media='') - { - if($media==='') - $this->_styleSheetFiles[$key]=$url; - else - $this->_styleSheetFiles[$key]=array($url,$media); - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerStyleSheetFile',$params); - } - public function registerStyleSheet($key,$css,$media='') - { - $this->_styleSheets[$key]=$css; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerStyleSheet',$params); - } - public function getStyleSheetUrls() - { - $stylesheets = array_values( - array_map( - create_function('$e', 'return is_array($e) ? $e[0] : $e;'), - $this->_styleSheetFiles) - ); - foreach(Prado::getApplication()->getAssetManager()->getPublished() as $path=>$url) - if (substr($url,strlen($url)-4)=='.css') - $stylesheets[] = $url; - $stylesheets = array_unique($stylesheets); - return $stylesheets; - } - public function getStyleSheetCodes() - { - return array_unique(array_values($this->_styleSheets)); - } - public function registerHeadScriptFile($key,$url) - { - $this->checkIfNotInRender(); - $this->_headScriptFiles[$key]=$url; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerHeadScriptFile',$params); - } - public function registerHeadScript($key,$script) - { - $this->checkIfNotInRender(); - $this->_headScripts[$key]=$script; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerHeadScript',$params); - } - public function registerScriptFile($key, $url) - { - $this->_scriptFiles[$key]=$url; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerScriptFile',$params); - } - public function registerBeginScript($key,$script) - { - $this->checkIfNotInRender(); - $this->_beginScripts[$key]=$script; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerBeginScript',$params); - } - public function registerEndScript($key,$script) - { - $this->_endScripts[$key]=$script; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerEndScript',$params); - } - public function registerHiddenField($name,$value) - { - $this->_hiddenFields[$name]=$value; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','registerHiddenField',$params); - } - public function isStyleSheetFileRegistered($key) - { - return isset($this->_styleSheetFiles[$key]); - } - public function isStyleSheetRegistered($key) - { - return isset($this->_styleSheets[$key]); - } - public function isHeadScriptFileRegistered($key) - { - return isset($this->_headScriptFiles[$key]); - } - public function isHeadScriptRegistered($key) - { - return isset($this->_headScripts[$key]); - } - public function isScriptFileRegistered($key) - { - return isset($this->_scriptFiles[$key]); - } - public function isBeginScriptRegistered($key) - { - return isset($this->_beginScripts[$key]); - } - public function isEndScriptRegistered($key) - { - return isset($this->_endScripts[$key]); - } - public function hasEndScripts() - { - return count($this->_endScripts) > 0; - } - public function hasBeginScripts() - { - return count($this->_beginScripts) > 0; - } - public function isHiddenFieldRegistered($key) - { - return isset($this->_hiddenFields[$key]); - } - public function renderStyleSheetFiles($writer) - { - $str=''; - foreach($this->_styleSheetFiles as $url) - { - if(is_array($url)) - $str.="<link rel=\"stylesheet\" type=\"text/css\" media=\"{$url[1]}\" href=\"".THttpUtility::htmlEncode($url[0])."\" />\n"; - else - $str.="<link rel=\"stylesheet\" type=\"text/css\" href=\"".THttpUtility::htmlEncode($url)."\" />\n"; - } - $writer->write($str); - } - public function renderStyleSheets($writer) - { - if(count($this->_styleSheets)) - $writer->write("<style type=\"text/css\">\n/*<![CDATA[*/\n".implode("\n",$this->_styleSheets)."\n/*]]>*/\n</style>\n"); - } - public function renderHeadScriptFiles($writer) - { - $this->renderScriptFiles($writer,$this->_headScriptFiles); - } - public function renderHeadScripts($writer) - { - $writer->write(TJavaScript::renderScriptBlocks($this->_headScripts)); - } - public function renderScriptFilesBegin($writer) - { - $this->renderAllPendingScriptFiles($writer); - } - public function renderScriptFilesEnd($writer) - { - $this->renderAllPendingScriptFiles($writer); - } - public function markScriptFileAsRendered($url) - { - $this->_renderedScriptFiles[$url] = $url; - $params=func_get_args(); - $this->_page->registerCachingAction('Page.ClientScript','markScriptFileAsRendered',$params); - } - protected function renderScriptFiles($writer, Array $scripts) - { - foreach($scripts as $script) - { - $writer->write(TJavaScript::renderScriptFile($script)); - $this->markScriptFileAsRendered($script); - } - } - protected function getRenderedScriptFiles() - { - return $this->_renderedScriptFiles; - } - public function renderAllPendingScriptFiles($writer) - { - if(!empty($this->_scriptFiles)) - { - $addedScripts = array_diff($this->_scriptFiles,$this->getRenderedScriptFiles()); - $this->renderScriptFiles($writer,$addedScripts); - } - } - public function renderBeginScripts($writer) - { - $writer->write(TJavaScript::renderScriptBlocks($this->_beginScripts)); - } - public function renderEndScripts($writer) - { - $writer->write(TJavaScript::renderScriptBlocks($this->_endScripts)); - } - public function renderBeginScriptsCallback($writer) - { - $writer->write(TJavaScript::renderScriptBlocksCallback($this->_beginScripts)); - } - public function renderEndScriptsCallback($writer) - { - $writer->write(TJavaScript::renderScriptBlocksCallback($this->_endScripts)); - } - public function renderHiddenFieldsBegin($writer) - { - $this->renderHiddenFieldsInt($writer,true); - } - public function renderHiddenFieldsEnd($writer) - { - $this->renderHiddenFieldsInt($writer,false); - } - public function flushScriptFiles($writer, $control=null) - { - if(!$this->_page->getIsCallback()) - { - $this->_page->ensureRenderInForm($control); - $this->renderAllPendingScriptFiles($writer); - } - } - protected function renderHiddenFieldsInt($writer, $initial) - { - if ($initial) $this->_renderedHiddenFields = array(); - $str=''; - foreach($this->_hiddenFields as $name=>$value) - { - if (in_array($name,$this->_renderedHiddenFields)) continue; - $id=strtr($name,':','_'); - if(is_array($value)) - { - foreach($value as $v) - $str.='<input type="hidden" name="'.$name.'[]" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n"; - } - else - { - $str.='<input type="hidden" name="'.$name.'" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n"; - } - $this->_renderedHiddenFields[] = $name; - } - if($str!=='') - $writer->write("<div style=\"visibility:hidden;\">\n".$str."</div>\n"); - } - public function getHiddenFields() - { - return $this->_hiddenFields; - } - protected function checkIfNotInRender() - { - if ($form = $this->_page->InFormRender) - throw new Exception('Operation invalid when page is already rendering'); - } -} -abstract class TClientSideOptions extends TComponent -{ - private $_options; - protected function setFunction($name, $code) - { - if(!TJavaScript::isJsLiteral($code)) - $code = TJavaScript::quoteJsLiteral($this->ensureFunction($code)); - $this->setOption($name, $code); - } - protected function getOption($name) - { - if ($this->_options) - return $this->_options->itemAt($name); - else - return null; - } - protected function setOption($name, $value) - { - $this->getOptions()->add($name, $value); - } - public function getOptions() - { - if (!$this->_options) - $this->_options = Prado::createComponent('System.Collections.TMap'); - return $this->_options; - } - protected function ensureFunction($javascript) - { - return "function(sender, parameter){ {$javascript} }"; - } -} -class TPage extends TTemplateControl -{ - const FIELD_POSTBACK_TARGET='PRADO_POSTBACK_TARGET'; - const FIELD_POSTBACK_PARAMETER='PRADO_POSTBACK_PARAMETER'; - const FIELD_LASTFOCUS='PRADO_LASTFOCUS'; - const FIELD_PAGESTATE='PRADO_PAGESTATE'; - const FIELD_CALLBACK_TARGET='PRADO_CALLBACK_TARGET'; - const FIELD_CALLBACK_PARAMETER='PRADO_CALLBACK_PARAMETER'; - private static $_systemPostFields=array( - 'PRADO_POSTBACK_TARGET'=>true, - 'PRADO_POSTBACK_PARAMETER'=>true, - 'PRADO_LASTFOCUS'=>true, - 'PRADO_PAGESTATE'=>true, - 'PRADO_CALLBACK_TARGET'=>true, - 'PRADO_CALLBACK_PARAMETER'=>true - ); - private $_form; - private $_head; - private $_validators=array(); - private $_validated=false; - private $_theme; - private $_title; - private $_styleSheet; - private $_clientScript; - protected $_postData; - protected $_restPostData; - protected $_controlsPostDataChanged=array(); - protected $_controlsRequiringPostData=array(); - protected $_controlsRegisteredForPostData=array(); - private $_postBackEventTarget; - private $_postBackEventParameter; - protected $_formRendered=false; - protected $_inFormRender=false; - private $_focus; - private $_pagePath=''; - private $_enableStateValidation=true; - private $_enableStateEncryption=false; - private $_enableStateCompression=true; - private $_statePersisterClass='System.Web.UI.TPageStatePersister'; - private $_statePersister; - private $_cachingStack; - private $_clientState=''; - protected $_isLoadingPostData=false; - private $_enableJavaScript=true; - private $_writer; - public function __construct() - { - $this->setPage($this); - } - public function run($writer) - { - $this->_writer = $writer; - $this->determinePostBackMode(); - if($this->getIsPostBack()) - { - if($this->getIsCallback()) - $this->processCallbackRequest($writer); - else - $this->processPostBackRequest($writer); - } - else - $this->processNormalRequest($writer); - $this->_writer = null; - } - protected function processNormalRequest($writer) - { - $this->onPreInit(null); - $this->initRecursive(); - $this->onInitComplete(null); - $this->onPreLoad(null); - $this->loadRecursive(); - $this->onLoadComplete(null); - $this->preRenderRecursive(); - $this->onPreRenderComplete(null); - $this->savePageState(); - $this->onSaveStateComplete(null); - $this->renderControl($writer); - $this->unloadRecursive(); - } - protected function processPostBackRequest($writer) - { - $this->onPreInit(null); - $this->initRecursive(); - $this->onInitComplete(null); - $this->_restPostData=new TMap; - $this->loadPageState(); - $this->processPostData($this->_postData,true); - $this->onPreLoad(null); - $this->loadRecursive(); - $this->processPostData($this->_restPostData,false); - $this->raiseChangedEvents(); - $this->raisePostBackEvent(); - $this->onLoadComplete(null); - $this->preRenderRecursive(); - $this->onPreRenderComplete(null); - $this->savePageState(); - $this->onSaveStateComplete(null); - $this->renderControl($writer); - $this->unloadRecursive(); - } - protected static function decodeUTF8($data, $enc) - { - if(is_array($data)) - { - foreach($data as $k=>$v) - $data[$k]=self::decodeUTF8($v, $enc); - return $data; - } elseif(is_string($data)) { - return iconv('UTF-8',$enc.'//IGNORE',$data); - } else { - return $data; - } - } - protected function processCallbackRequest($writer) - { - Prado::using('System.Web.UI.ActiveControls.TActivePageAdapter'); - $this->setAdapter(new TActivePageAdapter($this)); - $callbackEventParameter = $this->getRequest()->itemAt(TPage::FIELD_CALLBACK_PARAMETER); - if(strlen($callbackEventParameter) > 0) - $this->_postData[TPage::FIELD_CALLBACK_PARAMETER]=TJavaScript::jsonDecode((string)$callbackEventParameter); - if (($g=$this->getApplication()->getGlobalization(false))!==null && - strtoupper($enc=$g->getCharset())!='UTF-8') - foreach ($this->_postData as $k=>$v) - $this->_postData[$k]=self::decodeUTF8($v, $enc); - $this->onPreInit(null); - $this->initRecursive(); - $this->onInitComplete(null); - $this->_restPostData=new TMap; - $this->loadPageState(); - $this->processPostData($this->_postData,true); - $this->onPreLoad(null); - $this->loadRecursive(); - $this->processPostData($this->_restPostData,false); - $this->raiseChangedEvents(); - $this->getAdapter()->processCallbackEvent($writer); - $this->onLoadComplete(null); - $this->preRenderRecursive(); - $this->onPreRenderComplete(null); - $this->savePageState(); - $this->onSaveStateComplete(null); - $this->getAdapter()->renderCallbackResponse($writer); - $this->unloadRecursive(); - } - public function getCallbackClient() - { - if($this->getAdapter() !== null) - return $this->getAdapter()->getCallbackClientHandler(); - else - return new TCallbackClientScript(); - } - public function setCallbackClient($client) - { - $this->getAdapter()->setCallbackClientHandler($client); - } - public function getCallbackEventTarget() - { - return $this->getAdapter()->getCallbackEventTarget(); - } - public function setCallbackEventTarget(TControl $control) - { - $this->getAdapter()->setCallbackEventTarget($control); - } - public function getCallbackEventParameter() - { - return $this->getAdapter()->getCallbackEventParameter(); - } - public function setCallbackEventParameter($value) - { - $this->getAdapter()->setCallbackEventParameter($value); - } - public function getForm() - { - return $this->_form; - } - public function setForm(TForm $form) - { - if($this->_form===null) - $this->_form=$form; - else - throw new TInvalidOperationException('page_form_duplicated'); - } - public function getValidators($validationGroup=null) - { - if(!$this->_validators) - $this->_validators=new TList; - if(empty($validationGroup) === true) - return $this->_validators; - else - { - $list=new TList; - foreach($this->_validators as $validator) - if($validator->getValidationGroup()===$validationGroup) - $list->add($validator); - return $list; - } - } - public function validate($validationGroup=null) - { - $this->_validated=true; - if($this->_validators && $this->_validators->getCount()) - { - if($validationGroup===null) - { - foreach($this->_validators as $validator) - $validator->validate(); - } - else - { - foreach($this->_validators as $validator) - { - if($validator->getValidationGroup()===$validationGroup) - $validator->validate(); - } - } - } - } - public function getIsValid() - { - if($this->_validated) - { - if($this->_validators && $this->_validators->getCount()) - { - foreach($this->_validators as $validator) - if(!$validator->getIsValid()) - return false; - } - return true; - } - else - throw new TInvalidOperationException('page_isvalid_unknown'); - } - public function getTheme() - { - if(is_string($this->_theme)) - $this->_theme=$this->getService()->getThemeManager()->getTheme($this->_theme); - return $this->_theme; - } - public function setTheme($value) - { - $this->_theme=empty($value)?null:$value; - } - public function getStyleSheetTheme() - { - if(is_string($this->_styleSheet)) - $this->_styleSheet=$this->getService()->getThemeManager()->getTheme($this->_styleSheet); - return $this->_styleSheet; - } - public function setStyleSheetTheme($value) - { - $this->_styleSheet=empty($value)?null:$value; - } - public function applyControlSkin($control) - { - if(($theme=$this->getTheme())!==null) - $theme->applySkin($control); - } - public function applyControlStyleSheet($control) - { - if(($theme=$this->getStyleSheetTheme())!==null) - $theme->applySkin($control); - } - public function getClientScript() - { - if(!$this->_clientScript) { - $className = $classPath = $this->getService()->getClientScriptManagerClass(); - Prado::using($className); - if(($pos=strrpos($className,'.'))!==false) - $className=substr($className,$pos+1); - if(!class_exists($className,false) || ($className!=='TClientScriptManager' && !is_subclass_of($className,'TClientScriptManager'))) - throw new THttpException(404,'page_csmanagerclass_invalid',$classPath); - $this->_clientScript=new $className($this); - } - return $this->_clientScript; - } - public function onPreInit($param) - { - $this->raiseEvent('OnPreInit',$this,$param); - } - public function onInitComplete($param) - { - $this->raiseEvent('OnInitComplete',$this,$param); - } - public function onPreLoad($param) - { - $this->raiseEvent('OnPreLoad',$this,$param); - } - public function onLoadComplete($param) - { - $this->raiseEvent('OnLoadComplete',$this,$param); - } - public function onPreRenderComplete($param) - { - $this->raiseEvent('OnPreRenderComplete',$this,$param); - $cs=$this->getClientScript(); - $theme=$this->getTheme(); - if($theme instanceof ITheme) - { - foreach($theme->getStyleSheetFiles() as $url) - $cs->registerStyleSheetFile($url,$url,$this->getCssMediaType($url)); - foreach($theme->getJavaScriptFiles() as $url) - $cs->registerHeadScriptFile($url,$url); - } - $styleSheet=$this->getStyleSheetTheme(); - if($styleSheet instanceof ITheme) - { - foreach($styleSheet->getStyleSheetFiles() as $url) - $cs->registerStyleSheetFile($url,$url,$this->getCssMediaType($url)); - foreach($styleSheet->getJavaScriptFiles() as $url) - $cs->registerHeadScriptFile($url,$url); - } - if($cs->getRequiresHead() && $this->getHead()===null) - throw new TConfigurationException('page_head_required'); - } - private function getCssMediaType($url) - { - $segs=explode('.',basename($url)); - if(isset($segs[2])) - return $segs[count($segs)-2]; - else - return ''; - } - public function onSaveStateComplete($param) - { - $this->raiseEvent('OnSaveStateComplete',$this,$param); - } - private function determinePostBackMode() - { - $postData=$this->getRequest(); - if($postData->contains(self::FIELD_PAGESTATE) || $postData->contains(self::FIELD_POSTBACK_TARGET)) - $this->_postData=$postData; - } - public function getIsPostBack() - { - return $this->_postData!==null; - } - public function getIsCallback() - { - return $this->getIsPostBack() && $this->getRequest()->contains(self::FIELD_CALLBACK_TARGET); - } - public function saveState() - { - parent::saveState(); - $this->setViewState('ControlsRequiringPostBack',$this->_controlsRegisteredForPostData,array()); - } - public function loadState() - { - parent::loadState(); - $this->_controlsRequiringPostData=$this->getViewState('ControlsRequiringPostBack',array()); - } - protected function loadPageState() - { - $state=$this->getStatePersister()->load(); - $this->loadStateRecursive($state,$this->getEnableViewState()); - } - protected function savePageState() - { - $state=&$this->saveStateRecursive($this->getEnableViewState()); - $this->getStatePersister()->save($state); - } - protected function isSystemPostField($field) - { - return isset(self::$_systemPostFields[$field]); - } - public function registerRequiresPostData($control) - { - $id=is_string($control)?$control:$control->getUniqueID(); - $this->_controlsRegisteredForPostData[$id]=true; - $params=func_get_args(); - foreach($this->getCachingStack() as $item) - $item->registerAction('Page','registerRequiresPostData',array($id)); - } - public function getPostBackEventTarget() - { - if($this->_postBackEventTarget===null && $this->_postData!==null) - { - $eventTarget=$this->_postData->itemAt(self::FIELD_POSTBACK_TARGET); - if(!empty($eventTarget)) - $this->_postBackEventTarget=$this->findControl($eventTarget); - } - return $this->_postBackEventTarget; - } - public function setPostBackEventTarget(TControl $control) - { - $this->_postBackEventTarget=$control; - } - public function getPostBackEventParameter() - { - if($this->_postBackEventParameter===null && $this->_postData!==null) - { - if(($this->_postBackEventParameter=$this->_postData->itemAt(self::FIELD_POSTBACK_PARAMETER))===null) - $this->_postBackEventParameter=''; - } - return $this->_postBackEventParameter; - } - public function setPostBackEventParameter($value) - { - $this->_postBackEventParameter=$value; - } - protected function processPostData($postData,$beforeLoad) - { - $this->_isLoadingPostData=true; - if($beforeLoad) - $this->_restPostData=new TMap; - foreach($postData as $key=>$value) - { - if($this->isSystemPostField($key)) - continue; - else if($control=$this->findControl($key)) - { - if($control instanceof IPostBackDataHandler) - { - if($control->loadPostData($key,$postData)) - $this->_controlsPostDataChanged[]=$control; - } - else if($control instanceof IPostBackEventHandler && - empty($this->_postData[self::FIELD_POSTBACK_TARGET])) - { - $this->_postData->add(self::FIELD_POSTBACK_TARGET,$key); } - unset($this->_controlsRequiringPostData[$key]); - } - else if($beforeLoad) - $this->_restPostData->add($key,$value); - } - foreach($this->_controlsRequiringPostData as $key=>$value) - { - if($control=$this->findControl($key)) - { - if($control instanceof IPostBackDataHandler) - { - if($control->loadPostData($key,$this->_postData)) - $this->_controlsPostDataChanged[]=$control; - } - else - throw new TInvalidDataValueException('page_postbackcontrol_invalid',$key); - unset($this->_controlsRequiringPostData[$key]); - } - } - $this->_isLoadingPostData=false; - } - public function getIsLoadingPostData() - { - return $this->_isLoadingPostData; - } - protected function raiseChangedEvents() - { - foreach($this->_controlsPostDataChanged as $control) - $control->raisePostDataChangedEvent(); - } - protected function raisePostBackEvent() - { - if(($postBackHandler=$this->getPostBackEventTarget())===null) - $this->validate(); - else if($postBackHandler instanceof IPostBackEventHandler) - $postBackHandler->raisePostBackEvent($this->getPostBackEventParameter()); - } - public function getInFormRender() - { - return $this->_inFormRender; - } - public function ensureRenderInForm($control) - { - if(!$this->getIsCallback() && !$this->_inFormRender) - throw new TConfigurationException('page_control_outofform',get_class($control), $control ? $control->getUniqueID() : null); - } - public function beginFormRender($writer) - { - if($this->_formRendered) - throw new TConfigurationException('page_form_duplicated'); - $this->_formRendered=true; - $this->getClientScript()->registerHiddenField(self::FIELD_PAGESTATE,$this->getClientState()); - $this->_inFormRender=true; - } - public function endFormRender($writer) - { - if($this->_focus) - { - if(($this->_focus instanceof TControl) && $this->_focus->getVisible(true)) - $focus=$this->_focus->getClientID(); - else - $focus=$this->_focus; - $this->getClientScript()->registerFocusControl($focus); - } - else if($this->_postData && ($lastFocus=$this->_postData->itemAt(self::FIELD_LASTFOCUS))!==null) - $this->getClientScript()->registerFocusControl($lastFocus); - $this->_inFormRender=false; - } - public function setFocus($value) - { - $this->_focus=$value; - } - public function getClientSupportsJavaScript() - { - return $this->_enableJavaScript; - } - public function setClientSupportsJavaScript($value) - { - $this->_enableJavaScript=TPropertyValue::ensureBoolean($value); - } - public function getHead() - { - return $this->_head; - } - public function setHead(THead $value) - { - if($this->_head) - throw new TInvalidOperationException('page_head_duplicated'); - $this->_head=$value; - if($this->_title!==null) - { - $this->_head->setTitle($this->_title); - $this->_title=null; - } - } - public function getTitle() - { - if($this->_head) - return $this->_head->getTitle(); - else - return $this->_title===null ? '' : $this->_title; - } - public function setTitle($value) - { - if($this->_head) - $this->_head->setTitle($value); - else - $this->_title=$value; - } - public function getClientState() - { - return $this->_clientState; - } - public function setClientState($state) - { - $this->_clientState=$state; - } - public function getRequestClientState() - { - return $this->getRequest()->itemAt(self::FIELD_PAGESTATE); - } - public function getStatePersisterClass() - { - return $this->_statePersisterClass; - } - public function setStatePersisterClass($value) - { - $this->_statePersisterClass=$value; - } - public function getStatePersister() - { - if($this->_statePersister===null) - { - $this->_statePersister=Prado::createComponent($this->_statePersisterClass); - if(!($this->_statePersister instanceof IPageStatePersister)) - throw new TInvalidDataTypeException('page_statepersister_invalid'); - $this->_statePersister->setPage($this); - } - return $this->_statePersister; - } - public function getEnableStateValidation() - { - return $this->_enableStateValidation; - } - public function setEnableStateValidation($value) - { - $this->_enableStateValidation=TPropertyValue::ensureBoolean($value); - } - public function getEnableStateEncryption() - { - return $this->_enableStateEncryption; - } - public function setEnableStateEncryption($value) - { - $this->_enableStateEncryption=TPropertyValue::ensureBoolean($value); - } - public function getEnableStateCompression() - { - return $this->_enableStateCompression; - } - public function setEnableStateCompression($value) - { - $this->_enableStateCompression=TPropertyValue::ensureBoolean($value); - } - public function getPagePath() - { - return $this->_pagePath; - } - public function setPagePath($value) - { - $this->_pagePath=$value; - } - public function registerCachingAction($context,$funcName,$funcParams) - { - if($this->_cachingStack) - { - foreach($this->_cachingStack as $cache) - $cache->registerAction($context,$funcName,$funcParams); - } - } - public function getCachingStack() - { - if(!$this->_cachingStack) - $this->_cachingStack=new TStack; - return $this->_cachingStack; - } - public function flushWriter() - { - if ($this->_writer) - $this->Response->write($this->_writer->flush()); - } -} -interface IPageStatePersister -{ - public function getPage(); - public function setPage(TPage $page); - public function save($state); - public function load(); -} -class TPageStateFormatter -{ - public static function serialize($page,$data) - { - $sm=$page->getApplication()->getSecurityManager(); - if($page->getEnableStateValidation()) - $str=$sm->hashData(serialize($data)); - else - $str=serialize($data); - if($page->getEnableStateCompression() && extension_loaded('zlib')) - $str=gzcompress($str); - if($page->getEnableStateEncryption()) - $str=$sm->encrypt($str); - return base64_encode($str); - } - public static function unserialize($page,$data) - { - $str=base64_decode($data); - if($str==='') - return null; - if($str!==false) - { - $sm=$page->getApplication()->getSecurityManager(); - if($page->getEnableStateEncryption()) - $str=$sm->decrypt($str); - if($page->getEnableStateCompression() && extension_loaded('zlib')) - $str=@gzuncompress($str); - if($page->getEnableStateValidation()) - { - if(($str=$sm->validateData($str))!==false) - return unserialize($str); - } - else - return unserialize($str); - } - return null; - } -} -class TOutputCache extends TControl implements INamingContainer -{ - const CACHE_ID_PREFIX='prado:outputcache'; - private $_cacheModuleID=''; - private $_dataCached=false; - private $_cacheAvailable=false; - private $_cacheChecked=false; - private $_cacheKey=null; - private $_duration=60; - private $_cache=null; - private $_contents; - private $_state; - private $_actions=array(); - private $_varyByParam=''; - private $_keyPrefix=''; - private $_varyBySession=false; - private $_cachePostBack=false; - private $_cacheTime=0; - public function getAllowChildControls() - { - $this->determineCacheability(); - return !$this->_dataCached; - } - private function determineCacheability() - { - if(!$this->_cacheChecked) - { - $this->_cacheChecked=true; - if($this->_duration>0 && ($this->_cachePostBack || !$this->getPage()->getIsPostBack())) - { - if($this->_cacheModuleID!=='') - { - $this->_cache=$this->getApplication()->getModule($this->_cacheModuleID); - if(!($this->_cache instanceof ICache)) - throw new TConfigurationException('outputcache_cachemoduleid_invalid',$this->_cacheModuleID); - } - else - $this->_cache=$this->getApplication()->getCache(); - if($this->_cache!==null) - { - $this->_cacheAvailable=true; - $data=$this->_cache->get($this->getCacheKey()); - if(is_array($data)) - { - $param=new TOutputCacheCheckDependencyEventParameter; - $param->setCacheTime(isset($data[3])?$data[3]:0); - $this->onCheckDependency($param); - $this->_dataCached=$param->getIsValid(); - } - else - $this->_dataCached=false; - if($this->_dataCached) - list($this->_contents,$this->_state,$this->_actions,$this->_cacheTime)=$data; - } - } - } - } - protected function initRecursive($namingContainer=null) - { - if($this->_cacheAvailable && !$this->_dataCached) - { - $stack=$this->getPage()->getCachingStack(); - $stack->push($this); - parent::initRecursive($namingContainer); - $stack->pop(); - } - else - parent::initRecursive($namingContainer); - } - protected function loadRecursive() - { - if($this->_cacheAvailable && !$this->_dataCached) - { - $stack=$this->getPage()->getCachingStack(); - $stack->push($this); - parent::loadRecursive(); - $stack->pop(); - } - else - { - if($this->_dataCached) - $this->performActions(); - parent::loadRecursive(); - } - } - private function performActions() - { - $page=$this->getPage(); - $cs=$page->getClientScript(); - foreach($this->_actions as $action) - { - if($action[0]==='Page.ClientScript') - call_user_func_array(array($cs,$action[1]),$action[2]); - else if($action[0]==='Page') - call_user_func_array(array($page,$action[1]),$action[2]); - else - call_user_func_array(array($this->getSubProperty($action[0]),$action[1]),$action[2]); - } - } - protected function preRenderRecursive() - { - if($this->_cacheAvailable && !$this->_dataCached) - { - $stack=$this->getPage()->getCachingStack(); - $stack->push($this); - parent::preRenderRecursive(); - $stack->pop(); - } - else - parent::preRenderRecursive(); - } - protected function loadStateRecursive(&$state,$needViewState=true) - { - $st=unserialize($state); - parent::loadStateRecursive($st,$needViewState); - } - protected function &saveStateRecursive($needViewState=true) - { - if($this->_dataCached) - return $this->_state; - else - { - $st=parent::saveStateRecursive($needViewState); - $this->_state=serialize($st); - return $this->_state; - } - } - public function registerAction($context,$funcName,$funcParams) - { - $this->_actions[]=array($context,$funcName,$funcParams); - } - public function getCacheKey() - { - if($this->_cacheKey===null) - $this->_cacheKey=$this->calculateCacheKey(); - return $this->_cacheKey; - } - protected function calculateCacheKey() - { - $key=$this->getBaseCacheKey(); - if($this->_varyBySession) - $key.=$this->getSession()->getSessionID(); - if($this->_varyByParam!=='') - { - $params=array(); - $request=$this->getRequest(); - foreach(explode(',',$this->_varyByParam) as $name) - { - $name=trim($name); - $params[$name]=$request->itemAt($name); - } - $key.=serialize($params); - } - $param=new TOutputCacheCalculateKeyEventParameter; - $this->onCalculateKey($param); - $key.=$param->getCacheKey(); - return $key; - } - protected function getBaseCacheKey() - { - return self::CACHE_ID_PREFIX.$this->_keyPrefix.$this->getPage()->getPagePath().$this->getUniqueID(); - } - public function getCacheModuleID() - { - return $this->_cacheModuleID; - } - public function setCacheModuleID($value) - { - $this->_cacheModuleID=$value; - } - public function setCacheKeyPrefix($value) - { - $this->_keyPrefix=$value; - } - public function getCacheTime() - { - return $this->_cacheTime; - } - protected function getCacheDependency() - { - return null; - } - public function getContentCached() - { - return $this->_dataCached; - } - public function getDuration() - { - return $this->_duration; - } - public function setDuration($value) - { - if(($value=TPropertyValue::ensureInteger($value))<0) - throw new TInvalidDataValueException('outputcache_duration_invalid',get_class($this)); - $this->_duration=$value; - } - public function getVaryByParam() - { - return $this->_varyByParam; - } - public function setVaryByParam($value) - { - $this->_varyByParam=trim($value); - } - public function getVaryBySession() - { - return $this->_varyBySession; - } - public function setVaryBySession($value) - { - $this->_varyBySession=TPropertyValue::ensureBoolean($value); - } - public function getCachingPostBack() - { - return $this->_cachePostBack; - } - public function setCachingPostBack($value) - { - $this->_cachePostBack=TPropertyValue::ensureBoolean($value); - } - public function onCheckDependency($param) - { - $this->raiseEvent('OnCheckDependency',$this,$param); - } - public function onCalculateKey($param) - { - $this->raiseEvent('OnCalculateKey',$this,$param); - } - public function render($writer) - { - if($this->_dataCached) - $writer->write($this->_contents); - else if($this->_cacheAvailable) - { - $textwriter = new TTextWriter(); - $multiwriter = new TOutputCacheTextWriterMulti(array($writer->getWriter(),$textwriter)); - $htmlWriter = Prado::createComponent($this->GetResponse()->getHtmlWriterType(), $multiwriter); - $stack=$this->getPage()->getCachingStack(); - $stack->push($this); - parent::render($htmlWriter); - $stack->pop(); - $content=$textwriter->flush(); - $data=array($content,$this->_state,$this->_actions,time()); - $this->_cache->set($this->getCacheKey(),$data,$this->getDuration(),$this->getCacheDependency()); - } - else - parent::render($writer); - } -} -class TOutputCacheCheckDependencyEventParameter extends TEventParameter -{ - private $_isValid=true; - private $_cacheTime=0; - public function getIsValid() - { - return $this->_isValid; - } - public function setIsValid($value) - { - $this->_isValid=TPropertyValue::ensureBoolean($value); - } - public function getCacheTime() - { - return $this->_cacheTime; - } - public function setCacheTime($value) - { - $this->_cacheTime=TPropertyValue::ensureInteger($value); - } -} -class TOutputCacheCalculateKeyEventParameter extends TEventParameter -{ - private $_cacheKey=''; - public function getCacheKey() - { - return $this->_cacheKey; - } - public function setCacheKey($value) - { - $this->_cacheKey=TPropertyValue::ensureString($value); - } -} -class TOutputCacheTextWriterMulti extends TTextWriter -{ - protected $_writers; - public function __construct(Array $writers) - { - $this->_writers = $writers; - } - public function write($s) - { - foreach($this->_writers as $writer) - $writer->write($s); - } - public function flush() - { - foreach($this->_writers as $writer) - $s = $writer->flush(); - return $s; - } -} -class TTemplateManager extends TModule -{ - const TEMPLATE_FILE_EXT='.tpl'; - const TEMPLATE_CACHE_PREFIX='prado:template:'; - public function init($config) - { - $this->getService()->setTemplateManager($this); - } - public function getTemplateByClassName($className) - { - $class=new ReflectionClass($className); - $tplFile=dirname($class->getFileName()).DIRECTORY_SEPARATOR.$className.self::TEMPLATE_FILE_EXT; - return $this->getTemplateByFileName($tplFile); - } - public function getTemplateByFileName($fileName) - { - if(($fileName=$this->getLocalizedTemplate($fileName))!==null) - { - 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,$timestamps)=$array; - if($this->getApplication()->getMode()===TApplicationMode::Performance) - return $template; - $cacheValid=true; - foreach($timestamps as $tplFile=>$timestamp) - { - if(!is_file($tplFile) || filemtime($tplFile)>$timestamp) - { - $cacheValid=false; - break; - } - } - if($cacheValid) - return $template; - } - $template=new TTemplate(file_get_contents($fileName),dirname($fileName),$fileName); - $includedFiles=$template->getIncludedFiles(); - $timestamps=array(); - $timestamps[$fileName]=filemtime($fileName); - foreach($includedFiles as $includedFile) - $timestamps[$includedFile]=filemtime($includedFile); - $cache->set(self::TEMPLATE_CACHE_PREFIX.$fileName,array($template,$timestamps)); - return $template; - } - } - else - return null; - } - protected function getLocalizedTemplate($filename) - { - if(($app=$this->getApplication()->getGlobalization(false))===null) - return is_file($filename)?$filename:null; - foreach($app->getLocalizedResource($filename) as $file) - { - if(($file=realpath($file))!==false && is_file($file)) - return $file; - } - return null; - } -} -class TTemplate extends TApplicationComponent implements ITemplate -{ - const REGEX_RULES='/<!--.*?--!>|<!---.*?--->|<\/?com:([\w\.]+)((?:\s*[\w\.]+\s*=\s*\'.*?\'|\s*[\w\.]+\s*=\s*".*?"|\s*[\w\.]+\s*=\s*<%.*?%>)*)\s*\/?>|<\/?prop:([\w\.]+)\s*>|<%@\s*((?:\s*[\w\.]+\s*=\s*\'.*?\'|\s*[\w\.]+\s*=\s*".*?")*)\s*%>|<%[%#~\/\\$=\\[](.*?)%>|<prop:([\w\.]+)((?:\s*[\w\.]+\s*=\s*\'.*?\'|\s*[\w\.]+\s*=\s*".*?"|\s*[\w\.]+\s*=\s*<%.*?%>)*)\s*\/>/msS'; - const CONFIG_DATABIND=0; - const CONFIG_EXPRESSION=1; - const CONFIG_ASSET=2; - const CONFIG_PARAMETER=3; - const CONFIG_LOCALIZATION=4; - const CONFIG_TEMPLATE=5; - private $_tpl=array(); - private $_directive=array(); - private $_contextPath; - private $_tplFile=null; - private $_startingLine=0; - private $_content; - private $_sourceTemplate=true; - private $_hashCode=''; - private $_tplControl=null; - private $_includedFiles=array(); - private $_includeAtLine=array(); - private $_includeLines=array(); - public function __construct($template,$contextPath,$tplFile=null,$startingLine=0,$sourceTemplate=true) - { - $this->_sourceTemplate=$sourceTemplate; - $this->_contextPath=$contextPath; - $this->_tplFile=$tplFile; - $this->_startingLine=$startingLine; - $this->_content=$template; - $this->_hashCode=md5($template); - $this->parse($template); - $this->_content=null; } - public function getTemplateFile() - { - return $this->_tplFile; - } - public function getIsSourceTemplate() - { - return $this->_sourceTemplate; - } - public function getContextPath() - { - return $this->_contextPath; - } - public function getDirective() - { - return $this->_directive; - } - public function getHashCode() - { - return $this->_hashCode; - } - public function &getItems() - { - return $this->_tpl; - } - public function instantiateIn($tplControl,$parentControl=null) - { - $this->_tplControl=$tplControl; - if($parentControl===null) - $parentControl=$tplControl; - if(($page=$tplControl->getPage())===null) - $page=$this->getService()->getRequestedPage(); - $controls=array(); - $directChildren=array(); - foreach($this->_tpl as $key=>$object) - { - if($object[0]===-1) - $parent=$parentControl; - else if(isset($controls[$object[0]])) - $parent=$controls[$object[0]]; - else - continue; - if(isset($object[2])) { - $component=Prado::createComponent($object[1]); - $properties=&$object[2]; - if($component instanceof TControl) - { - if($component instanceof TOutputCache) - $component->setCacheKeyPrefix($this->_hashCode.$key); - $component->setTemplateControl($tplControl); - if(isset($properties['id'])) - { - if(is_array($properties['id'])) - $properties['id']=$component->evaluateExpression($properties['id'][1]); - $tplControl->registerObject($properties['id'],$component); - } - if(isset($properties['skinid'])) - { - if(is_array($properties['skinid'])) - $component->setSkinID($component->evaluateExpression($properties['skinid'][1])); - else - $component->setSkinID($properties['skinid']); - unset($properties['skinid']); - } - $component->trackViewState(false); - $component->applyStyleSheetSkin($page); - foreach($properties as $name=>$value) - $this->configureControl($component,$name,$value); - $component->trackViewState(true); - if($parent===$parentControl) - $directChildren[]=$component; - else - $component->createdOnTemplate($parent); - if($component->getAllowChildControls()) - $controls[$key]=$component; - } - else if($component instanceof TComponent) - { - $controls[$key]=$component; - if(isset($properties['id'])) - { - if(is_array($properties['id'])) - $properties['id']=$component->evaluateExpression($properties['id'][1]); - $tplControl->registerObject($properties['id'],$component); - if(!$component->hasProperty('id')) - unset($properties['id']); - } - foreach($properties as $name=>$value) - $this->configureComponent($component,$name,$value); - if($parent===$parentControl) - $directChildren[]=$component; - else - $component->createdOnTemplate($parent); - } - } - else - { - if($object[1] instanceof TCompositeLiteral) - { - $o=clone $object[1]; - $o->setContainer($tplControl); - if($parent===$parentControl) - $directChildren[]=$o; - else - $parent->addParsedObject($o); - } - else - { - if($parent===$parentControl) - $directChildren[]=$object[1]; - else - $parent->addParsedObject($object[1]); - } - } - } - foreach($directChildren as $control) - { - if($control instanceof TComponent) - $control->createdOnTemplate($parentControl); - else - $parentControl->addParsedObject($control); - } - } - protected function configureControl($control,$name,$value) - { - if(strncasecmp($name,'on',2)===0) $this->configureEvent($control,$name,$value,$control); - else if(($pos=strrpos($name,'.'))===false) $this->configureProperty($control,$name,$value); - else $this->configureSubProperty($control,$name,$value); - } - protected function configureComponent($component,$name,$value) - { - if(strpos($name,'.')===false) $this->configureProperty($component,$name,$value); - else $this->configureSubProperty($component,$name,$value); - } - protected function configureEvent($control,$name,$value,$contextControl) - { - if(strpos($value,'.')===false) - $control->attachEventHandler($name,array($contextControl,'TemplateControl.'.$value)); - else - $control->attachEventHandler($name,array($contextControl,$value)); - } - protected function configureProperty($component,$name,$value) - { - if(is_array($value)) - { - switch($value[0]) - { - case self::CONFIG_DATABIND: - $component->bindProperty($name,$value[1]); - break; - case self::CONFIG_EXPRESSION: - if($component instanceof TControl) - $component->autoBindProperty($name,$value[1]); - else - { - $setter='set'.$name; - $component->$setter($this->_tplControl->evaluateExpression($value[1])); - } - break; - case self::CONFIG_TEMPLATE: - $setter='set'.$name; - $component->$setter($value[1]); - break; - case self::CONFIG_ASSET: $setter='set'.$name; - $url=$this->publishFilePath($this->_contextPath.DIRECTORY_SEPARATOR.$value[1]); - $component->$setter($url); - break; - case self::CONFIG_PARAMETER: $setter='set'.$name; - $component->$setter($this->getApplication()->getParameters()->itemAt($value[1])); - break; - case self::CONFIG_LOCALIZATION: - $setter='set'.$name; - $component->$setter(Prado::localize($value[1])); - break; - default: throw new TConfigurationException('template_tag_unexpected',$name,$value[1]); - break; - } - } - else - { - if (substr($name,0,2)=='js') - if ($value and !($value instanceof TJavaScriptLiteral)) - $value = new TJavaScriptLiteral($value); - $setter='set'.$name; - $component->$setter($value); - } - } - protected function configureSubProperty($component,$name,$value) - { - if(is_array($value)) - { - switch($value[0]) - { - case self::CONFIG_DATABIND: $component->bindProperty($name,$value[1]); - break; - case self::CONFIG_EXPRESSION: if($component instanceof TControl) - $component->autoBindProperty($name,$value[1]); - else - $component->setSubProperty($name,$this->_tplControl->evaluateExpression($value[1])); - break; - case self::CONFIG_TEMPLATE: - $component->setSubProperty($name,$value[1]); - break; - case self::CONFIG_ASSET: $url=$this->publishFilePath($this->_contextPath.DIRECTORY_SEPARATOR.$value[1]); - $component->setSubProperty($name,$url); - break; - case self::CONFIG_PARAMETER: $component->setSubProperty($name,$this->getApplication()->getParameters()->itemAt($value[1])); - break; - case self::CONFIG_LOCALIZATION: - $component->setSubProperty($name,Prado::localize($value[1])); - break; - default: throw new TConfigurationException('template_tag_unexpected',$name,$value[1]); - break; - } - } - else - $component->setSubProperty($name,$value); - } - protected function parse($input) - { - $input=$this->preprocess($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; - $matchEnd=0; - $c=0; - $this->_directive=null; - try - { - 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,'<com:')===0) { - if($expectPropEnd) - continue; - if($matchStart>$textStart) - $tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart)); - $textStart=$matchEnd+1; - $type=$match[1][0]; - $attributes=$this->parseAttributes($match[2][0],$match[2][1]); - $this->validateAttributes($type,$attributes); - $tpl[$c++]=array($container,$type,$attributes); - if($str[strlen($str)-2]!=='/') { - $stack[] = $type; - $container=$c-1; - } - } - else if(strpos($str,'</com:')===0) { - if($expectPropEnd) - continue; - if($matchStart>$textStart) - $tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart)); - $textStart=$matchEnd+1; - $type=$match[1][0]; - if(empty($stack)) - throw new TConfigurationException('template_closingtag_unexpected',"</com:$type>"); - $name=array_pop($stack); - if($name!==$type) - { - $tag=$name[0]==='@' ? '</prop:'.substr($name,1).'>' : "</com:$name>"; - throw new TConfigurationException('template_closingtag_expected',$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]) || $this->_directive!==null) - throw new TConfigurationException('template_directive_nonunique'); - $this->_directive=$this->parseAttributes($match[4][0],$match[4][1]); - } - else if(strpos($str,'<%')===0) { - if($expectPropEnd) - continue; - if($matchStart>$textStart) - $tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart)); - $textStart=$matchEnd+1; - $literal=trim($match[5][0]); - if($str[2]==='=') $tpl[$c++]=array($container,array(TCompositeLiteral::TYPE_EXPRESSION,$literal)); - else if($str[2]==='%') $tpl[$c++]=array($container,array(TCompositeLiteral::TYPE_STATEMENTS,$literal)); - else if($str[2]==='#') - $tpl[$c++]=array($container,array(TCompositeLiteral::TYPE_DATABINDING,$literal)); - else if($str[2]==='$') - $tpl[$c++]=array($container,array(TCompositeLiteral::TYPE_EXPRESSION,"\$this->getApplication()->getParameters()->itemAt('$literal')")); - else if($str[2]==='~') - $tpl[$c++]=array($container,array(TCompositeLiteral::TYPE_EXPRESSION,"\$this->publishFilePath('$this->_contextPath/$literal')")); - else if($str[2]==='/') - $tpl[$c++]=array($container,array(TCompositeLiteral::TYPE_EXPRESSION,"rtrim(dirname(\$this->getApplication()->getRequest()->getApplicationUrl()), '/').'/$literal'")); - else if($str[2]==='[') - { - $literal=strtr(trim(substr($literal,0,strlen($literal)-1)),array("'"=>"\'","\\"=>"\\\\")); - $tpl[$c++]=array($container,array(TCompositeLiteral::TYPE_EXPRESSION,"Prado::localize('$literal')")); - } - } - else if(strpos($str,'<prop:')===0) { - if(strrpos($str,'/>')===strlen($str)-2) { - if($expectPropEnd) - continue; - if($matchStart>$textStart) - $tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart)); - $textStart=$matchEnd+1; - $prop=strtolower($match[6][0]); - $attrs=$this->parseAttributes($match[7][0],$match[7][1]); - $attributes=array(); - foreach($attrs as $name=>$value) - $attributes[$prop.'.'.$name]=$value; - $type=$tpl[$container][1]; - $this->validateAttributes($type,$attributes); - foreach($attributes as $name=>$value) - { - if(isset($tpl[$container][2][$name])) - throw new TConfigurationException('template_property_duplicated',$name); - $tpl[$container][2][$name]=$value; - } - } - else { - $prop=strtolower($match[3][0]); - $stack[] = '@'.$prop; - if(!$expectPropEnd) - { - if($matchStart>$textStart) - $tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart)); - $textStart=$matchEnd+1; - $expectPropEnd=true; - } - } - } - else if(strpos($str,'</prop:')===0) { - $prop=strtolower($match[3][0]); - if(empty($stack)) - throw new TConfigurationException('template_closingtag_unexpected',"</prop:$prop>"); - $name=array_pop($stack); - if($name!=='@'.$prop) - { - $tag=$name[0]==='@' ? '</prop:'.substr($name,1).'>' : "</com:$name>"; - throw new TConfigurationException('template_closingtag_expected',$tag); - } - if(($last=count($stack))<1 || $stack[$last-1][0]!=='@') - { - if($matchStart>$textStart) - { - $value=substr($input,$textStart,$matchStart-$textStart); - if(substr($prop,-8,8)==='template') - $value=$this->parseTemplateProperty($value,$textStart); - else - $value=$this->parseAttribute($value); - if($container>=0) - { - $type=$tpl[$container][1]; - $this->validateAttributes($type,array($prop=>$value)); - if(isset($tpl[$container][2][$prop])) - throw new TConfigurationException('template_property_duplicated',$prop); - $tpl[$container][2][$prop]=$value; - } - else $this->_directive[$prop]=$value; - $textStart=$matchEnd+1; - } - $expectPropEnd=false; - } - } - else if(strpos($str,'<!--')===0) { - if($expectPropEnd) - throw new TConfigurationException('template_comments_forbidden'); - if($matchStart>$textStart) - $tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart)); - $textStart=$matchEnd+1; - } - else - throw new TConfigurationException('template_matching_unexpected',$match); - } - if(!empty($stack)) - { - $name=array_pop($stack); - $tag=$name[0]==='@' ? '</prop:'.substr($name,1).'>' : "</com:$name>"; - throw new TConfigurationException('template_closingtag_expected',$tag); - } - if($textStart<strlen($input)) - $tpl[$c++]=array($container,substr($input,$textStart)); - } - catch(Exception $e) - { - if(($e instanceof TException) && ($e instanceof TTemplateException)) - throw $e; - if($matchEnd===0) - $line=$this->_startingLine+1; - else - $line=$this->_startingLine+count(explode("\n",substr($input,0,$matchEnd+1))); - $this->handleException($e,$line,$input); - } - if($this->_directive===null) - $this->_directive=array(); - $objects=array(); - $parent=null; - $merged=array(); - foreach($tpl as $id=>$object) - { - if(isset($object[2]) || $object[0]!==$parent) - { - if($parent!==null) - { - if(count($merged[1])===1 && is_string($merged[1][0])) - $objects[$id-1]=array($merged[0],$merged[1][0]); - else - $objects[$id-1]=array($merged[0],new TCompositeLiteral($merged[1])); - } - if(isset($object[2])) - { - $parent=null; - $objects[$id]=$object; - } - else - { - $parent=$object[0]; - $merged=array($parent,array($object[1])); - } - } - else - $merged[1][]=$object[1]; - } - if($parent!==null) - { - if(count($merged[1])===1 && is_string($merged[1][0])) - $objects[$id]=array($merged[0],$merged[1][0]); - else - $objects[$id]=array($merged[0],new TCompositeLiteral($merged[1])); - } - $tpl=$objects; - return $objects; - } - protected function parseAttributes($str,$offset) - { - if($str==='') - return array(); - $pattern='/([\w\.\-]+)\s*=\s*(\'.*?\'|".*?"|<%.*?%>)/msS'; - $attributes=array(); - $n=preg_match_all($pattern,$str,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE); - for($i=0;$i<$n;++$i) - { - $match=&$matches[$i]; - $name=strtolower($match[1][0]); - if(isset($attributes[$name])) - throw new TConfigurationException('template_property_duplicated',$name); - $value=$match[2][0]; - if(substr($name,-8,8)==='template') - { - if($value[0]==='\'' || $value[0]==='"') - $attributes[$name]=$this->parseTemplateProperty(substr($value,1,strlen($value)-2),$match[2][1]+1); - else - $attributes[$name]=$this->parseTemplateProperty($value,$match[2][1]); - } - else - { - if($value[0]==='\'' || $value[0]==='"') - $attributes[$name]=$this->parseAttribute(substr($value,1,strlen($value)-2)); - else - $attributes[$name]=$this->parseAttribute($value); - } - } - return $attributes; - } - protected function parseTemplateProperty($content,$offset) - { - $line=$this->_startingLine+count(explode("\n",substr($this->_content,0,$offset)))-1; - return array(self::CONFIG_TEMPLATE,new TTemplate($content,$this->_contextPath,$this->_tplFile,$line,false)); - } - protected function parseAttribute($value) - { - if(($n=preg_match_all('/<%[#=].*?%>/msS',$value,$matches,PREG_OFFSET_CAPTURE))>0) - { - $isDataBind=false; - $textStart=0; - $expr=''; - for($i=0;$i<$n;++$i) - { - $match=$matches[0][$i]; - $token=$match[0]; - $offset=$match[1]; - $length=strlen($token); - if($token[2]==='#') - $isDataBind=true; - if($offset>$textStart) - $expr.=".'".strtr(substr($value,$textStart,$offset-$textStart),array("'"=>"\\'","\\"=>"\\\\"))."'"; - $expr.='.('.substr($token,3,$length-5).')'; - $textStart=$offset+$length; - } - $length=strlen($value); - if($length>$textStart) - $expr.=".'".strtr(substr($value,$textStart,$length-$textStart),array("'"=>"\\'","\\"=>"\\\\"))."'"; - if($isDataBind) - return array(self::CONFIG_DATABIND,ltrim($expr,'.')); - else - return array(self::CONFIG_EXPRESSION,ltrim($expr,'.')); - } - else if(preg_match('/\\s*(<%~.*?%>|<%\\$.*?%>|<%\\[.*?\\]%>|<%\/.*?%>)\\s*/msS',$value,$matches) && $matches[0]===$value) - { - $value=$matches[1]; - if($value[2]==='~') - return array(self::CONFIG_ASSET,trim(substr($value,3,strlen($value)-5))); - elseif($value[2]==='[') - return array(self::CONFIG_LOCALIZATION,trim(substr($value,3,strlen($value)-6))); - elseif($value[2]==='$') - return array(self::CONFIG_PARAMETER,trim(substr($value,3,strlen($value)-5))); - elseif($value[2]==='/') { - $literal = trim(substr($value,3,strlen($value)-5)); - return array(self::CONFIG_EXPRESSION,"rtrim(dirname(\$this->getApplication()->getRequest()->getApplicationUrl()), '/').'/$literal'"); - } - } - else - return $value; - } - protected function validateAttributes($type,$attributes) - { - Prado::using($type); - if(($pos=strrpos($type,'.'))!==false) - $className=substr($type,$pos+1); - else - $className=$type; - $class=new ReflectionClass($className); - if(is_subclass_of($className,'TControl') || $className==='TControl') - { - foreach($attributes as $name=>$att) - { - if(($pos=strpos($name,'.'))!==false) - { - $subname=substr($name,0,$pos); - if(!$class->hasMethod('get'.$subname)) - throw new TConfigurationException('template_property_unknown',$type,$subname); - } - else if(strncasecmp($name,'on',2)===0) - { - if(!$class->hasMethod($name)) - throw new TConfigurationException('template_event_unknown',$type,$name); - else if(!is_string($att)) - throw new TConfigurationException('template_eventhandler_invalid',$type,$name); - } - else - { - if (! ($class->hasMethod('set'.$name) || $class->hasMethod('setjs'.$name)) ) - { - if ($class->hasMethod('get'.$name) || $class->hasMethod('getjs'.$name)) - throw new TConfigurationException('template_property_readonly',$type,$name); - else - throw new TConfigurationException('template_property_unknown',$type,$name); - } - else if(is_array($att) && $att[0]!==self::CONFIG_EXPRESSION) - { - if(strcasecmp($name,'id')===0) - throw new TConfigurationException('template_controlid_invalid',$type); - else if(strcasecmp($name,'skinid')===0) - throw new TConfigurationException('template_controlskinid_invalid',$type); - } - } - } - } - else if(is_subclass_of($className,'TComponent') || $className==='TComponent') - { - foreach($attributes as $name=>$att) - { - if(is_array($att) && ($att[0]===self::CONFIG_DATABIND)) - throw new TConfigurationException('template_databind_forbidden',$type,$name); - if(($pos=strpos($name,'.'))!==false) - { - $subname=substr($name,0,$pos); - if(!$class->hasMethod('get'.$subname)) - throw new TConfigurationException('template_property_unknown',$type,$subname); - } - else if(strncasecmp($name,'on',2)===0) - throw new TConfigurationException('template_event_forbidden',$type,$name); - else - { - if(strcasecmp($name,'id')!==0 && !$class->hasMethod('set'.$name)) - { - if($class->hasMethod('get'.$name)) - throw new TConfigurationException('template_property_readonly',$type,$name); - else - throw new TConfigurationException('template_property_unknown',$type,$name); - } - } - } - } - else - throw new TConfigurationException('template_component_required',$type); - } - public function getIncludedFiles() - { - return $this->_includedFiles; - } - protected function handleException($e,$line,$input=null) - { - $srcFile=$this->_tplFile; - if(($n=count($this->_includedFiles))>0) { - for($i=$n-1;$i>=0;--$i) - { - if($this->_includeAtLine[$i]<=$line) - { - if($line<$this->_includeAtLine[$i]+$this->_includeLines[$i]) - { - $line=$line-$this->_includeAtLine[$i]+1; - $srcFile=$this->_includedFiles[$i]; - break; - } - else - $line=$line-$this->_includeLines[$i]+1; - } - } - } - $exception=new TTemplateException('template_format_invalid',$e->getMessage()); - $exception->setLineNumber($line); - if(!empty($srcFile)) - $exception->setTemplateFile($srcFile); - else - $exception->setTemplateSource($input); - throw $exception; - } - protected function preprocess($input) - { - if($n=preg_match_all('/<%include(.*?)%>/',$input,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE)) - { - for($i=0;$i<$n;++$i) - { - $filePath=Prado::getPathOfNamespace(trim($matches[$i][1][0]),TTemplateManager::TEMPLATE_FILE_EXT); - if($filePath!==null && is_file($filePath)) - $this->_includedFiles[]=$filePath; - else - { - $errorLine=count(explode("\n",substr($input,0,$matches[$i][0][1]+1))); - $this->handleException(new TConfigurationException('template_include_invalid',trim($matches[$i][1][0])),$errorLine,$input); - } - } - $base=0; - for($i=0;$i<$n;++$i) - { - $ext=file_get_contents($this->_includedFiles[$i]); - $length=strlen($matches[$i][0][0]); - $offset=$base+$matches[$i][0][1]; - $this->_includeAtLine[$i]=count(explode("\n",substr($input,0,$offset))); - $this->_includeLines[$i]=count(explode("\n",$ext)); - $input=substr_replace($input,$ext,$offset,$length); - $base+=strlen($ext)-$length; - } - } - return $input; - } -} -class TThemeManager extends TModule -{ - const DEFAULT_BASEPATH='themes'; - const DEFAULT_THEMECLASS = 'TTheme'; - private $_themeClass=self::DEFAULT_THEMECLASS; - private $_initialized=false; - private $_basePath=null; - private $_baseUrl=null; - public function init($config) - { - $this->_initialized=true; - $service=$this->getService(); - if($service instanceof TPageService) - $service->setThemeManager($this); - else - throw new TConfigurationException('thememanager_service_unavailable'); - } - public function getTheme($name) - { - $themePath=$this->getBasePath().DIRECTORY_SEPARATOR.$name; - $themeUrl=rtrim($this->getBaseUrl(),'/').'/'.$name; - return Prado::createComponent($this->getThemeClass(), $themePath, $themeUrl); - } - public function setThemeClass($class) { - $this->_themeClass = $class===null ? self::DEFAULT_THEMECLASS : (string)$class; - } - public function getThemeClass() { - return $this->_themeClass; - } - public function getAvailableThemes() - { - $themes=array(); - $basePath=$this->getBasePath(); - $folder=@opendir($basePath); - while($file=@readdir($folder)) - { - if($file!=='.' && $file!=='..' && $file!=='.svn' && is_dir($basePath.DIRECTORY_SEPARATOR.$file)) - $themes[]=$file; - } - closedir($folder); - return $themes; - } - public function getBasePath() - { - if($this->_basePath===null) - { - $this->_basePath=dirname($this->getRequest()->getApplicationFilePath()).DIRECTORY_SEPARATOR.self::DEFAULT_BASEPATH; - if(($basePath=realpath($this->_basePath))===false || !is_dir($basePath)) - throw new TConfigurationException('thememanager_basepath_invalid2',$this->_basePath); - $this->_basePath=$basePath; - } - return $this->_basePath; - } - public function setBasePath($value) - { - if($this->_initialized) - throw new TInvalidOperationException('thememanager_basepath_unchangeable'); - else - { - $this->_basePath=Prado::getPathOfNamespace($value); - if($this->_basePath===null || !is_dir($this->_basePath)) - throw new TInvalidDataValueException('thememanager_basepath_invalid',$value); - } - } - public function getBaseUrl() - { - if($this->_baseUrl===null) - { - $appPath=dirname($this->getRequest()->getApplicationFilePath()); - $basePath=$this->getBasePath(); - if(strpos($basePath,$appPath)===false) - throw new TConfigurationException('thememanager_baseurl_required'); - $appUrl=rtrim(dirname($this->getRequest()->getApplicationUrl()),'/\\'); - $this->_baseUrl=$appUrl.strtr(substr($basePath,strlen($appPath)),'\\','/'); - } - return $this->_baseUrl; - } - public function setBaseUrl($value) - { - $this->_baseUrl=rtrim($value,'/'); - } -} -class TTheme extends TApplicationComponent implements ITheme -{ - const THEME_CACHE_PREFIX='prado:theme:'; - const SKIN_FILE_EXT='.skin'; - private $_themePath; - private $_themeUrl; - private $_skins=null; - private $_name=''; - private $_cssFiles=array(); - private $_jsFiles=array(); - public function __construct($themePath,$themeUrl) - { - $this->_themeUrl=$themeUrl; - $this->_themePath=realpath($themePath); - $this->_name=basename($themePath); - $cacheValid=false; - if(($cache=$this->getApplication()->getCache())!==null) - { - $array=$cache->get(self::THEME_CACHE_PREFIX.$themePath); - if(is_array($array)) - { - list($skins,$cssFiles,$jsFiles,$timestamp)=$array; - if($this->getApplication()->getMode()!==TApplicationMode::Performance) - { - if(($dir=opendir($themePath))===false) - throw new TIOException('theme_path_inexistent',$themePath); - $cacheValid=true; - while(($file=readdir($dir))!==false) - { - if($file==='.' || $file==='..') - continue; - else if(basename($file,'.css')!==$file) - $this->_cssFiles[]=$themeUrl.'/'.$file; - else if(basename($file,'.js')!==$file) - $this->_jsFiles[]=$themeUrl.'/'.$file; - else if(basename($file,self::SKIN_FILE_EXT)!==$file && filemtime($themePath.DIRECTORY_SEPARATOR.$file)>$timestamp) - { - $cacheValid=false; - break; - } - } - closedir($dir); - if($cacheValid) - $this->_skins=$skins; - } - else - { - $cacheValid=true; - $this->_cssFiles=$cssFiles; - $this->_jsFiles=$jsFiles; - $this->_skins=$skins; - } - } - } - if(!$cacheValid) - { - $this->_cssFiles=array(); - $this->_jsFiles=array(); - $this->_skins=array(); - if(($dir=opendir($themePath))===false) - throw new TIOException('theme_path_inexistent',$themePath); - while(($file=readdir($dir))!==false) - { - if($file==='.' || $file==='..') - continue; - else if(basename($file,'.css')!==$file) - $this->_cssFiles[]=$themeUrl.'/'.$file; - else if(basename($file,'.js')!==$file) - $this->_jsFiles[]=$themeUrl.'/'.$file; - else if(basename($file,self::SKIN_FILE_EXT)!==$file) - { - $template=new TTemplate(file_get_contents($themePath.'/'.$file),$themePath,$themePath.'/'.$file); - foreach($template->getItems() as $skin) - { - if(!isset($skin[2])) continue; - else if($skin[0]!==-1) - throw new TConfigurationException('theme_control_nested',$skin[1],dirname($themePath)); - $type=$skin[1]; - $id=isset($skin[2]['skinid'])?$skin[2]['skinid']:0; - unset($skin[2]['skinid']); - if(isset($this->_skins[$type][$id])) - throw new TConfigurationException('theme_skinid_duplicated',$type,$id,dirname($themePath)); - $this->_skins[$type][$id]=$skin[2]; - } - } - } - closedir($dir); - sort($this->_cssFiles); - sort($this->_jsFiles); - if($cache!==null) - $cache->set(self::THEME_CACHE_PREFIX.$themePath,array($this->_skins,$this->_cssFiles,$this->_jsFiles,time())); - } - } - public function getName() - { - return $this->_name; - } - protected function setName($value) - { - $this->_name = $value; - } - public function getBaseUrl() - { - return $this->_themeUrl; - } - protected function setBaseUrl($value) - { - $this->_themeUrl=rtrim($value,'/'); - } - public function getBasePath() - { - return $this->_themePath; - } - protected function setBasePath($value) - { - $this->_themePath=$value; - } - public function getSkins() - { - return $this->_skins; - } - protected function setSkins($value) - { - $this->_skins = $value; - } - public function applySkin($control) - { - $type=get_class($control); - if(($id=$control->getSkinID())==='') - $id=0; - if(isset($this->_skins[$type][$id])) - { - foreach($this->_skins[$type][$id] as $name=>$value) - { - if(is_array($value)) - { - switch($value[0]) - { - case TTemplate::CONFIG_EXPRESSION: - $value=$this->evaluateExpression($value[1]); - break; - case TTemplate::CONFIG_ASSET: - $value=$this->_themeUrl.'/'.ltrim($value[1],'/'); - break; - case TTemplate::CONFIG_DATABIND: - $control->bindProperty($name,$value[1]); - break; - case TTemplate::CONFIG_PARAMETER: - $control->setSubProperty($name,$this->getApplication()->getParameters()->itemAt($value[1])); - break; - case TTemplate::CONFIG_TEMPLATE: - $control->setSubProperty($name,$value[1]); - break; - case TTemplate::CONFIG_LOCALIZATION: - $control->setSubProperty($name,Prado::localize($value[1])); - break; - default: - throw new TConfigurationException('theme_tag_unexpected',$name,$value[0]); - break; - } - } - if(!is_array($value)) - { - if(strpos($name,'.')===false) { - if($control->hasProperty($name)) - { - if($control->canSetProperty($name)) - { - $setter='set'.$name; - $control->$setter($value); - } - else - throw new TConfigurationException('theme_property_readonly',$type,$name); - } - else - throw new TConfigurationException('theme_property_undefined',$type,$name); - } - else $control->setSubProperty($name,$value); - } - } - return true; - } - else - return false; - } - public function getStyleSheetFiles() - { - return $this->_cssFiles; - } - protected function setStyleSheetFiles($value) - { - $this->_cssFiles=$value; - } - public function getJavaScriptFiles() - { - return $this->_jsFiles; - } - protected function setJavaScriptFiles($value) - { - $this->_jsFiles=$value; - } -} -class TPageService extends TService -{ - const CONFIG_FILE_XML='config.xml'; - const CONFIG_FILE_PHP='config.php'; - const DEFAULT_BASEPATH='Pages'; - const FALLBACK_BASEPATH='pages'; - const CONFIG_CACHE_PREFIX='prado:pageservice:'; - const PAGE_FILE_EXT='.page'; - private $_basePath=null; - private $_basePageClass='TPage'; - private $_clientScriptManagerClass='System.Web.UI.TClientScriptManager'; - private $_defaultPage='Home'; - private $_pagePath=null; - private $_page=null; - private $_properties=array(); - private $_initialized=false; - private $_themeManager=null; - private $_templateManager=null; - public function init($config) - { - $pageConfig=$this->loadPageConfig($config); - $this->initPageContext($pageConfig); - $this->_initialized=true; - } - protected function initPageContext($pageConfig) - { - $application=$this->getApplication(); - foreach($pageConfig->getApplicationConfigurations() as $appConfig) - $application->applyConfiguration($appConfig); - $this->applyConfiguration($pageConfig); - } - protected function applyConfiguration($config) - { - $this->_properties=array_merge($this->_properties, $config->getProperties()); - $this->getApplication()->getAuthorizationRules()->mergeWith($config->getRules()); - $pagePath=$this->getRequestedPagePath(); - foreach($config->getExternalConfigurations() as $filePath=>$params) - { - list($configPagePath,$condition)=$params; - if($condition!==true) - $condition=$this->evaluateExpression($condition); - if($condition) - { - if(($path=Prado::getPathOfNamespace($filePath,Prado::getApplication()->getConfigurationFileExt()))===null || !is_file($path)) - throw new TConfigurationException('pageservice_includefile_invalid',$filePath); - $c=new TPageConfiguration($pagePath); - $c->loadFromFile($path,$configPagePath); - $this->applyConfiguration($c); - } - } - } - protected function determineRequestedPagePath() - { - $pagePath=$this->getRequest()->getServiceParameter(); - if(empty($pagePath)) - $pagePath=$this->getDefaultPage(); - return $pagePath; - } - protected function loadPageConfig($config) - { - $application=$this->getApplication(); - $pagePath=$this->getRequestedPagePath(); - if(($cache=$application->getCache())===null) - { - $pageConfig=new TPageConfiguration($pagePath); - if($config!==null) - { - if($application->getConfigurationType()==TApplication::CONFIG_TYPE_PHP) - $pageConfig->loadPageConfigurationFromPhp($config,$application->getBasePath(),''); - else - $pageConfig->loadPageConfigurationFromXml($config,$application->getBasePath(),''); - } - $pageConfig->loadFromFiles($this->getBasePath()); - } - else - { - $configCached=true; - $currentTimestamp=array(); - $arr=$cache->get(self::CONFIG_CACHE_PREFIX.$this->getID().$pagePath); - if(is_array($arr)) - { - list($pageConfig,$timestamps)=$arr; - if($application->getMode()!==TApplicationMode::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('.',$pagePath); - $configPath=$this->getBasePath(); - $fileName = $this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP - ? self::CONFIG_FILE_PHP - : self::CONFIG_FILE_XML; - foreach($paths as $path) - { - $configFile=$configPath.DIRECTORY_SEPARATOR.$fileName; - $currentTimestamp[$configFile]=@filemtime($configFile); - $configPath.=DIRECTORY_SEPARATOR.$path; - } - $appConfigFile=$application->getConfigurationFile(); - $currentTimestamp[0]=$appConfigFile===null?0:@filemtime($appConfigFile); - } - if(!$configCached) - { - $pageConfig=new TPageConfiguration($pagePath); - if($config!==null) - { - if($application->getConfigurationType()==TApplication::CONFIG_TYPE_PHP) - $pageConfig->loadPageConfigurationFromPhp($config,$application->getBasePath(),''); - else - $pageConfig->loadPageConfigurationFromXml($config,$application->getBasePath(),''); - } - $pageConfig->loadFromFiles($this->getBasePath()); - $cache->set(self::CONFIG_CACHE_PREFIX.$this->getID().$pagePath,array($pageConfig,$currentTimestamp)); - } - } - return $pageConfig; - } - 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 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 getRequestedPagePath() - { - if($this->_pagePath===null) - { - $this->_pagePath=strtr($this->determineRequestedPagePath(),'/\\','..'); - if(empty($this->_pagePath)) - throw new THttpException(404,'pageservice_page_required'); - } - 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 getDefaultPageUrl() - { - return $this->constructUrl($this->getDefaultPage()); - } - public function getBasePath() - { - if($this->_basePath===null) - { - $basePath=$this->getApplication()->getBasePath().DIRECTORY_SEPARATOR.self::DEFAULT_BASEPATH; - if(($this->_basePath=realpath($basePath))===false || !is_dir($this->_basePath)) - { - $basePath=$this->getApplication()->getBasePath().DIRECTORY_SEPARATOR.self::FALLBACK_BASEPATH; - if(($this->_basePath=realpath($basePath))===false || !is_dir($this->_basePath)) - throw new TConfigurationException('pageservice_basepath_invalid',$basePath); - } - } - return $this->_basePath; - } - public function setBasePath($value) - { - if($this->_initialized) - throw new TInvalidOperationException('pageservice_basepath_unchangeable'); - else if(($path=Prado::getPathOfNamespace($value))===null || !is_dir($path)) - throw new TConfigurationException('pageservice_basepath_invalid',$value); - $this->_basePath=realpath($path); - } - public function setBasePageClass($value) - { - $this->_basePageClass=$value; - } - public function getBasePageClass() - { - return $this->_basePageClass; - } - public function setClientScriptManagerClass($value) - { - $this->_clientScriptManagerClass=$value; - } - public function getClientScriptManagerClass() - { - return $this->_clientScriptManagerClass; - } - public function run() - { - $this->_page=$this->createPage($this->getRequestedPagePath()); - $this->runPage($this->_page,$this->_properties); - } - protected function createPage($pagePath) - { - $path=$this->getBasePath().DIRECTORY_SEPARATOR.strtr($pagePath,'.',DIRECTORY_SEPARATOR); - $hasTemplateFile=is_file($path.self::PAGE_FILE_EXT); - $hasClassFile=is_file($path.Prado::CLASS_FILE_EXT); - if(!$hasTemplateFile && !$hasClassFile) - throw new THttpException(404,'pageservice_page_unknown',$pagePath); - if($hasClassFile) - { - $className=basename($path); - if(!class_exists($className,false)) - include_once($path.Prado::CLASS_FILE_EXT); - } - else - { - $className=$this->getBasePageClass(); - Prado::using($className); - if(($pos=strrpos($className,'.'))!==false) - $className=substr($className,$pos+1); - } - if(!class_exists($className,false) || ($className!=='TPage' && !is_subclass_of($className,'TPage'))) - throw new THttpException(404,'pageservice_page_unknown',$pagePath); - $page=new $className; - $page->setPagePath($pagePath); - if($hasTemplateFile) - $page->setTemplate($this->getTemplateManager()->getTemplateByFileName($path.self::PAGE_FILE_EXT)); - return $page; - } - protected function runPage($page,$properties) - { - foreach($properties as $name=>$value) - $page->setSubProperty($name,$value); - $page->run($this->getResponse()->createHtmlWriter()); - } - public function constructUrl($pagePath,$getParams=null,$encodeAmpersand=true,$encodeGetItems=true) - { - return $this->getRequest()->constructUrl($this->getID(),$pagePath,$getParams,$encodeAmpersand,$encodeGetItems); - } -} -class TPageConfiguration extends TComponent -{ - private $_appConfigs=array(); - private $_properties=array(); - private $_rules=array(); - private $_includes=array(); - private $_pagePath=''; - public function __construct($pagePath) - { - $this->_pagePath=$pagePath; - } - public function getExternalConfigurations() - { - return $this->_includes; - } - public function getProperties() - { - return $this->_properties; - } - public function getRules() - { - return $this->_rules; - } - public function getApplicationConfigurations() - { - return $this->_appConfigs; - } - public function loadFromFiles($basePath) - { - $paths=explode('.',$this->_pagePath); - $page=array_pop($paths); - $path=$basePath; - $configPagePath=''; - $fileName = Prado::getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP - ? TPageService::CONFIG_FILE_PHP - : TPageService::CONFIG_FILE_XML; - foreach($paths as $p) - { - $this->loadFromFile($path.DIRECTORY_SEPARATOR.$fileName,$configPagePath); - $path.=DIRECTORY_SEPARATOR.$p; - if($configPagePath==='') - $configPagePath=$p; - else - $configPagePath.='.'.$p; - } - $this->loadFromFile($path.DIRECTORY_SEPARATOR.$fileName,$configPagePath); - $this->_rules=new TAuthorizationRuleCollection($this->_rules); - } - public function loadFromFile($fname,$configPagePath) - { - if(empty($fname) || !is_file($fname)) - return; - if(Prado::getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP) - { - $fcontent = include $fname; - $this->loadFromPhp($fcontent,dirname($fname),$configPagePath); - } - else - { - $dom=new TXmlDocument; - if($dom->loadFromFile($fname)) - $this->loadFromXml($dom,dirname($fname),$configPagePath); - else - throw new TConfigurationException('pageserviceconf_file_invalid',$fname); - } - } - public function loadFromPhp($config,$configPath,$configPagePath) - { - $this->loadApplicationConfigurationFromPhp($config,$configPath); - $this->loadPageConfigurationFromPhp($config,$configPath,$configPagePath); - } - public function loadFromXml($dom,$configPath,$configPagePath) - { - $this->loadApplicationConfigurationFromXml($dom,$configPath); - $this->loadPageConfigurationFromXml($dom,$configPath,$configPagePath); - } - public function loadApplicationConfigurationFromPhp($config,$configPath) - { - $appConfig=new TApplicationConfiguration; - $appConfig->loadFromPhp($config,$configPath); - $this->_appConfigs[]=$appConfig; - } - public function loadApplicationConfigurationFromXml($dom,$configPath) - { - $appConfig=new TApplicationConfiguration; - $appConfig->loadFromXml($dom,$configPath); - $this->_appConfigs[]=$appConfig; - } - public function loadPageConfigurationFromPhp($config, $configPath, $configPagePath) - { - if(isset($config['authorization']) && is_array($config['authorization'])) - { - $rules = array(); - foreach($config['authorization'] as $authorization) - { - $patterns=isset($authorization['pages'])?$authorization['pages']:''; - $ruleApplies=false; - if(empty($patterns) || trim($patterns)==='*') $ruleApplies=true; - else - { - foreach(explode(',',$patterns) as $pattern) - { - if(($pattern=trim($pattern))!=='') - { - if($configPagePath!=='') $pattern=$configPagePath.'.'.$pattern; - if(strcasecmp($pattern,$this->_pagePath)===0) - { - $ruleApplies=true; - break; - } - if($pattern[strlen($pattern)-1]==='*') { - if(strncasecmp($this->_pagePath,$pattern,strlen($pattern)-1)===0) - { - $ruleApplies=true; - break; - } - } - } - } - } - if($ruleApplies) - { - $action = isset($authorization['action'])?$authorization['action']:''; - $users = isset($authorization['users'])?$authorization['users']:''; - $roles = isset($authorization['roles'])?$authorization['roles']:''; - $verb = isset($authorization['verb'])?$authorization['verb']:''; - $ips = isset($authorization['ips'])?$authorization['ips']:''; - $rules[]=new TAuthorizationRule($action,$users,$roles,$verb,$ips); - } - } - $this->_rules=array_merge($rules,$this->_rules); - } - if(isset($config['pages']) && is_array($config['pages'])) - { - if(isset($config['pages']['properties'])) - { - $this->_properties = array_merge($this->_properties, $config['pages']['properties']); - unset($config['pages']['properties']); - } - foreach($config['pages'] as $id => $page) - { - $properties = array(); - if(isset($page['properties'])) - { - $properties=$page['properties']; - unset($page['properties']); - } - $matching=false; - $id=($configPagePath==='')?$id:$configPagePath.'.'.$id; - if(strcasecmp($id,$this->_pagePath)===0) - $matching=true; - else if($id[strlen($id)-1]==='*') $matching=strncasecmp($this->_pagePath,$id,strlen($id)-1)===0; - if($matching) - $this->_properties=array_merge($this->_properties,$properties); - } - } - if(isset($config['includes']) && is_array($config['includes'])) - { - foreach($config['includes'] as $include) - { - $when = isset($include['when'])?true:false; - if(!isset($include['file'])) - throw new TConfigurationException('pageserviceconf_includefile_required'); - $filePath = $include['file']; - if(isset($this->_includes[$filePath])) - $this->_includes[$filePath]=array($configPagePath,'('.$this->_includes[$filePath][1].') || ('.$when.')'); - else - $this->_includes[$filePath]=array($configPagePath,$when); - } - } - } - public function loadPageConfigurationFromXml($dom,$configPath,$configPagePath) - { - if(($authorizationNode=$dom->getElementByTagName('authorization'))!==null) - { - $rules=array(); - foreach($authorizationNode->getElements() as $node) - { - $patterns=$node->getAttribute('pages'); - $ruleApplies=false; - if(empty($patterns) || trim($patterns)==='*') $ruleApplies=true; - else - { - foreach(explode(',',$patterns) as $pattern) - { - if(($pattern=trim($pattern))!=='') - { - if($configPagePath!=='') $pattern=$configPagePath.'.'.$pattern; - if(strcasecmp($pattern,$this->_pagePath)===0) - { - $ruleApplies=true; - break; - } - if($pattern[strlen($pattern)-1]==='*') { - if(strncasecmp($this->_pagePath,$pattern,strlen($pattern)-1)===0) - { - $ruleApplies=true; - break; - } - } - } - } - } - if($ruleApplies) - $rules[]=new TAuthorizationRule($node->getTagName(),$node->getAttribute('users'),$node->getAttribute('roles'),$node->getAttribute('verb'),$node->getAttribute('ips')); - } - $this->_rules=array_merge($rules,$this->_rules); - } - if(($pagesNode=$dom->getElementByTagName('pages'))!==null) - { - $this->_properties=array_merge($this->_properties,$pagesNode->getAttributes()->toArray()); - foreach($pagesNode->getElementsByTagName('page') as $node) - { - $properties=$node->getAttributes(); - $id=$properties->remove('id'); - if(empty($id)) - throw new TConfigurationException('pageserviceconf_page_invalid',$configPath); - $matching=false; - $id=($configPagePath==='')?$id:$configPagePath.'.'.$id; - if(strcasecmp($id,$this->_pagePath)===0) - $matching=true; - else if($id[strlen($id)-1]==='*') $matching=strncasecmp($this->_pagePath,$id,strlen($id)-1)===0; - if($matching) - $this->_properties=array_merge($this->_properties,$properties->toArray()); - } - } - foreach($dom->getElementsByTagName('include') as $node) - { - if(($when=$node->getAttribute('when'))===null) - $when=true; - if(($filePath=$node->getAttribute('file'))===null) - throw new TConfigurationException('pageserviceconf_includefile_required'); - if(isset($this->_includes[$filePath])) - $this->_includes[$filePath]=array($configPagePath,'('.$this->_includes[$filePath][1].') || ('.$when.')'); - else - $this->_includes[$filePath]=array($configPagePath,$when); - } - } -} -class TAssetManager extends TModule -{ - const DEFAULT_BASEPATH='assets'; - private $_basePath=null; - private $_baseUrl=null; - private $_checkTimestamp=false; - private $_application; - private $_published=array(); - private $_initialized=false; - public function init($config) - { - $application=$this->getApplication(); - if($this->_basePath===null) - $this->_basePath=dirname($application->getRequest()->getApplicationFilePath()).DIRECTORY_SEPARATOR.self::DEFAULT_BASEPATH; - if(!is_writable($this->_basePath) || !is_dir($this->_basePath)) - throw new TConfigurationException('assetmanager_basepath_invalid',$this->_basePath); - if($this->_baseUrl===null) - $this->_baseUrl=rtrim(dirname($application->getRequest()->getApplicationUrl()),'/\\').'/'.self::DEFAULT_BASEPATH; - $application->setAssetManager($this); - $this->_initialized=true; - } - public function getBasePath() - { - return $this->_basePath; - } - public function setBasePath($value) - { - if($this->_initialized) - throw new TInvalidOperationException('assetmanager_basepath_unchangeable'); - else - { - $this->_basePath=Prado::getPathOfNamespace($value); - if($this->_basePath===null || !is_dir($this->_basePath) || !is_writable($this->_basePath)) - throw new TInvalidDataValueException('assetmanager_basepath_invalid',$value); - } - } - public function getBaseUrl() - { - return $this->_baseUrl; - } - public function setBaseUrl($value) - { - if($this->_initialized) - throw new TInvalidOperationException('assetmanager_baseurl_unchangeable'); - else - $this->_baseUrl=rtrim($value,'/'); - } - public function publishFilePath($path,$checkTimestamp=false) - { - if(isset($this->_published[$path])) - return $this->_published[$path]; - else if(empty($path) || ($fullpath=realpath($path))===false) - throw new TInvalidDataValueException('assetmanager_filepath_invalid',$path); - else if(is_file($fullpath)) - { - $dir=$this->hash(dirname($fullpath)); - $fileName=basename($fullpath); - $dst=$this->_basePath.DIRECTORY_SEPARATOR.$dir; - if(!is_file($dst.DIRECTORY_SEPARATOR.$fileName) || $checkTimestamp || $this->getApplication()->getMode()!==TApplicationMode::Performance) - $this->copyFile($fullpath,$dst); - return $this->_published[$path]=$this->_baseUrl.'/'.$dir.'/'.$fileName; - } - else - { - $dir=$this->hash($fullpath); - if(!is_dir($this->_basePath.DIRECTORY_SEPARATOR.$dir) || $checkTimestamp || $this->getApplication()->getMode()!==TApplicationMode::Performance) - { - $this->copyDirectory($fullpath,$this->_basePath.DIRECTORY_SEPARATOR.$dir); - } - return $this->_published[$path]=$this->_baseUrl.'/'.$dir; - } - } - public function getPublished() - { - return $this->_published; - } - protected function setPublished($values=array()) - { - $this->_published = $values; - } - public function getPublishedPath($path) - { - $path=realpath($path); - if(is_file($path)) - return $this->_basePath.DIRECTORY_SEPARATOR.$this->hash(dirname($path)).DIRECTORY_SEPARATOR.basename($path); - else - return $this->_basePath.DIRECTORY_SEPARATOR.$this->hash($path); - } - public function getPublishedUrl($path) - { - $path=realpath($path); - if(is_file($path)) - return $this->_baseUrl.'/'.$this->hash(dirname($path)).'/'.basename($path); - else - return $this->_baseUrl.'/'.$this->hash($path); - } - protected function hash($dir) - { - return sprintf('%x',crc32($dir.Prado::getVersion())); - } - protected function copyFile($src,$dst) - { - if(!is_dir($dst)) - { - @mkdir($dst); - @chmod($dst, PRADO_CHMOD); - } - $dstFile=$dst.DIRECTORY_SEPARATOR.basename($src); - if(@filemtime($dstFile)<@filemtime($src)) - { - @copy($src,$dstFile); - } - } - public function copyDirectory($src,$dst) - { - if(!is_dir($dst)) - { - @mkdir($dst); - @chmod($dst, PRADO_CHMOD); - } - if($folder=@opendir($src)) - { - while($file=@readdir($folder)) - { - if($file==='.' || $file==='..' || $file==='.svn') - continue; - else if(is_file($src.DIRECTORY_SEPARATOR.$file)) - { - if(@filemtime($dst.DIRECTORY_SEPARATOR.$file)<@filemtime($src.DIRECTORY_SEPARATOR.$file)) - { - @copy($src.DIRECTORY_SEPARATOR.$file,$dst.DIRECTORY_SEPARATOR.$file); - @chmod($dst.DIRECTORY_SEPARATOR.$file, PRADO_CHMOD); - } - } - else - $this->copyDirectory($src.DIRECTORY_SEPARATOR.$file,$dst.DIRECTORY_SEPARATOR.$file); - } - closedir($folder); - } else { - throw new TInvalidDataValueException('assetmanager_source_directory_invalid', $src); - } - } - public function publishTarFile($tarfile, $md5sum, $checkTimestamp=false) - { - if(isset($this->_published[$md5sum])) - return $this->_published[$md5sum]; - else if(($fullpath=realpath($md5sum))===false || !is_file($fullpath)) - throw new TInvalidDataValueException('assetmanager_tarchecksum_invalid',$md5sum); - else - { - $dir=$this->hash(dirname($fullpath)); - $fileName=basename($fullpath); - $dst=$this->_basePath.DIRECTORY_SEPARATOR.$dir; - if(!is_file($dst.DIRECTORY_SEPARATOR.$fileName) || $checkTimestamp || $this->getApplication()->getMode()!==TApplicationMode::Performance) - { - if(@filemtime($dst.DIRECTORY_SEPARATOR.$fileName)<@filemtime($fullpath)) - { - $this->copyFile($fullpath,$dst); - $this->deployTarFile($tarfile,$dst); - } - } - return $this->_published[$md5sum]=$this->_baseUrl.'/'.$dir; - } - } - protected function deployTarFile($path,$destination) - { - if(($fullpath=realpath($path))===false || !is_file($fullpath)) - throw new TIOException('assetmanager_tarfile_invalid',$path); - else - { - Prado::using('System.IO.TTarFileExtractor'); - $tar = new TTarFileExtractor($fullpath); - return $tar->extract($destination); - } - } -} -class TGlobalization extends TModule -{ - private $_defaultCharset = 'UTF-8'; - private $_defaultCulture = 'en'; - private $_charset=null; - private $_culture=null; - private $_translation; - private $_translateDefaultCulture=true; - public function init($config) - { - if($this->_charset===null) - $this->_charset=$this->getDefaultCharset(); - if($this->_culture===null) - $this->_culture=$this->getDefaultCulture(); - if($config!==null) - { - if($this->getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP) - $translation = isset($config['translate'])?$config['translate']:null; - else - { - $t = $config->getElementByTagName('translation'); - $translation = ($t)?$t->getAttributes():null; - } - if($translation) - $this->setTranslationConfiguration($translation); - } - $this->getApplication()->setGlobalization($this); - } - public function getTranslateDefaultCulture() - { - return $this->_translateDefaultCulture; - } - public function setTranslateDefaultCulture($value) - { - $this->_translateDefaultCulture = TPropertyValue::ensureBoolean($value); - } - public function getDefaultCulture() - { - return $this->_defaultCulture; - } - public function setDefaultCulture($culture) - { - $this->_defaultCulture = str_replace('-','_',$culture); - } - public function getDefaultCharset() - { - return $this->_defaultCharset; - } - public function setDefaultCharset($charset) - { - $this->_defaultCharset = $charset; - } - public function getCulture() - { - return $this->_culture; - } - public function setCulture($culture) - { - $this->_culture = str_replace('-','_',$culture); - } - public function getCharset() - { - return $this->_charset; - } - public function setCharset($charset) - { - $this->_charset = $charset; - } - public function getTranslationConfiguration() - { - return (!$this->_translateDefaultCulture && ($this->getDefaultCulture() == $this->getCulture())) - ? null - : $this->_translation; - } - protected function setTranslationConfiguration($config) - { - if($config['type'] == 'XLIFF' || $config['type'] == 'gettext') - { - if($config['source']) - { - $config['source'] = Prado::getPathOfNamespace($config['source']); - if(!is_dir($config['source'])) - { - if(@mkdir($config['source'])===false) - throw new TConfigurationException('globalization_source_path_failed', - $config['source']); - chmod($config['source'], PRADO_CHMOD); } - } - else - { - throw new TConfigurationException("invalid source dir '{$config['source']}'"); - } - } - if($config['cache']) - { - $config['cache'] = $this->getApplication()->getRunTimePath().'/i18n'; - if(!is_dir($config['cache'])) - { - if(@mkdir($config['cache'])===false) - throw new TConfigurationException('globalization_cache_path_failed', - $config['cache']); - chmod($config['cache'], PRADO_CHMOD); } - } - $this->_translation = $config; - } - public function getTranslationCatalogue() - { - return $this->_translation['catalogue']; - } - public function setTranslationCatalogue($value) - { - $this->_translation['catalogue'] = $value; - } - public function getCultureVariants($culture=null) - { - if($culture===null) $culture = $this->getCulture(); - $variants = explode('_', $culture); - $result = array(); - for(; count($variants) > 0; array_pop($variants)) - $result[] = implode('_', $variants); - return $result; - } - public function getLocalizedResource($file,$culture=null) - { - $files = array(); - $variants = $this->getCultureVariants($culture); - $path = pathinfo($file); - foreach($variants as $variant) - $files[] = $path['dirname'].DIRECTORY_SEPARATOR.$variant.DIRECTORY_SEPARATOR.$path['basename']; - $filename = substr($path['basename'],0,strrpos($path['basename'],'.')); - foreach($variants as $variant) - $files[] = $path['dirname'].DIRECTORY_SEPARATOR.$filename.'.'.$variant.'.'.$path['extension']; - $files[] = $file; - return $files; - } -} -class TApplication extends TComponent -{ - const STATE_OFF='Off'; - const STATE_DEBUG='Debug'; - const STATE_NORMAL='Normal'; - const STATE_PERFORMANCE='Performance'; - const PAGE_SERVICE_ID='page'; - const CONFIG_FILE_XML='application.xml'; - const CONFIG_FILE_EXT_XML='.xml'; - const CONFIG_TYPE_XML = 'xml'; - const CONFIG_FILE_PHP='application.php'; - const CONFIG_FILE_EXT_PHP='.php'; - const CONFIG_TYPE_PHP = 'php'; - const RUNTIME_PATH='runtime'; - const CONFIGCACHE_FILE='config.cache'; - const GLOBAL_FILE='global.cache'; - private static $_steps=array( - 'onBeginRequest', - 'onLoadState', - 'onLoadStateComplete', - 'onAuthentication', - 'onAuthenticationComplete', - 'onAuthorization', - 'onAuthorizationComplete', - 'onPreRunService', - 'runService', - 'onSaveState', - 'onSaveStateComplete', - 'onPreFlushOutput', - 'flushOutput' - ); - private $_id; - private $_uniqueID; - private $_requestCompleted=false; - private $_step; - private $_services; - private $_service; - private $_modules=array(); - private $_lazyModules=array(); - private $_parameters; - private $_configFile; - private $_configFileExt; - private $_configType; - private $_basePath; - private $_runtimePath; - private $_stateChanged=false; - private $_globals=array(); - private $_cacheFile; - private $_errorHandler; - private $_request; - private $_response; - private $_session; - private $_cache; - private $_statePersister; - private $_user; - private $_globalization; - private $_security; - private $_assetManager; - private $_authRules; - private $_mode=TApplicationMode::Debug; - private $_pageServiceID = self::PAGE_SERVICE_ID; - public function __construct($basePath='protected',$cacheConfig=true, $configType=self::CONFIG_TYPE_XML) - { - Prado::setApplication($this); - $this->setConfigurationType($configType); - $this->resolvePaths($basePath); - if($cacheConfig) - $this->_cacheFile=$this->_runtimePath.DIRECTORY_SEPARATOR.self::CONFIGCACHE_FILE; - $this->_uniqueID=md5($this->_runtimePath); - $this->_parameters=new TMap; - $this->_services=array($this->getPageServiceID()=>array('TPageService',array(),null)); - Prado::setPathOfAlias('Application',$this->_basePath); - } - protected function resolvePaths($basePath) - { - if(empty($basePath) || ($basePath=realpath($basePath))===false) - throw new TConfigurationException('application_basepath_invalid',$basePath); - if(is_dir($basePath) && is_file($basePath.DIRECTORY_SEPARATOR.$this->getConfigurationFileName())) - $configFile=$basePath.DIRECTORY_SEPARATOR.$this->getConfigurationFileName(); - else if(is_file($basePath)) - { - $configFile=$basePath; - $basePath=dirname($configFile); - } - else - $configFile=null; - $runtimePath=$basePath.DIRECTORY_SEPARATOR.self::RUNTIME_PATH; - if(is_writable($runtimePath)) - { - if($configFile!==null) - { - $runtimePath.=DIRECTORY_SEPARATOR.basename($configFile).'-'.Prado::getVersion(); - if(!is_dir($runtimePath)) - { - if(@mkdir($runtimePath)===false) - throw new TConfigurationException('application_runtimepath_failed',$runtimePath); - @chmod($runtimePath, PRADO_CHMOD); } - $this->setConfigurationFile($configFile); - } - $this->setBasePath($basePath); - $this->setRuntimePath($runtimePath); - } - else - throw new TConfigurationException('application_runtimepath_invalid',$runtimePath); - } - 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_unavailable'); - if($this->_requestCompleted) - break; - $method=self::$_steps[$this->_step]; - $this->$method(); - $this->_step++; - } - } - catch(Exception $e) - { - $this->onError($e); - } - $this->onEndRequest(); - } - public function completeRequest() - { - $this->_requestCompleted=true; - } - public function getRequestCompleted() - { - return $this->_requestCompleted; - } - public function getGlobalState($key,$defaultValue=null) - { - return isset($this->_globals[$key])?$this->_globals[$key]:$defaultValue; - } - public function setGlobalState($key,$value,$defaultValue=null,$forceSave=false) - { - $this->_stateChanged=true; - if($value===$defaultValue) - unset($this->_globals[$key]); - else - $this->_globals[$key]=$value; - if($forceSave) - $this->saveGlobals(); - } - 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) - { - $this->_stateChanged=false; - $this->getApplicationStatePersister()->save($this->_globals); - } - } - public function getID() - { - return $this->_id; - } - public function setID($value) - { - $this->_id=$value; - } - public function getPageServiceID() - { - return $this->_pageServiceID; - } - public function setPageServiceID($value) - { - $this->_pageServiceID=$value; - } - public function getUniqueID() - { - return $this->_uniqueID; - } - public function getMode() - { - return $this->_mode; - } - public function setMode($value) - { - $this->_mode=TPropertyValue::ensureEnum($value,'TApplicationMode'); - } - public function getBasePath() - { - return $this->_basePath; - } - public function setBasePath($value) - { - $this->_basePath=$value; - } - public function getConfigurationFile() - { - return $this->_configFile; - } - public function setConfigurationFile($value) - { - $this->_configFile=$value; - } - public function getConfigurationType() - { - return $this->_configType; - } - public function setConfigurationType($value) - { - $this->_configType = $value; - } - public function getConfigurationFileExt() - { - if($this->_configFileExt===null) - { - switch($this->_configType) - { - case TApplication::CONFIG_TYPE_PHP: - $this->_configFileExt = TApplication::CONFIG_FILE_EXT_PHP; - break; - default: - $this->_configFileExt = TApplication::CONFIG_FILE_EXT_XML; - } - } - return $this->_configFileExt; - } - public function getConfigurationFileName() - { - static $fileName; - if($fileName == null) - { - switch($this->_configType) - { - case TApplication::CONFIG_TYPE_PHP: - $fileName = TApplication::CONFIG_FILE_PHP; - break; - default: - $fileName = TApplication::CONFIG_FILE_XML; - } - } - return $fileName; - } - public function getRuntimePath() - { - return $this->_runtimePath; - } - public function setRuntimePath($value) - { - $this->_runtimePath=$value; - if($this->_cacheFile) - $this->_cacheFile=$this->_runtimePath.DIRECTORY_SEPARATOR.self::CONFIGCACHE_FILE; - $this->_uniqueID=md5($this->_runtimePath); - } - public function getService() - { - return $this->_service; - } - public function setService($value) - { - $this->_service=$value; - } - public function setModule($id,IModule $module=null) - { - if(isset($this->_modules[$id])) - throw new TConfigurationException('application_moduleid_duplicated',$id); - else - $this->_modules[$id]=$module; - } - public function getModule($id) - { - if(!array_key_exists($id, $this->_modules)) - return null; - if($this->_modules[$id]===null) - { - $module = $this->internalLoadModule($id, true); - $module[0]->init($module[1]); - } - return $this->_modules[$id]; - } - public function getModules() - { - return $this->_modules; - } - public function getParameters() - { - return $this->_parameters; - } - 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 getSecurityManager() - { - if(!$this->_security) - { - $this->_security=new TSecurityManager; - $this->_security->init(null); - } - return $this->_security; - } - public function setSecurityManager(TSecurityManager $sm) - { - $this->_security=$sm; - } - 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 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($createIfNotExists=true) - { - if($this->_globalization===null && $createIfNotExists) - { - $this->_globalization=new TGlobalization; - $this->_globalization->init(null); - } - return $this->_globalization; - } - public function setGlobalization(TGlobalization $glob) - { - $this->_globalization=$glob; - } - public function getAuthorizationRules() - { - if($this->_authRules===null) - $this->_authRules=new TAuthorizationRuleCollection; - return $this->_authRules; - } - protected function getApplicationConfigurationClass() - { - return 'TApplicationConfiguration'; - } - protected function internalLoadModule($id, $force=false) - { - list($moduleClass, $initProperties, $configElement)=$this->_lazyModules[$id]; - if(isset($initProperties['lazy']) && $initProperties['lazy'] && !$force) - { - $this->setModule($id, null); - return null; - } - $module=Prado::createComponent($moduleClass); - foreach($initProperties as $name=>$value) - { - if($name==='lazy') continue; - $module->setSubProperty($name,$value); - } - $this->setModule($id,$module); - $this->_lazyModules[$id]=null; - return array($module,$configElement); - } - public function applyConfiguration($config,$withinService=false) - { - if($config->getIsEmpty()) - return; - foreach($config->getAliases() as $alias=>$path) - Prado::setPathOfAlias($alias,$path); - foreach($config->getUsings() as $using) - Prado::using($using); - if(!$withinService) - { - foreach($config->getProperties() as $name=>$value) - $this->setSubProperty($name,$value); - } - if(empty($this->_services)) - $this->_services=array($this->getPageServiceID()=>array('TPageService',array(),null)); - foreach($config->getParameters() as $id=>$parameter) - { - if(is_array($parameter)) - { - $component=Prado::createComponent($parameter[0]); - foreach($parameter[1] as $name=>$value) - $component->setSubProperty($name,$value); - $this->_parameters->add($id,$component); - } - else - $this->_parameters->add($id,$parameter); - } - $modules=array(); - foreach($config->getModules() as $id=>$moduleConfig) - { - if(!is_string($id)) - $id='_module'.count($this->_lazyModules); - $this->_lazyModules[$id]=$moduleConfig; - if($module = $this->internalLoadModule($id)) - $modules[]=$module; - } - foreach($modules as $module) - $module[0]->init($module[1]); - foreach($config->getServices() as $serviceID=>$serviceConfig) - $this->_services[$serviceID]=$serviceConfig; - foreach($config->getExternalConfigurations() as $filePath=>$condition) - { - if($condition!==true) - $condition=$this->evaluateExpression($condition); - if($condition) - { - if(($path=Prado::getPathOfNamespace($filePath,$this->getConfigurationFileExt()))===null || !is_file($path)) - throw new TConfigurationException('application_includefile_invalid',$filePath); - $cn=$this->getApplicationConfigurationClass(); - $c=new $cn; - $c->loadFromFile($path); - $this->applyConfiguration($c,$withinService); - } - } - } - protected function initApplication() - { - if($this->_configFile!==null) - { - if($this->_cacheFile===null || @filemtime($this->_cacheFile)<filemtime($this->_configFile)) - { - $config=new TApplicationConfiguration; - $config->loadFromFile($this->_configFile); - if($this->_cacheFile!==null) - file_put_contents($this->_cacheFile,serialize($config),LOCK_EX); - } - else - $config=unserialize(file_get_contents($this->_cacheFile)); - $this->applyConfiguration($config,false); - } - if(($serviceID=$this->getRequest()->resolveRequest(array_keys($this->_services)))===null) - $serviceID=$this->getPageServiceID(); - $this->startService($serviceID); - } - public function startService($serviceID) - { - if(isset($this->_services[$serviceID])) - { - list($serviceClass,$initProperties,$configElement)=$this->_services[$serviceID]; - $service=Prado::createComponent($serviceClass); - if(!($service instanceof IService)) - throw new THttpException(500,'application_service_invalid',$serviceClass); - if(!$service->getEnabled()) - throw new THttpException(500,'application_service_unavailable',$serviceClass); - $service->setID($serviceID); - $this->setService($service); - foreach($initProperties as $name=>$value) - $service->setSubProperty($name,$value); - if($configElement!==null) - { - $config=new TApplicationConfiguration; - if($this->getConfigurationType()==self::CONFIG_TYPE_PHP) - $config->loadFromPhp($configElement,$this->getBasePath()); - else - $config->loadFromXml($configElement,$this->getBasePath()); - $this->applyConfiguration($config,true); - } - $service->init($configElement); - } - else - throw new THttpException(500,'application_service_unknown',$serviceID); - } - public function onError($param) - { - Prado::log($param->getMessage(),TLogger::ERROR,'System.TApplication'); - $this->raiseEvent('OnError',$this,$param); - $this->getErrorHandler()->handleError($this,$param); - } - public function onBeginRequest() - { - $this->raiseEvent('OnBeginRequest',$this,null); - } - public function onAuthentication() - { - $this->raiseEvent('OnAuthentication',$this,null); - } - public function onAuthenticationComplete() - { - $this->raiseEvent('OnAuthenticationComplete',$this,null); - } - public function onAuthorization() - { - $this->raiseEvent('OnAuthorization',$this,null); - } - public function onAuthorizationComplete() - { - $this->raiseEvent('OnAuthorizationComplete',$this,null); - } - public function onLoadState() - { - $this->loadGlobals(); - $this->raiseEvent('OnLoadState',$this,null); - } - public function onLoadStateComplete() - { - $this->raiseEvent('OnLoadStateComplete',$this,null); - } - public function onPreRunService() - { - $this->raiseEvent('OnPreRunService',$this,null); - } - public function runService() - { - if($this->_service) - $this->_service->run(); - } - public function onSaveState() - { - $this->raiseEvent('OnSaveState',$this,null); - $this->saveGlobals(); - } - public function onSaveStateComplete() - { - $this->raiseEvent('OnSaveStateComplete',$this,null); - } - public function onPreFlushOutput() - { - $this->raiseEvent('OnPreFlushOutput',$this,null); - } - public function flushOutput($continueBuffering = true) - { - $this->getResponse()->flush($continueBuffering); - } - public function onEndRequest() - { - $this->flushOutput(false); $this->saveGlobals(); $this->raiseEvent('OnEndRequest',$this,null); - } -} -class TApplicationMode extends TEnumerable -{ - const Off='Off'; - const Debug='Debug'; - const Normal='Normal'; - const Performance='Performance'; -} -class TApplicationConfiguration extends TComponent -{ - private $_properties=array(); - private $_usings=array(); - private $_aliases=array(); - private $_modules=array(); - private $_services=array(); - private $_parameters=array(); - private $_includes=array(); - private $_empty=true; - public function loadFromFile($fname) - { - if(Prado::getApplication()->getConfigurationType()==TApplication::CONFIG_TYPE_PHP) - { - $fcontent = include $fname; - $this->loadFromPhp($fcontent,dirname($fname)); - } - else - { - $dom=new TXmlDocument; - $dom->loadFromFile($fname); - $this->loadFromXml($dom,dirname($fname)); - } - } - public function getIsEmpty() - { - return $this->_empty; - } - public function loadFromPhp($config, $configPath) - { - if(isset($config['application'])) - { - foreach($config['application'] as $name=>$value) - { - $this->_properties[$name]=$value; - } - $this->_empty = false; - } - if(isset($config['paths']) && is_array($config['paths'])) - $this->loadPathsPhp($config['paths'],$configPath); - if(isset($config['modules']) && is_array($config['modules'])) - $this->loadModulesPhp($config['modules'],$configPath); - if(isset($config['services']) && is_array($config['services'])) - $this->loadServicesPhp($config['services'],$configPath); - if(isset($config['parameters']) && is_array($config['parameters'])) - $this->loadParametersPhp($config['parameters'], $configPath); - if(isset($config['includes']) && is_array($config['includes'])) - $this->loadExternalXml($config['includes'],$configPath); - } - public function loadFromXml($dom,$configPath) - { - foreach($dom->getAttributes() as $name=>$value) - { - $this->_properties[$name]=$value; - $this->_empty=false; - } - foreach($dom->getElements() as $element) - { - switch($element->getTagName()) - { - case 'paths': - $this->loadPathsXml($element,$configPath); - break; - case 'modules': - $this->loadModulesXml($element,$configPath); - break; - case 'services': - $this->loadServicesXml($element,$configPath); - break; - case 'parameters': - $this->loadParametersXml($element,$configPath); - break; - case 'include': - $this->loadExternalXml($element,$configPath); - break; - default: - break; - } - } - } - protected function loadPathsPhp($pathsNode, $configPath) - { - if(isset($pathsNode['aliases']) && is_array($pathsNode['aliases'])) - { - foreach($pathsNode['aliases'] as $id=>$path) - { - $path=str_replace('\\','/',$path); - if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) $p=realpath($path); - else - $p=realpath($configPath.DIRECTORY_SEPARATOR.$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; - } - } - if(isset($pathsNode['using']) && is_array($pathsNode['using'])) - { - foreach($pathsNode['using'] as $namespace) - { - $this->_usings[] = $namespace; - } - } - } - protected function loadPathsXml($pathsNode,$configPath) - { - foreach($pathsNode->getElements() as $element) - { - switch($element->getTagName()) - { - case 'alias': - { - if(($id=$element->getAttribute('id'))!==null && ($path=$element->getAttribute('path'))!==null) - { - $path=str_replace('\\','/',$path); - if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) $p=realpath($path); - else - $p=realpath($configPath.DIRECTORY_SEPARATOR.$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'); - $this->_empty=false; - break; - } - case 'using': - { - if(($namespace=$element->getAttribute('namespace'))!==null) - $this->_usings[]=$namespace; - else - throw new TConfigurationException('appconfig_using_invalid'); - $this->_empty=false; - break; - } - default: - throw new TConfigurationException('appconfig_paths_invalid',$element->getTagName()); - } - } - } - protected function loadModulesPhp($modulesNode, $configPath) - { - foreach($modulesNode as $id=>$module) - { - if(!isset($module['class'])) - throw new TConfigurationException('appconfig_moduletype_required',$id); - $type = $module['class']; - unset($module['class']); - $properties = array(); - if(isset($module['properties'])) - { - $properties = $module['properties']; - unset($module['properties']); - } - $properties['id'] = $id; - $this->_modules[$id]=array($type,$properties,$module); - $this->_empty=false; - } - } - protected function loadModulesXml($modulesNode,$configPath) - { - foreach($modulesNode->getElements() as $element) - { - if($element->getTagName()==='module') - { - $properties=$element->getAttributes(); - $id=$properties->itemAt('id'); - $type=$properties->remove('class'); - if($type===null) - throw new TConfigurationException('appconfig_moduletype_required',$id); - $element->setParent(null); - if($id===null) - $this->_modules[]=array($type,$properties->toArray(),$element); - else - $this->_modules[$id]=array($type,$properties->toArray(),$element); - $this->_empty=false; - } - else - throw new TConfigurationException('appconfig_modules_invalid',$element->getTagName()); - } - } - protected function loadServicesPhp($servicesNode,$configPath) - { - foreach($servicesNode as $id => $service) - { - if(!isset($service['class'])) - throw new TConfigurationException('appconfig_servicetype_required'); - $type = $service['class']; - $properties = isset($service['properties']) ? $service['properties'] : array(); - unset($service['properties']); - $properties['id'] = $id; - $this->_services[$id] = array($type,$properties,$service); - $this->_empty = false; - } - } - protected function loadServicesXml($servicesNode,$configPath) - { - foreach($servicesNode->getElements() as $element) - { - if($element->getTagName()==='service') - { - $properties=$element->getAttributes(); - if(($id=$properties->itemAt('id'))===null) - throw new TConfigurationException('appconfig_serviceid_required'); - if(($type=$properties->remove('class'))===null) - throw new TConfigurationException('appconfig_servicetype_required',$id); - $element->setParent(null); - $this->_services[$id]=array($type,$properties->toArray(),$element); - $this->_empty=false; - } - else - throw new TConfigurationException('appconfig_services_invalid',$element->getTagName()); - } - } - protected function loadParametersPhp($parametersNode,$configPath) - { - foreach($parametersNode as $id => $parameter) - { - if(is_array($parameter)) - { - if(isset($parameter['class'])) - { - $type = $parameter['class']; - unset($parameter['class']); - $properties = isset($service['properties']) ? $service['properties'] : array(); - $properties['id'] = $id; - $this->_parameters[$id] = array($type,$properties); - } - } - else - { - $this->_parameters[$id] = $parameter; - } - } - } - protected function loadParametersXml($parametersNode,$configPath) - { - foreach($parametersNode->getElements() as $element) - { - if($element->getTagName()==='parameter') - { - $properties=$element->getAttributes(); - if(($id=$properties->remove('id'))===null) - throw new TConfigurationException('appconfig_parameterid_required'); - if(($type=$properties->remove('class'))===null) - { - if(($value=$properties->remove('value'))===null) - $this->_parameters[$id]=$element; - else - $this->_parameters[$id]=$value; - } - else - $this->_parameters[$id]=array($type,$properties->toArray()); - $this->_empty=false; - } - else - throw new TConfigurationException('appconfig_parameters_invalid',$element->getTagName()); - } - } - protected function loadExternalPhp($includeNode,$configPath) - { - foreach($includeNode as $include) - { - $when = isset($include['when'])?true:false; - if(!isset($include['file'])) - throw new TConfigurationException('appconfig_includefile_required'); - $filePath = $include['file']; - if(isset($this->_includes[$filePath])) - $this->_includes[$filePath]='('.$this->_includes[$filePath].') || ('.$when.')'; - else - $$this->_includes[$filePath]=$when; - $this->_empty=false; - } - } - protected function loadExternalXml($includeNode,$configPath) - { - if(($when=$includeNode->getAttribute('when'))===null) - $when=true; - if(($filePath=$includeNode->getAttribute('file'))===null) - throw new TConfigurationException('appconfig_includefile_required'); - if(isset($this->_includes[$filePath])) - $this->_includes[$filePath]='('.$this->_includes[$filePath].') || ('.$when.')'; - else - $this->_includes[$filePath]=$when; - $this->_empty=false; - } - 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; - } - public function getExternalConfigurations() - { - return $this->_includes; - } -} -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(); - file_put_contents($fileName,$content,LOCK_EX); - } - } -} -class TShellApplication extends TApplication -{ - public function run() - { - $this->initApplication(); - } -} -?>
\ No newline at end of file |