* @link http://www.pradosoft.com/
* @copyright Copyright © 2005-2014 PradoSoft
* @license http://www.pradosoft.com/license/
* @package Prado\Web\UI
*/
namespace Prado\Web\UI;
use Prado\Exceptions\TConfigurationException;
use Prado\Exceptions\TInvalidDataValueException;
use Prado\Exceptions\TInvalidOperationException;
use Prado\Prado;
use Prado\Web\Services\TPageService;
/**
* TThemeManager class
*
* TThemeManager manages the themes used in a Prado application.
*
* Themes are stored under the directory specified by the
* {@link setBasePath BasePath} property. The themes can be accessed
* via URL {@link setBaseUrl BaseUrl}. Each theme is represented by a subdirectory
* and all the files under that directory. The name of a theme is the name
* of the corresponding subdirectory.
* By default, the base path of all themes is a directory named "themes"
* under the directory containing the application entry script.
* To get a theme (normally you do not need to), call {@link getTheme}.
*
* TThemeManager may be configured within page service tag in application
* configuration file as follows,
*
* where {@link getCacheExpire CacheExpire}, {@link getCacheControl CacheControl}
* and {@link getBufferOutput BufferOutput} are configurable properties of THttpResponse.
*
* @author Qiang Xue
* @package Prado\Web\UI
* @since 3.0
*/
class TThemeManager extends \Prado\TModule
{
/**
* default themes base path
*/
const DEFAULT_BASEPATH='themes';
/**
* default theme class
*/
const DEFAULT_THEMECLASS = 'TTheme';
/**
* @var string
*/
private $_themeClass=self::DEFAULT_THEMECLASS;
/**
* @var boolean whether this module has been initialized
*/
private $_initialized=false;
/**
* @var string the directory containing all themes
*/
private $_basePath=null;
/**
* @var string the base URL for all themes
*/
private $_baseUrl=null;
/**
* Initializes the module.
* This method is required by IModule and is invoked by application.
* @param TXmlElement module configuration
*/
public function init($config)
{
$this->_initialized=true;
$service=$this->getService();
if($service instanceof TPageService)
$service->setThemeManager($this);
else
throw new TConfigurationException('thememanager_service_unavailable');
}
/**
* @param string name of the theme to be retrieved
* @return TTheme the theme retrieved
*/
public function getTheme($name)
{
$themePath=$this->getBasePath().DIRECTORY_SEPARATOR.$name;
$themeUrl=rtrim($this->getBaseUrl(),'/').'/'.$name;
return Prado::createComponent($this->getThemeClass(), $themePath, $themeUrl);
}
/**
* @param string|null $class Theme class name in namespace format
*/
public function setThemeClass($class) {
$this->_themeClass = $class===null ? self::DEFAULT_THEMECLASS : (string)$class;
}
/**
* @return string Theme class name in namespace format. Defaults to {@link TThemeManager::DEFAULT_THEMECLASS DEFAULT_THEMECLASS}.
*/
public function getThemeClass() {
return $this->_themeClass;
}
/**
* @return array list of available theme names
*/
public function getAvailableThemes()
{
$themes=array();
$basePath=$this->getBasePath();
$folder=@opendir($basePath);
while($file=@readdir($folder))
{
if($file!=='.' && $file!=='..' && $file!=='.svn' && is_dir($basePath.DIRECTORY_SEPARATOR.$file))
$themes[]=$file;
}
closedir($folder);
return $themes;
}
/**
* @return string the base path for all themes. It is returned as an absolute path.
* @throws TConfigurationException if base path is not set and "themes" directory does not exist.
*/
public function getBasePath()
{
if($this->_basePath===null)
{
$this->_basePath=dirname($this->getRequest()->getApplicationFilePath()).DIRECTORY_SEPARATOR.self::DEFAULT_BASEPATH;
if(($basePath=realpath($this->_basePath))===false || !is_dir($basePath))
throw new TConfigurationException('thememanager_basepath_invalid2',$this->_basePath);
$this->_basePath=$basePath;
}
return $this->_basePath;
}
/**
* @param string the base path for all themes. It must be in the format of a namespace.
* @throws TInvalidDataValueException if the base path is not a proper namespace.
*/
public function setBasePath($value)
{
if($this->_initialized)
throw new TInvalidOperationException('thememanager_basepath_unchangeable');
else
{
$this->_basePath=Prado::getPathOfNamespace($value);
if($this->_basePath===null || !is_dir($this->_basePath))
throw new TInvalidDataValueException('thememanager_basepath_invalid',$value);
}
}
/**
* @return string the base URL for all themes.
* @throws TConfigurationException If base URL is not set and a correct one cannot be determined by Prado.
*/
public function getBaseUrl()
{
if($this->_baseUrl===null)
{
$appPath=dirname($this->getRequest()->getApplicationFilePath());
$basePath=$this->getBasePath();
if(strpos($basePath,$appPath)===false)
throw new TConfigurationException('thememanager_baseurl_required');
$appUrl=rtrim(dirname($this->getRequest()->getApplicationUrl()),'/\\');
$this->_baseUrl=$appUrl.strtr(substr($basePath,strlen($appPath)),'\\','/');
}
return $this->_baseUrl;
}
/**
* @param string the base URL for all themes.
*/
public function setBaseUrl($value)
{
$this->_baseUrl=rtrim($value,'/');
}
}