summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--framework/Data/TSqliteCache.php2
-rw-r--r--framework/Exceptions/TErrorHandler.php4
-rw-r--r--framework/Exceptions/messages.txt8
-rw-r--r--framework/TApplication.php124
-rw-r--r--framework/Web/Services/TPageService.php93
-rw-r--r--framework/Web/UI/TAssetManager.php4
-rw-r--r--framework/Web/UI/TThemeManager.php2
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 "<html><head><title>Recursive Error</title></head>\n";
echo "<body><h1>Recursive Error</h1>\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 = <using> element must have a "namespace" attrib
pageserviceconf_module_invalid = <module> element must have an "id" attribute in page directory configuration file '%s'.
pageserviceconf_moduletype_required = <module id="%s"> must have a "class" attribute in page directory configuration file '%s'.
pageserviceconf_parameter_invalid = <parameter> element must have an "id" attribute in page directory configuration file '%s'.
-pageserviceconf_page_invalid = <page> element must have an "id" attribute and a "class" attribute in page directory configuration file '%s'.
+pageserviceconf_page_invalid = <page> 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
@@ -119,6 +119,18 @@ class TApplication extends TComponent
*/
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
*/
const CONFIGCACHE_FILE='config.cache';
@@ -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
*/
@@ -179,9 +195,13 @@ class TApplication extends TComponent
*/
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
@@ -438,6 +472,14 @@ class TApplication extends TComponent
}
/**
+ * @return string configuration path
+ */
+ public function getConfigurationPath()
+ {
+ return $this->_configPath;
+ }
+
+ /**
* @return string configuration file path
*/
public function getConfigurationFile()
@@ -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;
}
/**
@@ -501,6 +543,29 @@ class TApplication extends TComponent
}
/**
+ * @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
*/
public function getRequest()
@@ -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)<filemtime($this->_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
@@ -83,6 +83,10 @@ class TPageService extends TComponent implements IService
*/
const CONFIG_CACHE_PREFIX='prado:pageservice:';
/**
+ * Page template file extension
+ */
+ const PAGE_FILE_EXT='.page';
+ /**
* @var string id of this service (page)
*/
private $_id;
@@ -93,16 +97,12 @@ 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
*/
private $_page=null;
@@ -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();
@@ -469,10 +470,6 @@ class TPageConfiguration extends TComponent
*/
private $_properties=array();
/**
- * @var string page type
- */
- private $_pageType=null;
- /**
* @var array list of namespaces to be used
*/
private $_usings=array();
@@ -505,14 +502,6 @@ class TPageConfiguration extends TComponent
}
/**
- * @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
* to the specified page. Each array element represents a single alias definition,
@@ -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);