summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY1
-rw-r--r--framework/Exceptions/messages.txt5
-rw-r--r--framework/TApplication.php292
-rw-r--r--framework/TService.php20
-rw-r--r--framework/Web/Services/TPageService.php217
-rw-r--r--framework/Web/THttpRequest.php33
-rw-r--r--framework/interfaces.php8
7 files changed, 265 insertions, 311 deletions
diff --git a/HISTORY b/HISTORY
index e0aba77e..ee8c5758 100644
--- a/HISTORY
+++ b/HISTORY
@@ -10,6 +10,7 @@ ENH: Added PRADO_CHMOD constant so that users can specify the permission of PRAD
ENH: Added Display property to TWebControl (Wei)
ENH: Added TUser.getState() and setState() for storing user session data (Qiang)
ENH: Added renderer feature to TRepeater, TDataList and TDataGrid (Qiang)
+ENH: Added support to include external application configuration files (Qiang)
NEW: TShellApplication (Qiang)
NEW: Active Record driver for IBM DB2 (Cesar Ramos)
diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt
index 1b9ab749..b35ba7bf 100644
--- a/framework/Exceptions/messages.txt
+++ b/framework/Exceptions/messages.txt
@@ -24,11 +24,13 @@ map_item_unremovable = The item cannot be removed from the map.
map_data_not_iterable = Data must be either an array or an object implementing Traversable interface.
map_readonly = {0} is read-only.
+application_includefile_invalid = Unable to find application configuration {0}. Make sure it is in namespace format and the file ends with ".xml".
application_basepath_invalid = Application base path '{0}' does not exist or is not a directory.
application_runtimepath_invalid = Application runtime path '{0}' does not exist or is not writable by Web server process.
application_service_invalid = Service '{0}' must implement IService interface.
application_service_unknown = Requested service '{0}' is not defined.
-application_service_unavailable = Service Unavailable.
+application_unavailable = Application is unavailable at this time.
+application_service_unavailable = Service '{0}' is unavailable at this time.
application_moduleid_duplicated = Application module ID '{0}' is not unique.
application_runtimepath_failed = Unable to create runtime path '{0}'. Make sure the parent directory exists and is writable by the Web process.
@@ -41,6 +43,7 @@ appconfig_moduletype_required = Application configuration <module id="{0}"> mu
appconfig_serviceid_required = Application configuration <service> element must have an "id" attribute.
appconfig_servicetype_required = Application configuration <service id="{0}"> must have a "class" attribute.
appconfig_parameterid_required = Application configuration <parameter> element must have an "id" attribute.
+appconfig_includefile_required = Application configuration <include> element must have a "file" attribute.
securitymanager_validationkey_invalid = TSecurityManager.ValidationKey must not be empty.
securitymanager_encryptionkey_invalid = TSecurityManager.EncryptionKey must not be empty.
diff --git a/framework/TApplication.php b/framework/TApplication.php
index b12dc64a..411b5241 100644
--- a/framework/TApplication.php
+++ b/framework/TApplication.php
@@ -130,6 +130,10 @@ class TApplication extends TComponent
*/
const CONFIG_FILE='application.xml';
/**
+ * File extension for external config files
+ */
+ const CONFIG_FILE_EXT='.xml';
+ /**
* Runtime directory name
*/
const RUNTIME_PATH='runtime';
@@ -178,6 +182,10 @@ class TApplication extends TComponent
*/
private $_step;
/**
+ * @var array available services and their configurations indexed by service IDs
+ */
+ private $_services;
+ /**
* @var IService current service instance
*/
private $_service;
@@ -188,7 +196,7 @@ class TApplication extends TComponent
/**
* @var array list of application modules
*/
- private $_modules;
+ private $_modules=array();
/**
* @var TMap list of application parameters
*/
@@ -296,6 +304,9 @@ class TApplication extends TComponent
// generates unique ID by hashing the runtime path
$this->_uniqueID=md5($this->_runtimePath);
+ $this->_parameters=new TMap;
+ $this->_services=array(self::PAGE_SERVICE_ID=>array('TPageService',array(),null));
+ Prado::setPathOfAlias('Application',$this->_basePath);
}
/**
@@ -329,7 +340,7 @@ class TApplication extends TComponent
{
if($configFile!==null)
{
- $runtimePath.=DIRECTORY_SEPARATOR.basename($configFile);
+ $runtimePath.=DIRECTORY_SEPARATOR.basename($configFile).'-'.Prado::getVersion();
if(!is_dir($runtimePath))
{
if(@mkdir($runtimePath)===false)
@@ -362,7 +373,7 @@ class TApplication extends TComponent
while($this->_step<$n)
{
if($this->_mode===self::STATE_OFF)
- throw new THttpException(503,'application_service_unavailable');
+ throw new THttpException(503,'application_unavailable');
if($this->_requestCompleted)
break;
$method=self::$_steps[$this->_step];
@@ -560,6 +571,14 @@ class TApplication extends TComponent
}
/**
+ * @param IService the currently requested service
+ */
+ public function setService($value)
+ {
+ $this->_service=$value;
+ }
+
+ /**
* Adds a module to application.
* Note, this method does not do module initialization.
* @param string ID of the module
@@ -601,29 +620,6 @@ class TApplication extends TComponent
}
/**
- * @return TPageService page service
- */
- public function getPageService()
- {
- if(!$this->_pageService)
- {
- $this->_pageService=new TPageService;
- $this->_pageService->init(null);
- }
- return $this->_pageService;
- }
-
- /**
- * Registers the page service instance.
- * This method should only be used by framework developers.
- * @param TPageService page service
- */
- public function setPageService(TPageService $service)
- {
- $this->_pageService=$service;
- }
-
- /**
* @return THttpRequest the request module
*/
public function getRequest()
@@ -831,49 +827,10 @@ class TApplication extends TComponent
return $this->_authRules;
}
- /**
- * Loads configuration and initializes application.
- * Configuration file will be read and parsed (if a valid cached version exists,
- * it will be used instead). Then, modules are created and initialized;
- * Afterwards, the requested service is created and initialized.
- * @param string configuration file path (absolute or relative to current executing script)
- * @param string cache file path, empty if no present or needed
- * @throws TConfigurationException if module is redefined of invalid type, or service not defined or of invalid type
- */
- protected function initApplication()
+ public function applyConfiguration($config,$withinService=false)
{
- Prado::trace('Initializing application','System.TApplication');
-
- Prado::setPathOfAlias('Application',$this->_basePath);
-
- if($this->_configFile===null)
- {
- $request=$this->getRequest();
- $request->setAvailableServices(array(self::PAGE_SERVICE_ID));
- $request->resolveRequest();
- $this->_service=$this->getPageService();
+ if($config->getIsEmpty())
return;
- }
-
- if($this->_cacheFile===null || @filemtime($this->_cacheFile)<filemtime($this->_configFile))
- {
- $config=new TApplicationConfiguration;
- $config->loadFromFile($this->_configFile);
- if($this->_cacheFile!==null)
- {
- if(($fp=fopen($this->_cacheFile,'wb'))!==false)
- {
- fputs($fp,Prado::serialize($config));
- fclose($fp);
- }
- else
- syslog(LOG_WARNING, 'Prado application config cache file "'.$this->_cacheFile.'" cannot be created.');
- }
- }
- else
- {
- $config=Prado::unserialize(file_get_contents($this->_cacheFile));
- }
// set path aliases and using namespaces
foreach($config->getAliases() as $alias=>$path)
@@ -882,11 +839,13 @@ class TApplication extends TComponent
Prado::using($using);
// set application properties
- foreach($config->getProperties() as $name=>$value)
- $this->setSubProperty($name,$value);
+ if(!$withinService)
+ {
+ foreach($config->getProperties() as $name=>$value)
+ $this->setSubProperty($name,$value);
+ }
// load parameters
- $this->_parameters=new TMap;
foreach($config->getParameters() as $id=>$parameter)
{
if(is_array($parameter))
@@ -901,46 +860,108 @@ class TApplication extends TComponent
}
// load and init modules specified in app config
- $this->_modules=array();
$modules=array();
foreach($config->getModules() as $id=>$moduleConfig)
{
Prado::trace("Loading module $id ({$moduleConfig[0]})",'System.TApplication');
-
- $module=Prado::createComponent($moduleConfig[0]);
+ list($moduleClass, $initProperties, $configElement)=$moduleConfig;
+ $module=Prado::createComponent($moduleClass);
if(is_string($id))
$this->setModule($id,$module);
- foreach($moduleConfig[1] as $name=>$value)
+ foreach($initProperties as $name=>$value)
$module->setSubProperty($name,$value);
- $modules[]=array($module,$moduleConfig[2]);
+ $modules[]=array($module,$configElement);
}
foreach($modules as $module)
$module[0]->init($module[1]);
// load service
- $services=$config->getServices();
- $serviceIDs=array_keys($services);
- array_unshift($serviceIDs,self::PAGE_SERVICE_ID);
- $request=$this->getRequest();
- $request->setAvailableServices($serviceIDs);
+ foreach($config->getServices() as $serviceID=>$serviceConfig)
+ $this->_services[$serviceID]=$serviceConfig;
+
+ // external configurations
+ foreach($config->getExternalConfigurations() as $filePath=>$condition)
+ {
+ if($condition!==true)
+ $condition=$this->evaluateExpression($condition);
+ if($condition)
+ {
+ if(($path=Prado::getPathOfNamespace($filePath,self::CONFIG_FILE_EXT))===null || !is_file($path))
+ throw new TConfigurationException('application_includefile_invalid',$filePath);
+ $c=new TApplicationConfiguration;
+ $c->loadFromFile($path);
+ $this->applyConfiguration($c,$withinService);
+ }
+ }
+ }
- $request->resolveRequest();
+ /**
+ * Loads configuration and initializes application.
+ * Configuration file will be read and parsed (if a valid cached version exists,
+ * it will be used instead). Then, modules are created and initialized;
+ * Afterwards, the requested service is created and initialized.
+ * @param string configuration file path (absolute or relative to current executing script)
+ * @param string cache file path, empty if no present or needed
+ * @throws TConfigurationException if module is redefined of invalid type, or service not defined or of invalid type
+ */
+ protected function initApplication()
+ {
+ Prado::trace('Initializing application','System.TApplication');
+
+ 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,Prado::serialize($config),LOCK_EX);
+ }
+ else
+ $config=Prado::unserialize(file_get_contents($this->_cacheFile));
+
+ $this->applyConfiguration($config,false);
+ }
- if(($serviceID=$request->getServiceID())===null)
+ if(($serviceID=$this->getRequest()->resolveRequest(array_keys($this->_services)))===null)
$serviceID=self::PAGE_SERVICE_ID;
- if(isset($services[$serviceID]))
+
+ $this->startService($serviceID);
+ }
+
+ /**
+ * Starts the specified service.
+ * The service instance will be created. Its properties will be initialized
+ * and the configurations will be applied, if any.
+ * @param string service ID
+ */
+ public function startService($serviceID)
+ {
+ if(isset($this->_services[$serviceID]))
{
- $serviceConfig=$services[$serviceID];
- $service=Prado::createComponent($serviceConfig[0]);
+ list($serviceClass,$initProperties,$configElement)=$this->_services[$serviceID];
+ $service=Prado::createComponent($serviceClass);
if(!($service instanceof IService))
- throw new THttpException(500,'application_service_unknown',$serviceID);
- $this->_service=$service;
- foreach($serviceConfig[1] as $name=>$value)
+ 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);
- $service->init($serviceConfig[2]);
+
+ if($configElement!==null)
+ {
+ $config=new TApplicationConfiguration;
+ $config->loadFromXml($configElement,$this->getBasePath());
+ $this->applyConfiguration($config,true);
+ }
+
+ $service->init($configElement);
}
else
- $this->_service=$this->getPageService();
+ throw new THttpException(500,'application_service_unknown',$serviceID);
}
/**
@@ -1147,6 +1168,14 @@ class TApplicationConfiguration extends TComponent
* @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.
@@ -1155,13 +1184,32 @@ class TApplicationConfiguration extends TComponent
*/
public function loadFromFile($fname)
{
- $configPath=dirname($fname);
$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 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;
+ }
// paths
if(($pathsNode=$dom->getElementByTagName('paths'))!==null)
@@ -1183,6 +1231,7 @@ class TApplicationConfiguration extends TComponent
}
else
throw new TConfigurationException('appconfig_alias_invalid');
+ $this->_empty=false;
}
foreach($pathsNode->getElementsByTagName('using') as $usingNode)
{
@@ -1190,6 +1239,7 @@ class TApplicationConfiguration extends TComponent
$this->_usings[]=$namespace;
else
throw new TConfigurationException('appconfig_using_invalid');
+ $this->_empty=false;
}
}
@@ -1208,6 +1258,7 @@ class TApplicationConfiguration extends TComponent
$this->_modules[]=array($type,$properties->toArray(),$node);
else
$this->_modules[$id]=array($type,$properties->toArray(),$node);
+ $this->_empty=false;
}
}
@@ -1223,6 +1274,7 @@ class TApplicationConfiguration extends TComponent
throw new TConfigurationException('appconfig_servicetype_required',$id);
$node->setParent(null);
$this->_services[$id]=array($type,$properties->toArray(),$node);
+ $this->_empty=false;
}
}
@@ -1243,12 +1295,26 @@ class TApplicationConfiguration extends TComponent
}
else
$this->_parameters[$id]=array($type,$properties->toArray());
+ $this->_empty=false;
}
}
+
+ // external configurations
+ foreach($dom->getElementsByTagName('include') as $node)
+ {
+ if(($when=$node->getAttribute('when'))===null)
+ $when=true;
+ if(($filePath=$node->getAttribute('file'))===null)
+ throw new TConfigurationException('appconfig_includefile_required');
+ $this->_includes[$filePath]=$when;
+ }
}
/**
- * @return array list of application initial property values, indexed by property names
+ * 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()
{
@@ -1256,7 +1322,11 @@ class TApplicationConfiguration extends TComponent
}
/**
- * @return array list of path aliases, indexed by alias names
+ * 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()
{
@@ -1264,6 +1334,10 @@ class TApplicationConfiguration extends TComponent
}
/**
+ * 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()
@@ -1272,7 +1346,18 @@ class TApplicationConfiguration extends TComponent
}
/**
- * @return array list of module configurations
+ * 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()
{
@@ -1288,12 +1373,29 @@ class TApplicationConfiguration extends TComponent
}
/**
- * @return array list of parameters
+ * 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;
+ }
}
/**
diff --git a/framework/TService.php b/framework/TService.php
index 5df31534..ec91c43a 100644
--- a/framework/TService.php
+++ b/framework/TService.php
@@ -27,6 +27,10 @@ abstract class TService extends TApplicationComponent implements IService
* @var string service id
*/
private $_id;
+ /**
+ * @var boolean whether the service is enabled
+ */
+ private $_enabled=true;
/**
* Initializes the service and attaches {@link run} to the RunService event of application.
@@ -54,6 +58,22 @@ abstract class TService extends TApplicationComponent implements IService
}
/**
+ * @return boolean whether the service is enabled
+ */
+ public function getEnabled()
+ {
+ return $this->_enabled;
+ }
+
+ /**
+ * @param boolean whether the service is enabled
+ */
+ public function setEnabled($value)
+ {
+ $this->_enabled=TPropertyValue::ensureBoolean($value);
+ }
+
+ /**
* Runs the service.
*/
public function run()
diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php
index 8d1eb3f4..a0c4b8fb 100644
--- a/framework/Web/Services/TPageService.php
+++ b/framework/Web/Services/TPageService.php
@@ -129,15 +129,6 @@ class TPageService extends TService
private $_templateManager=null;
/**
- * Constructor.
- * Sets default service ID to 'page'.
- */
- public function __construct()
- {
- $this->setID('page');
- }
-
- /**
* Initializes the service.
* This method is required by IService interface and is invoked by application.
* @param TXmlElement service configuration
@@ -146,8 +137,6 @@ class TPageService extends TService
{
Prado::trace("Initializing TPageService",'System.Web.Services.TPageService');
- $this->getApplication()->setPageService($this);
-
$pageConfig=$this->loadPageConfig($this->getRequestedPagePath(),$config);
$this->initPageContext($pageConfig);
@@ -166,45 +155,12 @@ class TPageService extends TService
{
$application=$this->getApplication();
- // set path aliases and using namespaces
- foreach($pageConfig->getAliases() as $alias=>$path)
- Prado::setPathOfAlias($alias,$path);
- foreach($pageConfig->getUsings() as $using)
- Prado::using($using);
+ foreach($pageConfig->getApplicationConfigurations() as $appConfig)
+ $application->applyConfiguration($appConfig);
// initial page properties (to be set when page runs)
$this->_properties=$pageConfig->getProperties();
- // load parameters
- $parameters=$application->getParameters();
- foreach($pageConfig->getParameters() as $id=>$parameter)
- {
- if(is_array($parameter))
- {
- $component=Prado::createComponent($parameter[0]);
- foreach($parameter[1] as $name=>$value)
- $component->setSubProperty($name,$value);
- $parameters->add($id,$component);
- }
- else
- $parameters->add($id,$parameter);
- }
-
- // load modules specified in page directory config
- $modules=array();
- foreach($pageConfig->getModules() as $id=>$moduleConfig)
- {
- Prado::trace("Loading module $id ({$moduleConfig[0]})",'System.Web.Services.TPageService');
- $module=Prado::createComponent($moduleConfig[0]);
- if(is_string($id))
- $application->setModule($id,$module);
- foreach($moduleConfig[1] as $name=>$value)
- $module->setSubProperty($name,$value);
- $modules[]=array($module,$moduleConfig[2]);
- }
- foreach($modules as $module)
- $module[0]->init($module[1]);
-
$application->getAuthorizationRules()->mergeWith($pageConfig->getRules());
}
@@ -233,8 +189,8 @@ class TPageService extends TService
{
$pageConfig=new TPageConfiguration;
if($config!==null)
- $pageConfig->loadXmlElement($config,$application->getBasePath(),null);
- $pageConfig->loadConfigurationFiles($pagePath,$this->getBasePath());
+ $pageConfig->loadFromXml($config,$application->getBasePath());
+ $pageConfig->loadFromFiles($pagePath,$this->getBasePath());
}
else
{
@@ -282,8 +238,8 @@ class TPageService extends TService
{
$pageConfig=new TPageConfiguration;
if($config!==null)
- $pageConfig->loadXmlElement($config,$application->getBasePath(),null);
- $pageConfig->loadConfigurationFiles($pagePath,$this->getBasePath());
+ $pageConfig->loadFromXml($config,$application->getBasePath());
+ $pageConfig->loadFromFiles($pagePath,$this->getBasePath());
$cache->set(self::CONFIG_CACHE_PREFIX.$this->getID().$pagePath,array($pageConfig,$currentTimestamp));
}
}
@@ -510,25 +466,13 @@ class TPageService extends TService
class TPageConfiguration extends TComponent
{
/**
- * @var array list of page initial property values
- */
- private $_properties=array();
- /**
- * @var array list of namespaces to be used
+ * @var array list of application configurations
*/
- private $_usings=array();
+ private $_appConfigs=array();
/**
- * @var array list of path aliases
- */
- private $_aliases=array();
- /**
- * @var array list of module configurations
- */
- private $_modules=array();
- /**
- * @var array list of parameters
+ * @var array list of page initial property values
*/
- private $_parameters=array();
+ private $_properties=array();
/**
* @var TAuthorizationRuleCollection list of authorization rules
*/
@@ -546,66 +490,6 @@ class TPageConfiguration extends TComponent
}
/**
- * 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;
- }
-
- /**
- * 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;
- }
-
- /**
* Returns list of authorization rules.
* The authorization rules are aggregated (bottom-up) from configuration files
* along the path to the specified page.
@@ -617,11 +501,19 @@ class TPageConfiguration extends TComponent
}
/**
+ * @return array list of application configurations specified along page path
+ */
+ public function getApplicationConfigurations()
+ {
+ return $this->_appConfigs;
+ }
+
+ /**
* Loads configuration for a page specified in a path format.
* @param string path to the page (dot-connected format)
* @param string root path for pages
*/
- public function loadConfigurationFiles($pagePath,$basePath)
+ public function loadFromFiles($pagePath,$basePath)
{
$paths=explode('.',$pagePath);
$page=array_pop($paths);
@@ -647,7 +539,7 @@ class TPageConfiguration extends TComponent
return;
$dom=new TXmlDocument;
if($dom->loadFromFile($fname))
- $this->loadXmlElement($dom,dirname($fname),$page);
+ $this->loadFromXml($dom,dirname($fname),$page);
else
throw new TConfigurationException('pageserviceconf_file_invalid',$fname);
}
@@ -658,73 +550,14 @@ class TPageConfiguration extends TComponent
* @param string base path corresponding to this xml element
* @param string page name, null if page is not required
*/
- public function loadXmlElement($dom,$configPath,$page)
+ public function loadFromXml($dom,$configPath,$page=null)
{
- // paths
- if(($pathsNode=$dom->getElementByTagName('paths'))!==null)
- {
- foreach($pathsNode->getElementsByTagName('alias') as $aliasNode)
- {
- if(($id=$aliasNode->getAttribute('id'))!==null && ($p=$aliasNode->getAttribute('path'))!==null)
- {
- $p=str_replace('\\','/',$p);
- $path=realpath(preg_match('/^\\/|.:\\//',$p)?$p:$configPath.'/'.$p);
- if($path===false || !is_dir($path))
- throw new TConfigurationException('pageserviceconf_aliaspath_invalid',$id,$p,$configPath);
- if(isset($this->_aliases[$id]))
- throw new TConfigurationException('pageserviceconf_alias_redefined',$id,$configPath);
- $this->_aliases[$id]=$path;
- }
- else
- throw new TConfigurationException('pageserviceconf_alias_invalid',$configPath);
- }
- foreach($pathsNode->getElementsByTagName('using') as $usingNode)
- {
- if(($namespace=$usingNode->getAttribute('namespace'))!==null)
- $this->_usings[]=$namespace;
- else
- throw new TConfigurationException('pageserviceconf_using_invalid',$configPath);
- }
- }
-
- // modules
- if(($modulesNode=$dom->getElementByTagName('modules'))!==null)
+ if($page!==null) // config.xml
{
- foreach($modulesNode->getElementsByTagName('module') as $node)
- {
- $properties=$node->getAttributes();
- $type=$properties->remove('class');
- $id=$properties->itemAt('id');
- if($type===null)
- throw new TConfigurationException('pageserviceconf_moduletype_required',$id,$configPath);
- $node->setParent(null);
- if($id===null)
- $this->_modules[]=array($type,$properties->toArray(),$node);
- else
- $this->_modules[$id]=array($type,$properties->toArray(),$node);
- }
+ $appConfig=new TApplicationConfiguration;
+ $appConfig->loadFromXml($dom,$configPath);
+ $this->_appConfigs[]=$appConfig;
}
-
- // parameters
- if(($parametersNode=$dom->getElementByTagName('parameters'))!==null)
- {
- foreach($parametersNode->getElementsByTagName('parameter') as $node)
- {
- $properties=$node->getAttributes();
- if(($id=$properties->remove('id'))===null)
- throw new TConfigurationException('pageserviceconf_parameter_invalid',$configPath);
- if(($type=$properties->remove('class'))===null)
- {
- if(($value=$properties->remove('value'))===null)
- $this->_parameters[$id]=$node;
- else
- $this->_parameters[$id]=$value;
- }
- else
- $this->_parameters[$id]=array($type,$properties->toArray());
- }
- }
-
// authorization
if(($authorizationNode=$dom->getElementByTagName('authorization'))!==null)
{
diff --git a/framework/Web/THttpRequest.php b/framework/Web/THttpRequest.php
index 47fe1230..9c3ce98d 100644
--- a/framework/Web/THttpRequest.php
+++ b/framework/Web/THttpRequest.php
@@ -568,22 +568,25 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar
* A URL in the format of /index.php?sp=serviceID.serviceParameter
* will be resolved with the serviceID and the serviceParameter.
* You may override this method to provide your own way of service resolution.
+ * @param array list of valid service IDs
+ * @return string the currently requested service ID, null if no service ID is found
* @see constructUrl
*/
- public function resolveRequest()
+ public function resolveRequest($serviceIDs)
{
Prado::trace("Resolving request from ".$_SERVER['REMOTE_ADDR'],'System.Web.THttpRequest');
- $this->_requestResolved=true;
$this->_items=array_merge($_GET,$this->parseUrl(),$_POST);
- foreach($this->_services as $id)
+ $this->_requestResolved=true;
+ foreach($serviceIDs as $serviceID)
{
- if($this->contains($id))
+ if($this->contains($serviceID))
{
- $this->setServiceID($id);
- $this->setServiceParameter($this->itemAt($id));
- break;
+ $this->setServiceID($serviceID);
+ $this->setServiceParameter($this->itemAt($serviceID));
+ return $serviceID;
}
}
+ return null;
}
/**
@@ -595,22 +598,6 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar
}
/**
- * @return array IDs of the available services
- */
- public function getAvailableServices()
- {
- return $this->_services;
- }
-
- /**
- * @param array IDs of the available services
- */
- public function setAvailableServices($services)
- {
- $this->_services=$services;
- }
-
- /**
* @return string requested service ID
*/
public function getServiceID()
diff --git a/framework/interfaces.php b/framework/interfaces.php
index 31bbefd7..747d5b02 100644
--- a/framework/interfaces.php
+++ b/framework/interfaces.php
@@ -63,6 +63,14 @@ interface IService
*/
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();