[ Index ]
 

Code source de PRADO 3.0.6

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/framework/Web/UI/ -> TThemeManager.php (source)

   1  <?php
   2  /**
   3   * TThemeManager class
   4   *
   5   * @author Qiang Xue <qiang.xue@gmail.com>
   6   * @link http://www.pradosoft.com/
   7   * @copyright Copyright &copy; 2005 PradoSoft
   8   * @license http://www.pradosoft.com/license/
   9   * @version $Id: TThemeManager.php 1536 2006-12-01 19:51:21Z xue $
  10   * @package System.Web.UI
  11   */
  12  
  13  Prado::using('System.Web.Services.TPageService');
  14  
  15  /**
  16   * TThemeManager class
  17   *
  18   * TThemeManager manages the themes used in a Prado application.
  19   *
  20   * Themes are stored under the directory specified by the
  21   * {@link setBasePath BasePath} property. The themes can be accessed
  22   * via URL {@link setBaseUrl BaseUrl}. Each theme is represented by a subdirectory
  23   * and all the files under that directory. The name of a theme is the name
  24   * of the corresponding subdirectory.
  25   * By default, the base path of all themes is a directory named "themes"
  26   * under the directory containing the application entry script.
  27   * To get a theme (normally you do not need to), call {@link getTheme}.
  28   *
  29   * TThemeManager may be configured within page service tag in application
  30   * configuration file as follows,
  31   * <module id="themes" class="System.Web.UI.TThemeManager"
  32   *         BasePath="Application.themes" BaseUrl="/themes" />
  33   * where {@link getCacheExpire CacheExpire}, {@link getCacheControl CacheControl}
  34   * and {@link getBufferOutput BufferOutput} are configurable properties of THttpResponse.
  35   *
  36   * @author Qiang Xue <qiang.xue@gmail.com>
  37   * @version $Id: TThemeManager.php 1536 2006-12-01 19:51:21Z xue $
  38   * @package System.Web.UI
  39   * @since 3.0
  40   */
  41  class TThemeManager extends TModule
  42  {
  43      /**
  44       * default themes base path
  45       */
  46      const DEFAULT_BASEPATH='themes';
  47      /**
  48       * @var boolean whether this module has been initialized
  49       */
  50      private $_initialized=false;
  51      /**
  52       * @var string the directory containing all themes
  53       */
  54      private $_basePath=null;
  55      /**
  56       * @var string the base URL for all themes
  57       */
  58      private $_baseUrl=null;
  59  
  60      /**
  61       * Initializes the module.
  62       * This method is required by IModule and is invoked by application.
  63       * @param TXmlElement module configuration
  64       */
  65  	public function init($config)
  66      {
  67          $this->_initialized=true;
  68          $service=$this->getService();
  69          if($service instanceof TPageService)
  70              $service->setThemeManager($this);
  71          else
  72              throw new TConfigurationException('thememanager_service_unavailable');
  73      }
  74  
  75      /**
  76       * @param string name of the theme to be retrieved
  77       * @return TTheme the theme retrieved
  78       */
  79  	public function getTheme($name)
  80      {
  81          $themePath=$this->getBasePath().'/'.$name;
  82          $themeUrl=rtrim($this->getBaseUrl(),'/').'/'.$name;
  83          return new TTheme($themePath,$themeUrl);
  84  
  85      }
  86  
  87      /**
  88       * @return array list of available theme names
  89       */
  90  	public function getAvailableThemes()
  91      {
  92          $themes=array();
  93          $basePath=$this->getBasePath();
  94          $folder=@opendir($basePath);
  95          while($file=@readdir($folder))
  96          {
  97              if($file!=='.' && $file!=='..' && $file!=='.svn' && is_dir($basePath.'/'.$file))
  98                  $themes[]=$file;
  99          }
 100          closedir($folder);
 101          return $themes;
 102      }
 103  
 104      /**
 105       * @return string the base path for all themes. It is returned as an absolute path.
 106       * @throws TConfigurationException if base path is not set and "themes" directory does not exist.
 107       */
 108  	public function getBasePath()
 109      {
 110          if($this->_basePath===null)
 111          {
 112              $this->_basePath=dirname($this->getRequest()->getApplicationFilePath()).'/'.self::DEFAULT_BASEPATH;
 113              if(($basePath=realpath($this->_basePath))===false || !is_dir($basePath))
 114                  throw new TConfigurationException('thememanager_basepath_invalid2',$this->_basePath);
 115              $this->_basePath=$basePath;
 116          }
 117          return $this->_basePath;
 118      }
 119  
 120      /**
 121       * @param string the base path for all themes. It must be in the format of a namespace.
 122       * @throws TInvalidDataValueException if the base path is not a proper namespace.
 123       */
 124  	public function setBasePath($value)
 125      {
 126          if($this->_initialized)
 127              throw new TInvalidOperationException('thememanager_basepath_unchangeable');
 128          else
 129          {
 130              $this->_basePath=Prado::getPathOfNamespace($value);
 131              if($this->_basePath===null || !is_dir($this->_basePath))
 132                  throw new TInvalidDataValueException('thememanager_basepath_invalid',$value);
 133          }
 134      }
 135  
 136      /**
 137       * @return string the base URL for all themes.
 138       * @throws TConfigurationException If base URL is not set and a correct one cannot be determined by Prado.
 139       */
 140  	public function getBaseUrl()
 141      {
 142          if($this->_baseUrl===null)
 143          {
 144              $appPath=dirname($this->getRequest()->getApplicationFilePath());
 145              $basePath=$this->getBasePath();
 146              if(strpos($basePath,$appPath)===false)
 147                  throw new TConfigurationException('thememanager_baseurl_required');
 148              $appUrl=rtrim(dirname($this->getRequest()->getApplicationUrl()),'/\\');
 149              $this->_baseUrl=$appUrl.strtr(substr($basePath,strlen($appPath)),'\\','/');
 150          }
 151          return $this->_baseUrl;
 152      }
 153  
 154      /**
 155       * @param string the base URL for all themes.
 156       */
 157  	public function setBaseUrl($value)
 158      {
 159          $this->_baseUrl=rtrim($value,'/');
 160      }
 161  }
 162  
 163  /**
 164   * TTheme class
 165   *
 166   * TTheme represents a particular theme. It is merely a collection of skins
 167   * that are applicable to the corresponding controls.
 168   *
 169   * Each theme is stored as a directory and files under that directory.
 170   * The theme name is the directory name. When TTheme is created, the files
 171   * whose name has the extension ".skin" are parsed and saved as controls skins.
 172   *
 173   * A skin is essentially a list of initial property values that are to be applied
 174   * to a control when the skin is applied.
 175   * Each type of control can have multiple skins identified by the SkinID.
 176   * If a skin does not have SkinID, it is the default skin that will be applied
 177   * to controls that do not specify particular SkinID.
 178   *
 179   * Whenever possible, TTheme will try to make use of available cache to save
 180   * the parsing time.
 181   *
 182   * To apply a theme to a particular control, call {@link applySkin}.
 183   *
 184   * @author Qiang Xue <qiang.xue@gmail.com>
 185   * @version $Id: TThemeManager.php 1536 2006-12-01 19:51:21Z xue $
 186   * @package System.Web.UI
 187   * @since 3.0
 188   */
 189  class TTheme extends TApplicationComponent implements ITheme
 190  {
 191      /**
 192       * prefix for cache variable name used to store parsed themes
 193       */
 194      const THEME_CACHE_PREFIX='prado:theme:';
 195      /**
 196       * Extension name of skin files
 197       */
 198      const SKIN_FILE_EXT='.skin';
 199      /**
 200       * @var string theme path
 201       */
 202      private $_themePath;
 203      /**
 204       * @var string theme url
 205       */
 206      private $_themeUrl;
 207      /**
 208       * @var array list of skins for the theme
 209       */
 210      private $_skins=null;
 211      /**
 212       * @var string theme name
 213       */
 214      private $_name='';
 215      /**
 216       * @var array list of css files
 217       */
 218      private $_cssFiles=array();
 219      /**
 220       * @var array list of js files
 221       */
 222      private $_jsFiles=array();
 223  
 224      /**
 225       * Constructor.
 226       * @param string theme path
 227       * @param string theme URL
 228       * @throws TConfigurationException if theme path does not exist or any parsing error of the skin files
 229       */
 230  	public function __construct($themePath,$themeUrl)
 231      {
 232          $this->_themeUrl=$themeUrl;
 233          $this->_themePath=realpath($themePath);
 234          $this->_name=basename($themePath);
 235          $cacheValid=false;
 236          // TODO: the following needs to be cleaned up (Qiang)
 237          if(($cache=$this->getApplication()->getCache())!==null)
 238          {
 239              $array=$cache->get(self::THEME_CACHE_PREFIX.$themePath);
 240              if(is_array($array))
 241              {
 242                  list($skins,$cssFiles,$jsFiles,$timestamp)=$array;
 243                  if($this->getApplication()->getMode()!==TApplicationMode::Performance)
 244                  {
 245                      if(($dir=opendir($themePath))===false)
 246                          throw new TIOException('theme_path_inexistent',$themePath);
 247                      $cacheValid=true;
 248                      while(($file=readdir($dir))!==false)
 249                      {
 250                          if($file==='.' || $file==='..')
 251                              continue;
 252                          else if(basename($file,'.css')!==$file)
 253                              $this->_cssFiles[]=$themeUrl.'/'.$file;
 254                          else if(basename($file,'.js')!==$file)
 255                              $this->_jsFiles[]=$themeUrl.'/'.$file;
 256                          else if(basename($file,self::SKIN_FILE_EXT)!==$file && filemtime($themePath.'/'.$file)>$timestamp)
 257                          {
 258                              $cacheValid=false;
 259                              break;
 260                          }
 261                      }
 262                      closedir($dir);
 263                      if($cacheValid)
 264                          $this->_skins=$skins;
 265                  }
 266                  else
 267                  {
 268                      $cacheValid=true;
 269                      $this->_cssFiles=$cssFiles;
 270                      $this->_jsFiles=$jsFiles;
 271                      $this->_skins=$skins;
 272                  }
 273              }
 274          }
 275          if(!$cacheValid)
 276          {
 277              $this->_cssFiles=array();
 278              $this->_jsFiles=array();
 279              $this->_skins=array();
 280              if(($dir=opendir($themePath))===false)
 281                  throw new TIOException('theme_path_inexistent',$themePath);
 282              while(($file=readdir($dir))!==false)
 283              {
 284                  if($file==='.' || $file==='..')
 285                      continue;
 286                  else if(basename($file,'.css')!==$file)
 287                      $this->_cssFiles[]=$themeUrl.'/'.$file;
 288                  else if(basename($file,'.js')!==$file)
 289                      $this->_jsFiles[]=$themeUrl.'/'.$file;
 290                  else if(basename($file,self::SKIN_FILE_EXT)!==$file)
 291                  {
 292                      $template=new TTemplate(file_get_contents($themePath.'/'.$file),$themePath,$themePath.'/'.$file);
 293                      foreach($template->getItems() as $skin)
 294                      {
 295                          if(!isset($skin[2]))  // a text string, ignored
 296                              continue;
 297                          else if($skin[0]!==-1)
 298                              throw new TConfigurationException('theme_control_nested',$skin[1],dirname($themePath));
 299                          $type=$skin[1];
 300                          $id=isset($skin[2]['skinid'])?$skin[2]['skinid']:0;
 301                          unset($skin[2]['skinid']);
 302                          if(isset($this->_skins[$type][$id]))
 303                              throw new TConfigurationException('theme_skinid_duplicated',$type,$id,dirname($themePath));
 304                          /*
 305                          foreach($skin[2] as $name=>$value)
 306                          {
 307                              if(is_array($value) && ($value[0]===TTemplate::CONFIG_DATABIND || $value[0]===TTemplate::CONFIG_PARAMETER))
 308                                  throw new TConfigurationException('theme_databind_forbidden',dirname($themePath),$type,$id);
 309                          }
 310                          */
 311                          $this->_skins[$type][$id]=$skin[2];
 312                      }
 313                  }
 314              }
 315              closedir($dir);
 316              sort($this->_cssFiles);
 317              sort($this->_jsFiles);
 318              if($cache!==null)
 319                  $cache->set(self::THEME_CACHE_PREFIX.$themePath,array($this->_skins,$this->_cssFiles,$this->_jsFiles,time()));
 320          }
 321      }
 322  
 323      /**
 324       * @return string theme name
 325       */
 326  	public function getName()
 327      {
 328          return $this->_name;
 329      }
 330  
 331      /**
 332       * @return string the URL to the theme folder (without ending slash)
 333       */
 334  	public function getBaseUrl()
 335      {
 336          return $this->_themeUrl;
 337      }
 338  
 339      /**
 340       * @return string the file path to the theme folder
 341       */
 342  	public function getBasePath()
 343      {
 344          return $this->_themePath;
 345      }
 346  
 347      /**
 348       * Applies the theme to a particular control.
 349       * The control's class name and SkinID value will be used to
 350       * identify which skin to be applied. If the control's SkinID is empty,
 351       * the default skin will be applied.
 352       * @param TControl the control to be applied with a skin
 353       * @return boolean if a skin is successfully applied
 354       * @throws TConfigurationException if any error happened during the skin application
 355       */
 356  	public function applySkin($control)
 357      {
 358          $type=get_class($control);
 359          if(($id=$control->getSkinID())==='')
 360              $id=0;
 361          if(isset($this->_skins[$type][$id]))
 362          {
 363              foreach($this->_skins[$type][$id] as $name=>$value)
 364              {
 365                  Prado::trace("Applying skin $name to $type",'System.Web.UI.TThemeManager');
 366                  if(is_array($value))
 367                  {
 368                      switch($value[0])
 369                      {
 370                          case TTemplate::CONFIG_EXPRESSION:
 371                              $value=$this->evaluateExpression($value[1]);
 372                              break;
 373                          case TTemplate::CONFIG_ASSET:
 374                              $value=$this->_themeUrl.'/'.ltrim($value[1],'/');
 375                              break;
 376                          case TTemplate::CONFIG_DATABIND:
 377                              $control->bindProperty($name,$value[1]);
 378                              break;
 379                          case TTemplate::CONFIG_PARAMETER:
 380                              $control->setSubProperty($name,$this->getApplication()->getParameters()->itemAt($value[1]));
 381                              break;
 382                          case TTemplate::CONFIG_TEMPLATE:
 383                              $control->setSubProperty($name,$value[1]);
 384                              break;
 385                          case TTemplate::CONFIG_LOCALIZATION:
 386                              $control->setSubProperty($name,Prado::localize($value[1]));
 387                              break;
 388                          default:
 389                              throw new TConfigurationException('theme_tag_unexpected',$name,$value[0]);
 390                              break;
 391                      }
 392                  }
 393                  if(!is_array($value))
 394                  {
 395                      if(strpos($name,'.')===false)    // is simple property or custom attribute
 396                      {
 397                          if($control->hasProperty($name))
 398                          {
 399                              if($control->canSetProperty($name))
 400                              {
 401                                  $setter='set'.$name;
 402                                  $control->$setter($value);
 403                              }
 404                              else
 405                                  throw new TConfigurationException('theme_property_readonly',$type,$name);
 406                          }
 407                          else
 408                              throw new TConfigurationException('theme_property_undefined',$type,$name);
 409                      }
 410                      else    // complex property
 411                          $control->setSubProperty($name,$value);
 412                  }
 413              }
 414              return true;
 415          }
 416          else
 417              return false;
 418      }
 419  
 420      /**
 421       * @return array list of CSS files (URL) in the theme
 422       */
 423  	public function getStyleSheetFiles()
 424      {
 425          return $this->_cssFiles;
 426      }
 427  
 428      /**
 429       * @return array list of Javascript files (URL) in the theme
 430       */
 431  	public function getJavaScriptFiles()
 432      {
 433          return $this->_jsFiles;
 434      }
 435  }
 436  
 437  ?>


Généré le : Sun Feb 25 21:07:04 2007 par Balluche grâce à PHPXref 0.7