[ Index ] |
|
Code source de PRADO 3.0.6 |
1 <?php 2 /** 3 * TAssetManager class 4 * 5 * @author Qiang Xue <qiang.xue@gmail.com> 6 * @link http://www.pradosoft.com/ 7 * @copyright Copyright © 2005 PradoSoft 8 * @license http://www.pradosoft.com/license/ 9 * @version $Id: TAssetManager.php 1546 2006-12-03 22:44:38Z wei $ 10 * @package System.Web 11 */ 12 13 /** 14 * TAssetManager class 15 * 16 * TAssetManager provides a scheme to allow web clients visiting 17 * private files that are normally web-inaccessible. 18 * 19 * TAssetManager will copy the file to be published into a web-accessible 20 * directory. The default base directory for storing the file is "assets", which 21 * should be under the application directory. This can be changed by setting 22 * the {@link setBasePath BasePath} property together with the 23 * {@link setBaseUrl BaseUrl} property that refers to the URL for accessing the base path. 24 * 25 * By default, TAssetManager will not publish a file or directory if it already 26 * exists in the publishing directory and has an older modification time. 27 * If the application mode is set as 'Performance', the modification time check 28 * will be skipped. You can explicitly require a modification time check 29 * with the function {@link publishFilePath}. This is usually 30 * very useful during development. 31 * 32 * TAssetManager may be configured in application configuration file as follows, 33 * <code> 34 * <module id="asset" BasePath="Application.assets" BaseUrl="/assets" /> 35 * </code> 36 * where {@link getBasePath BasePath} and {@link getBaseUrl BaseUrl} are 37 * configurable properties of TAssetManager. Make sure that BasePath is a namespace 38 * pointing to a valid directory writable by the Web server process. 39 * 40 * @author Qiang Xue <qiang.xue@gmail.com> 41 * @version $Id: TAssetManager.php 1546 2006-12-03 22:44:38Z wei $ 42 * @package System.Web 43 * @since 3.0 44 */ 45 class TAssetManager extends TModule 46 { 47 /** 48 * Default web accessible base path for storing private files 49 */ 50 const DEFAULT_BASEPATH='assets'; 51 /** 52 * @var string base web accessible path for storing private files 53 */ 54 private $_basePath=null; 55 /** 56 * @var string base URL for accessing the publishing directory. 57 */ 58 private $_baseUrl=null; 59 /** 60 * @var boolean whether to use timestamp checking to ensure files are published with up-to-date versions. 61 */ 62 private $_checkTimestamp=false; 63 /** 64 * @var TApplication application instance 65 */ 66 private $_application; 67 /** 68 * @var array published assets 69 */ 70 private $_published=array(); 71 /** 72 * @var boolean whether the module is initialized 73 */ 74 private $_initialized=false; 75 76 /** 77 * Initializes the module. 78 * This method is required by IModule and is invoked by application. 79 * @param TXmlElement module configuration 80 */ 81 public function init($config) 82 { 83 $application=$this->getApplication(); 84 if($this->_basePath===null) 85 $this->_basePath=dirname($application->getRequest()->getApplicationFilePath()).'/'.self::DEFAULT_BASEPATH; 86 if(!is_writable($this->_basePath) || !is_dir($this->_basePath)) 87 throw new TConfigurationException('assetmanager_basepath_invalid',$this->_basePath); 88 if($this->_baseUrl===null) 89 $this->_baseUrl=rtrim(dirname($application->getRequest()->getApplicationUrl()),'/\\').'/'.self::DEFAULT_BASEPATH; 90 $application->setAssetManager($this); 91 $this->_initialized=true; 92 } 93 94 /** 95 * @return string the root directory storing published asset files 96 */ 97 public function getBasePath() 98 { 99 return $this->_basePath; 100 } 101 102 /** 103 * Sets the root directory storing published asset files. 104 * The directory must be in namespace format. 105 * @param string the root directory storing published asset files 106 * @throws TInvalidOperationException if the module is initialized already 107 */ 108 public function setBasePath($value) 109 { 110 if($this->_initialized) 111 throw new TInvalidOperationException('assetmanager_basepath_unchangeable'); 112 else 113 { 114 $this->_basePath=Prado::getPathOfNamespace($value); 115 if($this->_basePath===null || !is_dir($this->_basePath) || !is_writable($this->_basePath)) 116 throw new TInvalidDataValueException('assetmanage_basepath_invalid',$value); 117 } 118 } 119 120 /** 121 * @return string the base url that the published asset files can be accessed 122 */ 123 public function getBaseUrl() 124 { 125 return $this->_baseUrl; 126 } 127 128 /** 129 * @param string the base url that the published asset files can be accessed 130 * @throws TInvalidOperationException if the module is initialized already 131 */ 132 public function setBaseUrl($value) 133 { 134 if($this->_initialized) 135 throw new TInvalidOperationException('assetmanager_baseurl_unchangeable'); 136 else 137 $this->_baseUrl=rtrim($value,'/'); 138 } 139 140 /** 141 * Publishes a file or a directory (recursively). 142 * This method will copy the content in a directory (recursively) to 143 * a web accessible directory and returns the URL for the directory. 144 * If the application is not in performance mode, the file modification 145 * time will be used to make sure the published file is latest or not. 146 * If not, a file copy will be performed. 147 * @param string the path to be published 148 * @param boolean If true, file modification time will be checked even if the application 149 * is in performance mode. 150 * @return string an absolute URL to the published directory 151 * @throws TInvalidDataValueException if the file path to be published is 152 * invalid 153 */ 154 public function publishFilePath($path,$checkTimestamp=false) 155 { 156 if(isset($this->_published[$path])) 157 return $this->_published[$path]; 158 else if(empty($path) || ($fullpath=realpath($path))===false) 159 throw new TInvalidDataValueException('assetmanager_filepath_invalid',$path); 160 else if(is_file($fullpath)) 161 { 162 $dir=$this->hash(dirname($fullpath)); 163 $fileName=basename($fullpath); 164 $dst=$this->_basePath.'/'.$dir; 165 if(!is_file($dst.'/'.$fileName) || $checkTimestamp || $this->getApplication()->getMode()!==TApplicationMode::Performance) 166 $this->copyFile($fullpath,$dst); 167 return $this->_published[$path]=$this->_baseUrl.'/'.$dir.'/'.$fileName; 168 } 169 else 170 { 171 $dir=$this->hash($fullpath); 172 if(!is_dir($this->_basePath.'/'.$dir) || $checkTimestamp || $this->getApplication()->getMode()!==TApplicationMode::Performance) 173 { 174 Prado::trace("Publishing directory $fullpath",'System.Web.UI.TAssetManager'); 175 $this->copyDirectory($fullpath,$this->_basePath.'/'.$dir); 176 } 177 return $this->_published[$path]=$this->_baseUrl.'/'.$dir; 178 } 179 } 180 181 /** 182 * Returns the published path of a file path. 183 * This method does not perform any publishing. It merely tells you 184 * if the file path is published, where it will go. 185 * @param string directory or file path being published 186 * @return string the published file path 187 */ 188 public function getPublishedPath($path) 189 { 190 $path=realpath($path); 191 if(is_file($path)) 192 return $this->_basePath.'/'.$this->hash(dirname($path)).'/'.basename($path); 193 else 194 return $this->_basePath.'/'.$this->hash($path); 195 } 196 197 /** 198 * Returns the URL of a published file path. 199 * This method does not perform any publishing. It merely tells you 200 * if the file path is published, what the URL will be to access it. 201 * @param string directory or file path being published 202 * @return string the published URL for the file path 203 */ 204 public function getPublishedUrl($path) 205 { 206 $path=realpath($path); 207 if(is_file($path)) 208 return $this->_baseUrl.'/'.$this->hash(dirname($path)).'/'.basename($path); 209 else 210 return $this->_baseUrl.'/'.$this->hash($path); 211 } 212 213 /** 214 * Generate a CRC32 hash for the directory path. Collisions are higher 215 * than MD5 but generates a much smaller hash string. 216 * @param string string to be hashed. 217 * @return string hashed string. 218 */ 219 protected function hash($dir) 220 { 221 return sprintf('%x',crc32($dir)); 222 } 223 224 /** 225 * Copies a file to a directory. 226 * Copying is done only when the destination file does not exist 227 * or has an older file modification time. 228 * @param string source file path 229 * @param string destination directory (if not exists, it will be created) 230 */ 231 protected function copyFile($src,$dst) 232 { 233 if(!is_dir($dst)) 234 { 235 @mkdir($dst); 236 @chmod($dst, 0777); 237 } 238 $dstFile=$dst.'/'.basename($src); 239 if(@filemtime($dstFile)<@filemtime($src)) 240 { 241 Prado::trace("Publishing file $src to $dstFile",'System.Web.TAssetManager'); 242 @copy($src,$dstFile); 243 } 244 } 245 246 /** 247 * Copies a directory recursively as another. 248 * If the destination directory does not exist, it will be created. 249 * File modification time is used to ensure the copied files are latest. 250 * @param string the source directory 251 * @param string the destination directory 252 * @todo a generic solution to ignore certain directories and files 253 */ 254 public function copyDirectory($src,$dst) 255 { 256 if(!is_dir($dst)) 257 { 258 @mkdir($dst); 259 @chmod($dst, 0777); 260 } 261 $folder=@opendir($src); 262 while($file=@readdir($folder)) 263 { 264 if($file==='.' || $file==='..' || $file==='.svn') 265 continue; 266 else if(is_file($src.'/'.$file)) 267 { 268 if(@filemtime($dst.'/'.$file)<@filemtime($src.'/'.$file)) 269 @copy($src.'/'.$file,$dst.'/'.$file); 270 } 271 else 272 $this->copyDirectory($src.'/'.$file,$dst.'/'.$file); 273 } 274 closedir($folder); 275 } 276 277 /** 278 * Publish a tar file by extracting its contents to the assets directory. 279 * Each tar file must be accomplished with its own MD5 check sum file. 280 * The MD5 file is published when the tar contents are successfully 281 * extracted to the assets directory. The presence of the MD5 file 282 * as published asset assumes that the tar file has already been extracted. 283 * @param string tar filename 284 * @param string MD5 checksum for the corresponding tar file. 285 * @return string URL path to the directory where the tar file was extracted. 286 */ 287 public function publishTarFile($tarfile, $md5sum, $checkTimestamp=false) 288 { 289 if(isset($this->_published[$md5sum])) 290 return $this->_published[$md5sum]; 291 else if(($fullpath=realpath($md5sum))===false) 292 throw new TInvalidDataValueException('assetmanager_tarchecksum_invalid',$md5sum); 293 else 294 { 295 $dir=$this->hash(dirname($fullpath)); 296 $fileName=basename($fullpath); 297 $dst=$this->_basePath.'/'.$dir; 298 if(!is_file($dst.'/'.$fileName) || $checkTimestamp || $this->getApplication()->getMode()!==TApplicationMode::Performance) 299 { 300 if(@filemtime($dst.'/'.$fileName)<@filemtime($fullpath)) 301 { 302 $this->copyFile($fullpath,$dst); 303 $this->deployTarFile($tarfile,$dst); 304 } 305 } 306 return $this->_published[$md5sum]=$this->_baseUrl.'/'.$dir; 307 } 308 } 309 310 /** 311 * Extracts the tar file to the destination directory. 312 * N.B Tar file must not be compressed. 313 * @param string tar file 314 * @param string path where the contents of tar file are to be extracted 315 * @return boolean true if extract successful, false otherwise. 316 */ 317 protected function deployTarFile($path,$destination) 318 { 319 if(($fullpath=realpath($path))===false) 320 throw new TIOException('assetmanager_tarfile_invalid',$path); 321 else 322 { 323 Prado::using('System.IO.TTarFileExtractor'); 324 $tar = new TTarFileExtractor($fullpath); 325 return $tar->extract($destination); 326 } 327 } 328 329 } 330 331 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |