From b404b6fed5dc814ceb2cf03a17b20ff9d6da775d Mon Sep 17 00:00:00 2001 From: xue <> Date: Mon, 21 Nov 2005 21:01:09 +0000 Subject: --- framework/Exceptions/messages.txt | 16 ++++- framework/Security/TAuthManager.php | 2 +- framework/TApplication.php | 4 +- framework/Web/Services/TPageService.php | 107 ++++++++++++++++++++++++-------- framework/core.php | 4 ++ 5 files changed, 103 insertions(+), 30 deletions(-) diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt index 63c03214..3788ce37 100644 --- a/framework/Exceptions/messages.txt +++ b/framework/Exceptions/messages.txt @@ -30,7 +30,8 @@ application_service_unknown = Requested service '%s' is not defined. application_service_unavailable = Service Unavailable. appconfig_aliaspath_invalid = Application configuration uses an invalid file path "%s". -appconfig_aliasid_required = Application configuration element must have an "id" attribute. +appconfig_alias_invalid = Application configuration element must have an "id" attribute and a "path" attribute. +appconfig_alias_redefined = Application configuration cannot be redefined. appconfig_using_invalid = Application configuration element must have a "namespace" attribute. appconfig_moduleid_required = Application configuration element must have an "id" attribute. appconfig_moduletype_required = Application configuration must have a "type" attribute. @@ -75,6 +76,19 @@ 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_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. +pageservice_basepath_unchangeable = TPageService.BasePath cannot be modified after the service is initialized. + +pageserviceconf_file_invalid = Unable to open page directory configuration file '%s'. +pageserviceconf_aliaspath_invalid = uses an invalid file path "%s" in page directory configuration file '%s'. +pageserviceconf_alias_invalid = element must have an "id" attribute and a "path" attribute in page directory configuration file '%s'. +pageserviceconf_using_invalid = element must have a "namespace" attribute in page directory configuration file '%s'. +pageserviceconf_module_invalid = element must have an "id" attribute in page directory configuration file '%s'. +pageserviceconf_moduletype_required = must have a "type" 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 "type" 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/Security/TAuthManager.php b/framework/Security/TAuthManager.php index f24a1bdd..789b9fd7 100644 --- a/framework/Security/TAuthManager.php +++ b/framework/Security/TAuthManager.php @@ -155,7 +155,7 @@ class TAuthManager extends TComponent implements IModule $this->onAuthenticate($param); $service=$this->_application->getService(); - if(($service instanceof TPageService) && $service->isRequestingPage($this->getLoginPage())) + if(($service instanceof TPageService) && $service->getRequestedPagePath()===$this->getLoginPage()) $this->_skipAuthorization=true; } diff --git a/framework/TApplication.php b/framework/TApplication.php index 665ed076..f4d8c124 100644 --- a/framework/TApplication.php +++ b/framework/TApplication.php @@ -768,10 +768,12 @@ class TApplicationConfiguration extends TComponent $p=realpath($configPath.'/'.$path); if($p===false || !is_dir($p)) throw new TConfigurationException('appconfig_aliaspath_invalid',$id,$path); + if(isset($this->_aliases[$id])) + throw new TConfigurationException('appconfig_alias_redefined',$id); $this->_aliases[$id]=$p; } else - throw new TConfigurationException('appconfig_aliasid_required'); + throw new TConfigurationException('appconfig_alias_invalid'); } foreach($pathsNode->getElementsByTagName('using') as $usingNode) { diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php index 048bead3..3c57cfc3 100644 --- a/framework/Web/Services/TPageService.php +++ b/framework/Web/Services/TPageService.php @@ -10,6 +10,9 @@ * @package System.Web.Services */ +/** + * Include classes to be used by page service + */ Prado::using('System.Web.UI.TPage'); Prado::using('System.Web.TTemplateManager'); Prado::using('System.Web.TThemeManager'); @@ -18,7 +21,46 @@ Prado::using('System.Web.TAssetManager'); /** * TPageService class. * - * TPageService implements a service that can serve user requested pages. + * TPageService implements the service for serving user page requests. + * + * Pages that are available to client users are stored under a directory specified by + * {@link setBasePath BasePath}. The directory may contain subdirectories. + * A directory may be used to group together the pages serving for the similar goal. + * Each directory must contain a configuration file config.xml that is similar to the application + * configuration file. The only difference is that the page directory configuration + * contains a mapping between page IDs and page types. The page IDs are visible + * by client users while page types are used on the server side. + * A page is requested via page path, which is a dot-connected directory names + * appended by the page ID. Assume '/Users/Admin' is the directory + * containing the page 'Update' whose type is UpdateUserPage. Then the page can + * be requested via 'Users.Admin.Update'. + * + * Modules can be configured and loaded in page directory configurations. + * Configuration of a module in a subdirectory will overwrite its parent + * directory's configuration, if both configurations refer to the same module. + * + * By default, TPageService will automatically load three modules: + * - {@link TTemplateManager} : manages page and control templates + * - {@link TThemeManager} : manages themes used in a Prado application + * - {@link TAssetManager} : manages assets used in a Prado application. + * + * In page directory configurations, static authorization rules can also be specified, + * which governs who and which roles can access particular pages. + * Refer to {@link TAuthorizationRule} for more details about authorization rules. + * Page authorization rules can be configured within an tag in + * each page directory configuration as follows, + * + * + * + * + * + * where the 'pages' attribute may be filled with a sequence of comma-separated + * page IDs. If 'pages' attribute does not appear in a rule, the rule will be + * applied to all pages in this directory and all subdirectories (recursively). + * Application of authorization rules are in a bottom-up fashion, starting from + * the directory containing the requested page up to all parent directories. + * The first matching rule will be used. The last rule always allows all users + * accessing to any resources. * * @author Qiang Xue * @version $Revision: $ $Date: $ @@ -31,6 +73,10 @@ class TPageService extends TComponent implements IService * Configuration file name */ const CONFIG_FILE='config.xml'; + /** + * Default base path + */ + const DEFAULT_BASEPATH='pages'; /** * Prefix of ID used for storing parsed configuration in cache */ @@ -42,7 +88,7 @@ class TPageService extends TComponent implements IService /** * @var string root path of pages */ - private $_basePath; + private $_basePath=null; /** * @var string default page */ @@ -90,8 +136,12 @@ class TPageService extends TComponent implements IService { $this->_application=$application; - if(($basePath=Prado::getPathOfNamespace($this->_basePath))===null || !is_dir($basePath)) - throw new TConfigurationException('pageservice_basepath_invalid',$this->_basePath); + if($this->_basePath===null) + { + $basePath=dirname($application->getConfigurationPath()).'/'.self::DEFAULT_BASEPATH; + if(($this->_basePath=realpath($basePath))===false || !is_dir($this->_basePath)) + throw new TConfigurationException('pageservice_basepath_invalid',$basePath); + } $this->_pagePath=$application->getRequest()->getServiceParameter(); if(empty($this->_pagePath)) @@ -103,7 +153,7 @@ class TPageService extends TComponent implements IService { $pageConfig=new TPageConfiguration; $pageConfig->loadXmlElement($config,dirname($application->getConfigurationFile()),null); - $pageConfig->loadConfigurationFiles($this->_pagePath,$basePath); + $pageConfig->loadConfigurationFiles($this->_pagePath,$this->_basePath); } else { @@ -117,7 +167,7 @@ class TPageService extends TComponent implements IService // check to see if cache is the latest $paths=explode('.',$this->_pagePath); array_pop($paths); - $configPath=$basePath; + $configPath=$this->_basePath; foreach($paths as $path) { if(@filemtime($configPath.'/'.self::CONFIG_FILE)>$timestamp) @@ -137,7 +187,7 @@ class TPageService extends TComponent implements IService { $pageConfig=new TPageConfiguration; $pageConfig->loadXmlElement($config,dirname($application->getConfigurationFile()),null); - $pageConfig->loadConfigurationFiles($this->_pagePath,$basePath); + $pageConfig->loadConfigurationFiles($this->_pagePath,$this->_basePath); $cache->set(self::CONFIG_CACHE_PREFIX.$this->_pagePath,array($pageConfig,time())); } } @@ -247,11 +297,11 @@ class TPageService extends TComponent implements IService } /** - * @return boolean true if the pagepath is currently being requested, false otherwise + * @return string the requested page path */ - public function isRequestingPage($pagePath) + public function getRequestedPagePath() { - return $this->_pagePath===$pagePath; + return $this->_pagePath; } /** @@ -284,14 +334,14 @@ class TPageService extends TComponent implements IService /** * @param string root directory (in namespace form) storing pages - * @throws TInvalidOperationException if the service is initialized already + * @throws TInvalidOperationException if the service is initialized already or basepath is invalid */ public function setBasePath($value) { if($this->_initialized) throw new TInvalidOperationException('pageservice_basepath_unchangeable'); - else - $this->_basePath=$value; + else if(($this->_basePath=realpath(Prado::getPathOfNamespace($value)))===false || !is_dir($this->_basePath)) + throw new TConfigurationException('pageservice_basepath_invalid',$value); } /** @@ -310,8 +360,8 @@ class TPageService extends TComponent implements IService $p=explode('.',$this->_pagePath); array_pop($p); array_push($p,$className); - $path=Prado::getPathOfNamespace($this->_basePath).'/'.implode('/',$p).Prado::CLASS_FILE_EXT; - require_once($path); + $path=$this->_basePath.'/'.implode('/',$p).Prado::CLASS_FILE_EXT; + include_once($path); } } else @@ -321,7 +371,7 @@ class TPageService extends TComponent implements IService { if(!class_exists($className,false)) { - require_once($path); + include_once($path); } } } @@ -519,7 +569,7 @@ class TPageConfiguration extends TComponent if($dom->loadFromFile($fname)) $this->loadXmlElement($dom,dirname($fname),$page); else - throw new TConfigurationException('pageservice_configfile_invalid',$fname); + throw new TConfigurationException('pageserviceconf_file_invalid',$fname); } /** @@ -540,20 +590,20 @@ class TPageConfiguration extends TComponent $p=str_replace('\\','/',$p); $path=realpath(preg_match('/^\\/|.:\\//',$p)?$p:$configPath.'/'.$p); if($path===false || !is_dir($path)) - throw new TConfigurationException('pageservice_alias_path_invalid',$configPath,$id,$p); + throw new TConfigurationException('pageserviceconf_aliaspath_invalid',$id,$p,$configPath); if(isset($this->_aliases[$id])) - throw new TConfigurationException('pageservice_alias_redefined',$configPath,$id); + throw new TConfigurationException('pageserviceconf_alias_redefined',$id,$configPath); $this->_aliases[$id]=$path; } else - throw new TConfigurationException('pageservice_alias_element_invalid',$configPath); + 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('pageservice_using_element_invalid',$configPath); + throw new TConfigurationException('pageserviceconf_using_invalid',$configPath); } } @@ -565,10 +615,10 @@ class TPageConfiguration extends TComponent $properties=$node->getAttributes(); $type=$properties->remove('type'); if(($id=$properties->itemAt('id'))===null) - throw new TConfigurationException('pageservice_module_element_invalid',$configPath); + throw new TConfigurationException('pageserviceconf_module_invalid',$configPath); if(isset($this->_modules[$id])) { - if($type===null) + if($type===null || $type===$this->_modules[$id][0]) { $this->_modules[$id][1]=array_merge($this->_modules[$id][1],$properties->toArray()); $elements=$this->_modules[$id][2]->getElements(); @@ -576,10 +626,13 @@ class TPageConfiguration extends TComponent $elements->add($element); } else - throw new TConfigurationException('pageservice_module_redefined',$configPath,$id); + { + $node->setParent(null); + $this->_modules[$id]=array($type,$properties->toArray(),$node); + } } else if($type===null) - throw new TConfigurationException('pageservice_module_element_invalid',$configPath); + throw new TConfigurationException('pageserviceconf_moduletype_required',$id,$configPath); else { $node->setParent(null); @@ -595,7 +648,7 @@ class TPageConfiguration extends TComponent { $properties=$node->getAttributes(); if(($id=$properties->remove('id'))===null) - throw new TConfigurationException('pageservice_parameter_element_invalid'); + throw new TConfigurationException('pageserviceconf_parameter_invalid',$configPath); if(($type=$properties->remove('type'))===null) $this->_parameters[$id]=$node->getValue(); else @@ -643,7 +696,7 @@ class TPageConfiguration extends TComponent $type=$properties->remove('type'); $id=$properties->itemAt('id'); if($id===null || $type===null) - throw new TConfigurationException('pageservice_page_element_invalid',$configPath); + throw new TConfigurationException('pageserviceconf_page_invalid',$configPath); if($id===$page) { $this->_properties=array_merge($this->_properties,$properties->toArray()); diff --git a/framework/core.php b/framework/core.php index f61761a9..bd143117 100644 --- a/framework/core.php +++ b/framework/core.php @@ -626,6 +626,10 @@ class PradoBase return $languages; } + /** + * Returns the most preferred language by the client user. + * @return string the most preferred language by the client user, defaults to English. + */ public static function getPreferredLanguage() { static $language=null; -- cgit v1.2.3