From 99b820a5bf36158405208f140cf48f8aedf91fff Mon Sep 17 00:00:00 2001 From: xue <> Date: Mon, 14 Nov 2005 00:29:41 +0000 Subject: Added theme support. --- framework/Web/UI/TTheme.php | 160 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 132 insertions(+), 28 deletions(-) (limited to 'framework/Web/UI/TTheme.php') diff --git a/framework/Web/UI/TTheme.php b/framework/Web/UI/TTheme.php index 3d4d4e5d..452c473c 100644 --- a/framework/Web/UI/TTheme.php +++ b/framework/Web/UI/TTheme.php @@ -1,46 +1,129 @@ _themePath=$name; - $this->initialize(); + $this->_application=$application; + if($this->_themePath===null) + $this->_themePath=dirname($application->getConfigurationFile()).'/'.self::DEFAULT_THEME_PATH; + + $this->_initialized=true; } - private function initialize() + /** + * @return string id of this module + */ + public function getID() { - if(($theme=opendir($this->_themePath))===false) - throw new Exception("Invalid theme ".$this->_themePath); - while(($file=readdir($theme))!==false) + return $this->_id; + } + + /** + * @param string id of this module + */ + public function setID($value) + { + $this->_id=$value; + } + + public function getTheme($name) + { + $themePath=realpath($this->_themePath.'/'.$name); + if($themePath===false || !is_dir($this->_themePath)) + throw new TConfigurationException('thememanager_themepath_invalid',$themePath); + if(($cache=$this->_application->getCache())===null) + return new TTheme($themePath.'/'.self::THEME_FILE); + else { - if(basename($file,'.skin')!==$file) - $this->parseSkinFile($this->_themePath.'/'.$file); + $themeFile=$themePath.'/'.self::THEME_FILE; + $array=$cache->get(self::THEME_CACHE_PREFIX.$themePath); + if(is_array($array)) + { + list($theme,$timestamp)=$array; + if(filemtime($themeFile)<$timestamp) + return $theme; + } + $theme=new TTheme($themeFile); + $cache->set(self::THEME_CACHE_PREFIX.$themePath,array($theme,time())); + return $theme; } - closedir($theme); } - private function parseSkinFile($fileName) + public function getThemePath() { - if(($skin=simplexml_load_file($fileName))===false) - throw new Exception("Parsing $fileName failed."); - foreach($skin->children() as $type=>$control) + return $this->_themePath; + } + + public function setThemePath($value) + { + if($this->_initialized) + throw new TInvalidOperationException('thememanager_themepath_unchangeable'); + else + $this->_themePath=$value; + } +} + +class TTheme extends TTemplate +{ + private $_themePath; + private $_themeFile; + private $_skins=array(); + + public function __construct($themeFile) + { + $this->_themeFile=$themeFile; + $this->_themePath=dirname($themeFile); + if(is_file($themeFile) && is_readable($themeFile)) { - $attributes=array(); - foreach($control->attributes() as $name=>$value) + $theme=&$this->parse(file_get_contents($themeFile)); + foreach($theme as $skin) { - $attributes[strtolower($name)]=(string)$value; + if($skin[0]!==0) + throw new TConfigurationException('theme_control_nested',$skin[1]); + else if(!isset($skin[2])) // a text string, ignored + continue; + $type=$skin[1]; + $id=isset($skin[2]['skinid'])?$skin[2]['skinid']:0; + unset($skin[2]['skinid']); + if(isset($this->_skins[$type][$id])) + throw new TConfigurationException('theme_skinid_duplicated',$type,$id); + foreach($skin[2] as $name=>$value) + { + if(is_array($value) && $value[0]===0) + throw new TConfigurationException('theme_databind_unsupported',$type,$id,$name); + } + $this->_skins[$type][$id]=$skin[2]; } - $skinID=isset($attributes['skinid'])?(string)$attributes['skinid']:0; - unset($attributes['skinid']); - if(isset($this->_skins[$type][$skinID])) - throw new Exception("Duplicated skin $type.$skinID"); - else - $this->_skins[$type][$skinID]=$attributes; } + else + throw new TIOException('theme_themefile_invalid',$themeFile); } public function applySkin($control) @@ -52,11 +135,32 @@ class TTheme extends TComponent { foreach($this->_skins[$type][$id] as $name=>$value) { - $control->setSubProperty($name,$value); + if(is_array($value)) + $value=$this->evaluateExpression($value); + if(strpos($name,'.')===false) // is simple property or custom attribute + { + if($control->hasProperty($name)) + { + if($control->canSetProperty($name)) + { + $setter='set'.$name; + $control->$setter($value); + } + else + throw new TConfigurationException('theme_property_readonly',get_class($control),$name); + } + else if($control->getAllowCustomAttributes()) + $control->getAttributes()->add($name,$value); + else + throw new TConfigurationException('theme_property_undefined',get_class($control),$name); + } + else // complex property + $control->setSubProperty($name,$value); } + return true; } else - return; + return false; } } -- cgit v1.2.3