From 153581e1081ba4225eb93221aced493709cb606c Mon Sep 17 00:00:00 2001 From: xue <> Date: Fri, 23 Dec 2005 03:31:07 +0000 Subject: Implemented new page storage method. --- framework/Data/TSqliteCache.php | 2 +- framework/Exceptions/TErrorHandler.php | 4 +- framework/Exceptions/messages.txt | 8 +-- framework/TApplication.php | 124 +++++++++++++++++++++++++------- framework/Web/Services/TPageService.php | 93 ++++++++++-------------- framework/Web/UI/TAssetManager.php | 4 +- framework/Web/UI/TThemeManager.php | 2 +- 7 files changed, 146 insertions(+), 91 deletions(-) diff --git a/framework/Data/TSqliteCache.php b/framework/Data/TSqliteCache.php index 8425ccf1..865c2a47 100644 --- a/framework/Data/TSqliteCache.php +++ b/framework/Data/TSqliteCache.php @@ -121,7 +121,7 @@ class TSqliteCache extends TModule implements ICache if(!function_exists('sqlite_open')) throw new TConfigurationException('sqlitecache_extension_required'); if($this->_file===null) - $this->_file=$application->getStatePath().'/sqlite.cache'; + $this->_file=$application->getRuntimePath().'/sqlite.cache'; $error=''; if(($this->_db=new SQLiteDatabase($this->_file,0666,$error))===false) throw new TConfigurationException('sqlitecache_connection_failed',$error); diff --git a/framework/Exceptions/TErrorHandler.php b/framework/Exceptions/TErrorHandler.php index 87d5d342..ca42c8ff 100644 --- a/framework/Exceptions/TErrorHandler.php +++ b/framework/Exceptions/TErrorHandler.php @@ -138,7 +138,7 @@ class TErrorHandler extends TModule header('Content-Type: text/html; charset=UTF-8'); if($param instanceof THttpException) $this->handleExternalError($param->getStatusCode(),$param); - else if(Prado::getApplication()->getMode()==='Debug') + else if(Prado::getApplication()->getMode()===TApplication::STATE_DEBUG) $this->displayException($param); else $this->handleExternalError(500,$param); @@ -192,7 +192,7 @@ class TErrorHandler extends TModule */ protected function handleRecursiveError($exception) { - if(Prado::getApplication()->getMode()==='Debug') + if(Prado::getApplication()->getMode()===TApplication::STATE_DEBUG) { echo "Recursive Error\n"; echo "

Recursive Error

\n"; diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt index 651287e1..d32b3005 100644 --- a/framework/Exceptions/messages.txt +++ b/framework/Exceptions/messages.txt @@ -23,9 +23,8 @@ map_addition_disallowed = The new item cannot be added to the map. 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. -application_configfile_inexistent = Application configuration file '%s' does not exist. -application_statepath_invalid = Application state path '%s' does not exist or is not writable by Web server process. -application_module_existing = Application module '%s' cannot be registered twice. +application_configpath_inexistent = Application configuration path '%s' does not exist. +application_runtimepath_invalid = Application runtime path '%s' does not exist or is not writable by Web server process. application_service_invalid = Service '%s' must implement IService interface. application_service_unknown = Requested service '%s' is not defined. application_service_unavailable = Service Unavailable. @@ -77,6 +76,7 @@ memcache_port_unchangeable = TMemCache.Port cannot be modified after the modu errorhandler_errortemplatepath_invalid = TErrorHandler.ErrorTemplatePath '%s' is invalid. Make sure it is in namespace form and points to a valid directory containing error template files. pageservice_page_unknown = Page '%s' Not Found +pageservice_pageclass_unknown = Page class '%s' is unknown. pageservice_basepath_invalid = TPageService.BasePath '%s' is not a valid directory. pageservice_page_required = Page Name Required pageservice_defaultpage_unchangeable = TPageService.DefaultPage cannot be modified after the service is initialized. @@ -89,7 +89,7 @@ pageserviceconf_using_invalid = element must have a "namespace" attrib pageserviceconf_module_invalid = element must have an "id" attribute in page directory configuration file '%s'. pageserviceconf_moduletype_required = must have a "class" attribute in page directory configuration file '%s'. pageserviceconf_parameter_invalid = element must have an "id" attribute in page directory configuration file '%s'. -pageserviceconf_page_invalid = element must have an "id" attribute and a "class" attribute in page directory configuration file '%s'. +pageserviceconf_page_invalid = element must have an "id" attribute in page directory configuration file '%s'. template_templatefile_invalid = Template file '%s' cannot open. template_closingtag_unexpected = %s: Unexpected closing tag '%s' is found. diff --git a/framework/TApplication.php b/framework/TApplication.php index 18d54c9c..8455c632 100644 --- a/framework/TApplication.php +++ b/framework/TApplication.php @@ -118,6 +118,18 @@ class TApplication extends TComponent * Default service ID */ const DEFAULT_SERVICE='page'; + /** + * Page service ID + */ + const PAGE_SERVICE='page'; + /** + * Application configuration file name + */ + const CONFIG_FILE='application.xml'; + /** + * Runtime directory name + */ + const RUNTIME_PATH='runtime'; /** * Config cache file */ @@ -165,7 +177,11 @@ class TApplication extends TComponent /** * @var IService current service instance */ - private $_service; + private $_service=null; + /** + * @var TPageService page service + */ + private $_pageService=null; /** * @var array list of application modules */ @@ -178,10 +194,14 @@ class TApplication extends TComponent * @var string configuration file */ private $_configFile; + /** + * @var string configuration path + */ + private $_configPath; /** * @var string directory storing application state */ - private $_statePath; + private $_runtimePath; /** * @var boolean if any global state is changed during the current request */ @@ -236,22 +256,36 @@ class TApplication extends TComponent * @param boolean whether to cache application configuration. Defaults to true. * @throws TConfigurationException if configuration file cannot be read or the state path is invalid. */ - public function __construct($configFile,$statePath=null,$cacheConfig=true) + public function __construct($configPath=null,$cacheConfig=true) { parent::__construct(); + + // register application as a singleton Prado::setApplication($this); - if(($this->_configFile=realpath($configFile))===false || !is_file($this->_configFile)) - throw new TConfigurationException('application_configfile_inexistent',$configFile); - if($statePath===null) - $this->_statePath=dirname($this->_configFile); - else if(is_dir($statePath) && is_writable($statePath)) - $this->_statePath=$statePath; + + // determine configuration path and file + if($configPath===null) + $configPath=dirname($_SERVER['SCRIPT_FILENAME']).'/protected'; + if(($this->_configPath=realpath($configPath))===false) + throw new TConfigurationException('application_configpath_inexistent',$configPath); + if(is_dir($this->_configPath)) + { + $configFile=$this->_configPath.'/'.self::CONFIG_FILE; + $this->_configFile=is_file($configFile) ? $configFile : null; + } else - throw new TConfigurationException('application_statepath_invalid',$statePath); - $this->_cacheFile=$cacheConfig ? $this->_statePath.'/'.self::CONFIGCACHE_FILE : null; + { + $this->_configFile=$this->_configPath; + $this->_configPath=dirname($this->_configPath); + } + $this->_runtimePath=$this->_configPath.'/'.self::RUNTIME_PATH; + if(!is_dir($this->_runtimePath) || !is_writable($this->_runtimePath)) + throw new TConfigurationException('application_runtimepath_invalid',$this->_runtimePath); - // generates unique ID by hashing the configuration file path - $this->_uniqueID=md5($this->_configFile); + $this->_cacheFile=$cacheConfig ? $this->_runtimePath.'/'.self::CONFIGCACHE_FILE : null; + + // generates unique ID by hashing the configuration path + $this->_uniqueID=md5($this->_configPath); } @@ -270,7 +304,7 @@ class TApplication extends TComponent $this->_requestCompleted=false; while($this->_step<$n) { - if($this->_mode==='Off') + if($this->_mode===self::STATE_OFF) throw new THttpException(503,'application_service_unavailable'); $method='on'.self::$_steps[$this->_step]; $this->$method($this); @@ -365,7 +399,7 @@ class TApplication extends TComponent $this->_globals=$value; else { - if(($content=@file_get_contents($this->getStatePath().'/'.self::GLOBAL_FILE))!==false) + if(($content=@file_get_contents($this->getRuntimePath().'/'.self::GLOBAL_FILE))!==false) $this->_globals=unserialize($content); } } @@ -389,7 +423,7 @@ class TApplication extends TComponent } if($saveFile) { - $fileName=$this->getStatePath().'/'.self::GLOBAL_FILE; + $fileName=$this->getRuntimePath().'/'.self::GLOBAL_FILE; if(version_compare(phpversion(),'5.1.0','>=')) file_put_contents($fileName,$content,LOCK_EX); else @@ -437,6 +471,14 @@ class TApplication extends TComponent $this->_mode=TPropertyValue::ensureEnum($value,array(self::STATE_OFF,self::STATE_DEBUG,self::STATE_NORMAL,self::STATE_PERFORMANCE)); } + /** + * @return string configuration path + */ + public function getConfigurationPath() + { + return $this->_configPath; + } + /** * @return string configuration file path */ @@ -449,9 +491,9 @@ class TApplication extends TComponent * Gets the directory storing application-level persistent data. * @return string application state path */ - public function getStatePath() + public function getRuntimePath() { - return $this->_statePath; + return $this->_runtimePath; } /** @@ -500,6 +542,29 @@ class TApplication extends TComponent return $this->_parameters; } + /** + * @return TPageService page service + */ + public function getPageService() + { + if(!$this->_pageService) + { + $this->_pageService=new TPageService; + $this->_pageService->init($this,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 */ @@ -637,6 +702,19 @@ class TApplication extends TComponent */ protected function initApplication() { + Prado::setPathOfAlias('Application',$this->_configPath); + + if($this->_configFile===null) + { + if(($serviceID=$this->getRequest()->getServiceID())===null) + $serviceID=self::DEFAULT_SERVICE; + if($serviceID===self::PAGE_SERVICE) + $this->_service=$this->getPageService(); + else + throw new THttpException(500,'application_service_unknown',$serviceID); + return; + } + if($this->_cacheFile===null || @filemtime($this->_cacheFile)_configFile)) { $config=new TApplicationConfiguration; @@ -657,7 +735,6 @@ class TApplication extends TComponent $config=Prado::unserialize(file_get_contents($this->_cacheFile)); } - // set path aliases and using namespaces foreach($config->getAliases() as $alias=>$path) Prado::setPathOfAlias($alias,$path); @@ -706,10 +783,11 @@ class TApplication extends TComponent foreach($serviceConfig[1] as $name=>$value) $service->setSubProperty($name,$value); $service->init($this,$serviceConfig[2]); - $this->attachEventHandler('RunService',array($service,'run')); } + else if($serviceID===self::DEFAULT_SERVICE) + $this->_service=$this->getPageService(); else - throw new TConfigurationException('application_service_unknown',$serviceID); + throw new THttpException(500,'application_service_unknown',$serviceID); } /** @@ -894,9 +972,7 @@ class TApplicationConfiguration extends TComponent /** * @var array list of service configurations */ - private $_services=array( - 'page'=>array('TPageService',array(),null) - ); + private $_services=array(); /** * @var array list of parameters */ diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php index edb7c213..485346e2 100644 --- a/framework/Web/Services/TPageService.php +++ b/framework/Web/Services/TPageService.php @@ -82,6 +82,10 @@ class TPageService extends TComponent implements IService * Prefix of ID used for storing parsed configuration in cache */ const CONFIG_CACHE_PREFIX='prado:pageservice:'; + /** + * Page template file extension + */ + const PAGE_FILE_EXT='.page'; /** * @var string id of this service (page) */ @@ -93,15 +97,11 @@ class TPageService extends TComponent implements IService /** * @var string default page */ - private $_defaultPage=null; + private $_defaultPage='Home'; /** * @var string requested page (path) */ private $_pagePath; - /** - * @var string requested page type - */ - private $_pageType; /** * @var TPage the requested page */ @@ -143,11 +143,13 @@ class TPageService extends TComponent implements IService */ public function init($application,$config) { + $application->setPageService($this); + $this->_application=$application; if($this->_basePath===null) { - $basePath=dirname($application->getConfigurationPath()).'/'.self::DEFAULT_BASEPATH; + $basePath=$application->getConfigurationPath().'/'.self::DEFAULT_BASEPATH; if(($this->_basePath=realpath($basePath))===false || !is_dir($this->_basePath)) throw new TConfigurationException('pageservice_basepath_invalid',$basePath); } @@ -156,12 +158,13 @@ class TPageService extends TComponent implements IService if(empty($this->_pagePath)) $this->_pagePath=$this->_defaultPage; if(empty($this->_pagePath)) - throw new THttpException(400,'pageservice_page_required'); + throw new THttpException(404,'pageservice_page_required'); if(($cache=$application->getCache())===null) { $pageConfig=new TPageConfiguration; - $pageConfig->loadXmlElement($config,dirname($application->getConfigurationFile()),null); + if($config!==null) + $pageConfig->loadXmlElement($config,$application->getConfigurationPath(),null); $pageConfig->loadConfigurationFiles($this->_pagePath,$this->_basePath); } else @@ -171,7 +174,7 @@ class TPageService extends TComponent implements IService if(is_array($arr)) { list($pageConfig,$timestamp)=$arr; - if($application->getMode()!=='Performance') + if($application->getMode()!==TApplication::STATE_PERFORMANCE) { // check to see if cache is the latest $paths=explode('.',$this->_pagePath); @@ -186,8 +189,12 @@ class TPageService extends TComponent implements IService } $configPath.='/'.$path; } - if($configCached && (@filemtime($application->getConfigurationFile())>$timestamp || @filemtime($configPath.'/'.self::CONFIG_FILE)>$timestamp)) - $configCached=false; + if($configCached) + { + $appConfig=$application->getConfigurationFile(); + if(!$appConfig || @filemtime($appConfig)>$timestamp || @filemtime($configPath.'/'.self::CONFIG_FILE)>$timestamp) + $configCached=false; + } } } else @@ -195,13 +202,13 @@ class TPageService extends TComponent implements IService if(!$configCached) { $pageConfig=new TPageConfiguration; - $pageConfig->loadXmlElement($config,dirname($application->getConfigurationFile()),null); + if($config!==null) + $pageConfig->loadXmlElement($config,$application->getConfigurationPath(),null); $pageConfig->loadConfigurationFiles($this->_pagePath,$this->_basePath); $cache->set(self::CONFIG_CACHE_PREFIX.$this->_pagePath,array($pageConfig,time())); } } - $this->_pageType=$pageConfig->getPageType(); // set path aliases and using namespaces foreach($pageConfig->getAliases() as $alias=>$path) @@ -239,6 +246,8 @@ class TPageService extends TComponent implements IService $application->getAuthorizationRules()->mergeWith($pageConfig->getRules()); $this->_initialized=true; + + $application->attachEventHandler('RunService',array($this,'run')); } /** @@ -405,33 +414,25 @@ class TPageService extends TComponent implements IService public function run() { $page=null; - if(($pos=strpos($this->_pageType,'.'))===false) - { - $className=$this->_pageType; - if(!class_exists($className,false)) - { - $p=explode('.',$this->_pagePath); - array_pop($p); - array_push($p,$className); - $path=$this->_basePath.'/'.implode('/',$p).Prado::CLASS_FILE_EXT; - include_once($path); - } - } - else + $path=$this->_basePath.'/'.strtr($this->_pagePath,'.','/'); + if(is_file($path.self::PAGE_FILE_EXT)) { - $className=substr($this->_pageType,$pos+1); - if(($path=Prado::getPathOfNamespace($this->_pageType,Prado::CLASS_FILE_EXT))!==null) + if(is_file($path.Prado::CLASS_FILE_EXT)) { + $className=basename($path); if(!class_exists($className,false)) - { - include_once($path); - } + include_once($path.Prado::CLASS_FILE_EXT); + if(!class_exists($className,false)) + throw new TConfigurationException('pageservice_pageclass_unknown',$className); } - } - if(class_exists($className,false)) + else + $className='TPage'; + $this->_properties['Template']=$this->getTemplateManager()->getTemplateByFileName($path.self::PAGE_FILE_EXT); $this->_page=new $className($this->_properties); + } else - throw new THttpException(404,'pageservice_page_unknown',$this->_pageType); + throw new THttpException(404,'pageservice_page_unknown',$this->_pagePath); + $writer=$this->_application->getResponse()->createHtmlWriter(); $this->_page->run($writer); $writer->flush(); @@ -468,10 +469,6 @@ class TPageConfiguration extends TComponent * @var array list of page initial property values */ private $_properties=array(); - /** - * @var string page type - */ - private $_pageType=null; /** * @var array list of namespaces to be used */ @@ -504,14 +501,6 @@ class TPageConfiguration extends TComponent return $this->_properties; } - /** - * @return string the requested page type - */ - public function getPageType() - { - return $this->_pageType; - } - /** * Returns list of path alias definitions. * The definitions are aggregated (top-down) from configuration files along the path @@ -610,10 +599,7 @@ class TPageConfiguration extends TComponent private function loadFromFile($fname,$page) { if(empty($fname) || !is_file($fname)) - { - if($page===null) - return; - } + return; $dom=new TXmlDocument; if($dom->loadFromFile($fname)) $this->loadXmlElement($dom,dirname($fname),$page); @@ -742,20 +728,13 @@ class TPageConfiguration extends TComponent foreach($pagesNode->getElementsByTagName('page') as $node) { $properties=$node->getAttributes(); - if(($type=$properties->remove('class'))===null) - $type='TPage'; if(($id=$properties->itemAt('id'))===null) throw new TConfigurationException('pageserviceconf_page_invalid',$configPath); if($id===$page) - { $this->_properties=array_merge($this->_properties,$properties->toArray()); - $this->_pageType=$type; - } } } } - if($page!==null && $this->_pageType===null) - throw new THttpException(404,'pageservice_page_unknown',$page); } } diff --git a/framework/Web/UI/TAssetManager.php b/framework/Web/UI/TAssetManager.php index 78b84177..f9a9dcb8 100644 --- a/framework/Web/UI/TAssetManager.php +++ b/framework/Web/UI/TAssetManager.php @@ -152,7 +152,7 @@ class TAssetManager extends TModule { $dir=$this->hash(dirname($fullpath)); $file=$this->_basePath.'/'.$dir.'/'.basename($fullpath); - if(!is_file($file) || $checkTimestamp || $this->_application->getMode()!=='Performance') + if(!is_file($file) || $checkTimestamp || $this->_application->getMode()!==TApplication::STATE_PERFORMANCE) { if(!is_dir($this->_basePath.'/'.$dir)) @mkdir($this->_basePath.'/'.$dir); @@ -165,7 +165,7 @@ class TAssetManager extends TModule else { $dir=$this->hash($fullpath); - if(!is_dir($this->_basePath.'/'.$dir) || $checkTimestamp || $this->_application->getMode()!=='Performance') + if(!is_dir($this->_basePath.'/'.$dir) || $checkTimestamp || $this->_application->getMode()!==TApplication::STATE_PERFORMANCE) $this->copyDirectory($fullpath,$this->_basePath.'/'.$dir); $this->_published[$path]=$this->_baseUrl.'/'.$dir; return $this->_published[$path]; diff --git a/framework/Web/UI/TThemeManager.php b/framework/Web/UI/TThemeManager.php index 6c7457ee..afe3f02a 100644 --- a/framework/Web/UI/TThemeManager.php +++ b/framework/Web/UI/TThemeManager.php @@ -224,7 +224,7 @@ class TTheme extends TComponent { list($skins,$cssFiles,$jsFiles,$timestamp)=$array; $cacheValid=true; - if($application->getMode()!=='Performance') + if($application->getMode()!==TApplication::STATE_PERFORMANCE) { if(($dir=opendir($themePath))===false) throw new TIOException('theme_path_inexistent',$themePath); -- cgit v1.2.3