summaryrefslogtreecommitdiff
path: root/framework/TApplicationConfiguration.php
diff options
context:
space:
mode:
Diffstat (limited to 'framework/TApplicationConfiguration.php')
-rw-r--r--framework/TApplicationConfiguration.php518
1 files changed, 518 insertions, 0 deletions
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 &copy; 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