summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--demos/controls/protected/application.xml4
-rw-r--r--demos/controls/protected/pages/HomePage.tpl4
-rw-r--r--framework/Web/Services/TPageService.php80
-rw-r--r--framework/Web/TAssetManager.php134
-rw-r--r--framework/Web/UI/TControl.php26
-rw-r--r--tests/UnitTests/framework/Data/xml/data3.xml2
-rw-r--r--tests/UnitTests/framework/Data/xml/data3.xml.out2
-rw-r--r--tests/UnitTests/framework/TestSystem/protected/application.xml2
9 files changed, 184 insertions, 71 deletions
diff --git a/.gitattributes b/.gitattributes
index 7c9dd4dd..0f1d392e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -34,6 +34,7 @@ framework/TODO.txt -text
framework/Web/Javascripts/WebForms.js -text
framework/Web/Services/TAssetService.php -text
framework/Web/Services/TPageService.php -text
+framework/Web/TAssetManager.php -text
framework/Web/THttpRequest.php -text
framework/Web/THttpResponse.php -text
framework/Web/THttpSession.php -text
diff --git a/demos/controls/protected/application.xml b/demos/controls/protected/application.xml
index ef8280d6..9bfa0ac6 100644
--- a/demos/controls/protected/application.xml
+++ b/demos/controls/protected/application.xml
@@ -12,8 +12,8 @@
<module id="session" type="THttpSession" />
</modules>
<services>
- <!-- page service, PageRootPath is required -->
- <service id="page" PageRootPath="Demo.pages" DefaultPage="home">
+ <!-- page service, PageBasePath is required -->
+ <service id="page" PageBasePath="Demo.pages" DefaultPage="home">
<!-- modules configured and loaded when page service is requested -->
<modules>
<!-- user manager module -->
diff --git a/demos/controls/protected/pages/HomePage.tpl b/demos/controls/protected/pages/HomePage.tpl
index c7b35f02..322f28a1 100644
--- a/demos/controls/protected/pages/HomePage.tpl
+++ b/demos/controls/protected/pages/HomePage.tpl
@@ -5,8 +5,8 @@
<com:TLabel Text="label" /><br/>
<com:System.Web.UI.WebControls.TButton text="Toggle Button" ForeColor="red" Font.size="18" Click="testClick" /> (requires membership)<br/>
<com:TCheckBox Text="Checkbox" /><br/>
-<com:TImage ImageUrl="/prado3/demos/images/fungii_logo.gif" />
-<com:TImageButton ImageUrl="/prado3/demos/images/fungii_logo.gif" /><br/>
+<com:TImage ImageUrl=<%=$this->TemplateControl->getAsset('fungii_logo.gif') %> />
+<com:TImageButton ImageUrl=<%=$this->TemplateControl->getAsset('fungii_logo.gif')%> /><br/>
<com:THyperLink Text="Visit a 'classless' page" NavigateUrl="?sp=page.plain" /> |
<com:THyperLink Text="Visit member only page" NavigateUrl="?sp=page.private.member" />
</com:TForm> \ No newline at end of file
diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php
index e4791543..f6609725 100644
--- a/framework/Web/Services/TPageService.php
+++ b/framework/Web/Services/TPageService.php
@@ -38,7 +38,7 @@ class TPageService extends TComponent implements IService
/**
* @var string root path of pages
*/
- private $_pageRootPath;
+ private $_pageBasePath;
/**
* @var string default page
*/
@@ -52,14 +52,6 @@ class TPageService extends TComponent implements IService
*/
private $_pageType;
/**
- * @var string the base URL for accessing published assets
- */
- private $_assetBaseUrl;
- /**
- * @var string the root path for storing published asset files
- */
- private $_assetRootPath;
- /**
* @var array list of initial page property values
*/
private $_properties;
@@ -86,8 +78,8 @@ class TPageService extends TComponent implements IService
{
$this->_application=$application;
- if(($pageRootPath=Prado::getPathOfNamespace($this->_pageRootPath))===null || !is_dir($pageRootPath))
- throw new TConfigurationException('pageservice_pagerootpath_invalid',$this->_pageRootPath);
+ if(($pageBasePath=Prado::getPathOfNamespace($this->_pageBasePath))===null || !is_dir($pageBasePath))
+ throw new TConfigurationException('pageservice_pagebasepath_invalid',$this->_pageBasePath);
$this->_pagePath=$application->getRequest()->getServiceParameter();
if(empty($this->_pagePath))
@@ -99,7 +91,7 @@ class TPageService extends TComponent implements IService
{
$pageConfig=new TPageConfiguration;
$pageConfig->loadXmlElement($config,dirname($application->getConfigurationFile()),null);
- $pageConfig->loadConfigurationFiles($this->_pagePath,$pageRootPath);
+ $pageConfig->loadConfigurationFiles($this->_pagePath,$pageBasePath);
}
else
{
@@ -113,7 +105,7 @@ class TPageService extends TComponent implements IService
// check to see if cache is the latest
$paths=explode('.',$this->_pagePath);
array_pop($paths);
- $configPath=$pageRootPath;
+ $configPath=$pageBasePath;
foreach($paths as $path)
{
if(@filemtime($configPath.'/'.self::CONFIG_FILE)>$timestamp)
@@ -133,7 +125,7 @@ class TPageService extends TComponent implements IService
{
$pageConfig=new TPageConfiguration;
$pageConfig->loadXmlElement($config,dirname($application->getConfigurationFile()),null);
- $pageConfig->loadConfigurationFiles($this->_pagePath,$pageRootPath);
+ $pageConfig->loadConfigurationFiles($this->_pagePath,$pageBasePath);
$cache->set(self::CONFIG_CACHE_PREFIX.$this->_pagePath,array($pageConfig,time()),$this->_cacheExpire<0?0:$this->_cacheExpire);
}
}
@@ -163,7 +155,7 @@ class TPageService extends TComponent implements IService
}
}
- // load modules specified in app config
+ // load modules specified in page directory config
foreach($pageConfig->getModules() as $id=>$moduleConfig)
{
$module=Prado::createComponent($moduleConfig[0]);
@@ -274,61 +266,21 @@ class TPageService extends TComponent implements IService
/**
* @return string root directory (in namespace form) storing pages
*/
- public function getPageRootPath()
+ public function getPageBasePath()
{
- return $this->_pageRootPath;
+ return $this->_pageBasePath;
}
/**
* @param string root directory (in namespace form) storing pages
* @throws TInvalidOperationException if the service is initialized already
*/
- public function setPageRootPath($value)
- {
- if($this->_initialized)
- throw new TInvalidOperationException('pageservice_pagerootpath_unchangeable');
- else
- $this->_pageRootPath=$value;
- }
-
- /**
- * @return string the root directory storing published asset files
- */
- public function getAssetRootPath()
- {
- return $this->_assetRootPath;
- }
-
- /**
- * @param string the root directory storing published asset files
- * @throws TInvalidOperationException if the service is initialized already
- */
- public function setAssetRootPath($value)
- {
- if($this->_initialized)
- throw new TInvalidOperationException('pageservice_assetrootpath_unchangeable');
- else
- $this->_assetRootPath=$value;
- }
-
- /**
- * @return string the base url that the published asset files can be accessed
- */
- public function getAssetBaseUrl()
- {
- return $this->_assetBaseUrl;
- }
-
- /**
- * @param string the base url that the published asset files can be accessed
- * @throws TInvalidOperationException if the service is initialized already
- */
- public function setAssetBaseUrl($value)
+ public function setPageBasePath($value)
{
if($this->_initialized)
- throw new TInvalidOperationException('pageservice_assetbaseurl_unchangeable');
+ throw new TInvalidOperationException('pageservice_pagebasepath_unchangeable');
else
- $this->_assetBaseUrl=$value;
+ $this->_pageBasePath=$value;
}
/**
@@ -347,7 +299,7 @@ class TPageService extends TComponent implements IService
$p=explode('.',$this->_pagePath);
array_pop($p);
array_push($p,$className);
- $path=Prado::getPathOfNamespace($this->_pageRootPath).'/'.implode('/',$p).Prado::CLASS_FILE_EXT;
+ $path=Prado::getPathOfNamespace($this->_pageBasePath).'/'.implode('/',$p).Prado::CLASS_FILE_EXT;
require_once($path);
}
}
@@ -419,7 +371,7 @@ class TPageConfiguration extends TComponent
*/
private $_modules=array(
'template'=>array('System.Web.UI.TTemplateManager',array(),null),
- //'asset'=>array('System.Web.TAssetManager',array(),null)
+ 'asset'=>array('System.Web.TAssetManager',array(),null)
);
/**
* @var array list of parameters
@@ -525,11 +477,11 @@ class TPageConfiguration extends TComponent
* @param string path to the page (dot-connected format)
* @param string root path for pages
*/
- public function loadConfigurationFiles($pagePath,$pageRootPath)
+ public function loadConfigurationFiles($pagePath,$pageBasePath)
{
$paths=explode('.',$pagePath);
$page=array_pop($paths);
- $path=$pageRootPath;
+ $path=$pageBasePath;
foreach($paths as $p)
{
$this->loadFromFile($path.'/'.TPageService::CONFIG_FILE,null);
diff --git a/framework/Web/TAssetManager.php b/framework/Web/TAssetManager.php
new file mode 100644
index 00000000..af4cfd73
--- /dev/null
+++ b/framework/Web/TAssetManager.php
@@ -0,0 +1,134 @@
+<?php
+
+class TAssetManager extends TComponent implements IModule
+{
+ const DEFAULT_BASEPATH='assets';
+ private $_basePath=null;
+ private $_baseUrl=null;
+ /**
+ * @var string module ID
+ */
+ private $_id;
+
+ /**
+ * Initializes the module.
+ * This method is required by IModule and is invoked by application.
+ * @param IApplication application
+ * @param TXmlElement module configuration
+ */
+ public function init($application,$config)
+ {
+ if($this->_basePath===null)
+ $this->_basePath=dirname($application->getRequest()->getPhysicalApplicationPath()).'/'.self::DEFAULT_BASEPATH;
+ if(!is_writable($this->_basePath) || !is_dir($this->_basePath))
+ throw new TConfigurationException('assetmanager_basepath_invalid',$this->_basePath);
+ if($this->_baseUrl===null)
+ $this->_baseUrl=dirname($application->getRequest()->getApplicationPath()).'/'.self::DEFAULT_BASEPATH;
+ }
+
+ /**
+ * @return string id of this module
+ */
+ public function getID()
+ {
+ return $this->_id;
+ }
+
+ /**
+ * @param string id of this module
+ */
+ public function setID($value)
+ {
+ $this->_id=$value;
+ }
+
+ /**
+ * @return string the root directory storing published asset files
+ */
+ public function getBasePath()
+ {
+ return $this->_basePath;
+ }
+
+ /**
+ * @param string the root directory storing published asset files
+ * @throws TInvalidOperationException if the service is initialized already
+ */
+ public function setBasePath($value)
+ {
+ if($this->_initialized)
+ throw new TInvalidOperationException('assetmanager_basepath_unchangeable');
+ else if(is_dir($value))
+ $this->_basePath=realpath($value);
+ else
+ throw new TInvalidDataValueException('assetmanage_basepath_invalid',$value);
+ }
+
+ /**
+ * @return string the base url that the published asset files can be accessed
+ */
+ public function getBaseUrl()
+ {
+ return $this->_baseUrl;
+ }
+
+ /**
+ * @param string the base url that the published asset files can be accessed
+ * @throws TInvalidOperationException if the service is initialized already
+ */
+ public function setBaseUrl($value)
+ {
+ if($this->_initialized)
+ throw new TInvalidOperationException('pageservice_baseurl_unchangeable');
+ else
+ $this->_baseUrl=$value;
+ }
+
+ public function publishDirectory($path,$forceOverwrite=false)
+ {
+ if(($fullpath=realpath($path))!==false && is_dir($fullpath))
+ {
+ $dir=md5($fullpath);
+ if(!is_dir($this->_basePath.'/'.$dir))
+ $this->copyDirectory($this->_basePath.'/'.$dir);
+ return $this->_baseUrl.'/'.$dir;
+ }
+ else
+ throw new TInvalidDataValueException('assetmanager_directory_invalid',$path);
+ }
+
+ protected function copyDirectory($src,$dst)
+ {
+ mkdir($dst);
+ $folder=opendir($src);
+ while($file=readdir($folder))
+ {
+ if($file==='.' || $file==='..')
+ continue;
+ else if(is_file($src.'/'.$file))
+ copy($src.'/'.$file,$dst.'/'.$file);
+ else
+ $this->copyDirectory($src.'/'.$file,$dst.'/'.$file);
+ }
+ closedir($folder);
+ }
+
+ public function publishFile($path,$forceOverwrite=false)
+ {
+ if(($fullpath=realpath($path))!==false && is_file($fullpath))
+ {
+ $dir=md5(dirname($fullpath));
+ $file=$this->_basePath.'/'.$dir.'/'.basename($fullpath);
+ if(!is_file($file))
+ {
+ @mkdir($this->_basePath.'/'.$dir);
+ copy($fullpath,$file);
+ }
+ return $this->_baseUrl.'/'.$dir.'/'.basename($fullpath);
+ }
+ else
+ throw new TInvalidDataValueException('assetmanager_file_invalid',$path);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php
index a3d3c93a..65993664 100644
--- a/framework/Web/UI/TControl.php
+++ b/framework/Web/UI/TControl.php
@@ -69,6 +69,10 @@ class TControl extends TComponent
* prefix to an ID automatically generated
*/
const AUTOMATIC_ID_PREFIX='ctl';
+ /**
+ * default control asset path
+ */
+ const ASSET_PATH='assets';
/**
* the stage of lifecycles that the control is currently at
@@ -270,6 +274,28 @@ class TControl extends TComponent
return Prado::getApplication()->getUser();
}
+ public function publishFile($file)
+ {
+ return Prado::getApplication()->getService()->getAssetManager()->publishFile($file);
+ }
+
+ public function publishDirectory($directory)
+ {
+ return Prado::getApplication()->getService()->getAssetManager()->publishDirectory($directory);
+ }
+
+ public function getAsset($assetName)
+ {
+ $class=new ReflectionClass(get_class($this));
+ $assetFile=dirname($class->getFileName()).'/'.self::ASSET_PATH.'/'.$assetName;
+ if(is_file($assetFile))
+ return $this->publishFile($assetFile);
+ else if(is_dir($assetFile))
+ return $this->publishDirectory($assetFile);
+ else
+ return '';
+ }
+
/**
* Returns the id of the control.
* Control ID can be either manually set or automatically generated.
diff --git a/tests/UnitTests/framework/Data/xml/data3.xml b/tests/UnitTests/framework/Data/xml/data3.xml
index 9e66a7f0..5eaece3b 100644
--- a/tests/UnitTests/framework/Data/xml/data3.xml
+++ b/tests/UnitTests/framework/Data/xml/data3.xml
@@ -11,7 +11,7 @@
</module>
</modules>
<services default="page">
- <service id="page" RootPath="protected/pages">
+ <service id="page" BasePath="protected/pages">
<modules>
<module id="template" type="System.Modules.TTemplateManager" />
<module id="session" type="System.Modules.TSession" />
diff --git a/tests/UnitTests/framework/Data/xml/data3.xml.out b/tests/UnitTests/framework/Data/xml/data3.xml.out
index a87d0558..d46e65b9 100644
--- a/tests/UnitTests/framework/Data/xml/data3.xml.out
+++ b/tests/UnitTests/framework/Data/xml/data3.xml.out
@@ -10,7 +10,7 @@
</module>
</modules>
<services default="page">
- <service id="page" RootPath="protected/pages">
+ <service id="page" BasePath="protected/pages">
<modules>
<module id="template" type="System.Modules.TTemplateManager" />
<module id="session" type="System.Modules.TSession" />
diff --git a/tests/UnitTests/framework/TestSystem/protected/application.xml b/tests/UnitTests/framework/TestSystem/protected/application.xml
index 0ee5f172..6ca4aaa8 100644
--- a/tests/UnitTests/framework/TestSystem/protected/application.xml
+++ b/tests/UnitTests/framework/TestSystem/protected/application.xml
@@ -10,7 +10,7 @@
<module id="cache" type="System.Data.TSqliteCache" DbFile="TestSystem/protected/data/test.db" />
</modules>
<services>
- <service id="page" RootPath="TestSystem/protected/pages" />
+ <service id="page" BasePath="TestSystem/protected/pages" />
</services>
<parameters>
<parameter id="param1">value 1</parameter>