From d45b5615d48bff5373a6cda0728cb26332c3d962 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Tue, 20 Jan 2015 19:19:55 +0100 Subject: One class per file: framework/Caching/ --- framework/Caching/TDirectoryCacheDependency.php | 170 ++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 framework/Caching/TDirectoryCacheDependency.php (limited to 'framework/Caching/TDirectoryCacheDependency.php') diff --git a/framework/Caching/TDirectoryCacheDependency.php b/framework/Caching/TDirectoryCacheDependency.php new file mode 100644 index 00000000..66f7393d --- /dev/null +++ b/framework/Caching/TDirectoryCacheDependency.php @@ -0,0 +1,170 @@ + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Caching + */ + +/** + * TDirectoryCacheDependency class. + * + * TDirectoryCacheDependency performs dependency checking based on the + * modification time of the files contained in the specified directory. + * The directory being checked is specified via {@link setDirectory Directory}. + * + * By default, all files under the specified directory and subdirectories + * will be checked. If the last modification time of any of them is changed + * or if different number of files are contained in a directory, the dependency + * is reported as changed. By specifying {@link setRecursiveCheck RecursiveCheck} + * and {@link setRecursiveLevel RecursiveLevel}, one can limit the checking + * to a certain depth of the subdirectories. + * + * @author Qiang Xue + * @package System.Caching + * @since 3.1.0 + */ +class TDirectoryCacheDependency extends TCacheDependency +{ + private $_recursiveCheck=true; + private $_recursiveLevel=-1; + private $_timestamps; + private $_directory; + + /** + * Constructor. + * @param string the directory to be checked + */ + public function __construct($directory) + { + $this->setDirectory($directory); + } + + /** + * @return string the directory to be checked + */ + public function getDirectory() + { + return $this->_directory; + } + + /** + * @param string the directory to be checked + * @throws TInvalidDataValueException if the directory does not exist + */ + public function setDirectory($directory) + { + if(($path=realpath($directory))===false || !is_dir($path)) + throw new TInvalidDataValueException('directorycachedependency_directory_invalid',$directory); + $this->_directory=$path; + $this->_timestamps=$this->generateTimestamps($path); + } + + /** + * @return boolean whether the subdirectories of the directory will also be checked. + * It defaults to true. + */ + public function getRecursiveCheck() + { + return $this->_recursiveCheck; + } + + /** + * @param boolean whether the subdirectories of the directory will also be checked. + */ + public function setRecursiveCheck($value) + { + $this->_recursiveCheck=TPropertyValue::ensureBoolean($value); + } + + /** + * @return int the depth of the subdirectories to be checked. + * It defaults to -1, meaning unlimited depth. + */ + public function getRecursiveLevel() + { + return $this->_recursiveLevel; + } + + /** + * Sets a value indicating the depth of the subdirectories to be checked. + * This is meaningful only when {@link getRecursiveCheck RecursiveCheck} + * is true. + * @param int the depth of the subdirectories to be checked. + * If the value is less than 0, it means unlimited depth. + * If the value is 0, it means checking the files directly under the specified directory. + */ + public function setRecursiveLevel($value) + { + $this->_recursiveLevel=TPropertyValue::ensureInteger($value); + } + + /** + * Performs the actual dependency checking. + * This method returns true if the directory is changed. + * @return boolean whether the dependency is changed or not. + */ + public function getHasChanged() + { + return $this->generateTimestamps($this->_directory)!=$this->_timestamps; + } + + /** + * Checks to see if the file should be checked for dependency. + * This method is invoked when dependency of the whole directory is being checked. + * By default, it always returns true, meaning the file should be checked. + * You may override this method to check only certain files. + * @param string the name of the file that may be checked for dependency. + * @return boolean whether this file should be checked. + */ + protected function validateFile($fileName) + { + return true; + } + + /** + * Checks to see if the specified subdirectory should be checked for dependency. + * This method is invoked when dependency of the whole directory is being checked. + * By default, it always returns true, meaning the subdirectory should be checked. + * You may override this method to check only certain subdirectories. + * @param string the name of the subdirectory that may be checked for dependency. + * @return boolean whether this subdirectory should be checked. + */ + protected function validateDirectory($directory) + { + return true; + } + + /** + * Determines the last modification time for files under the directory. + * This method may go recursively into subdirectories if + * {@link setRecursiveCheck RecursiveCheck} is set true. + * @param string the directory name + * @param int level of the recursion + * @return array list of file modification time indexed by the file path + */ + protected function generateTimestamps($directory,$level=0) + { + if(($dir=opendir($directory))===false) + throw new TIOException('directorycachedependency_directory_invalid',$directory); + $timestamps=array(); + while(($file=readdir($dir))!==false) + { + $path=$directory.DIRECTORY_SEPARATOR.$file; + if($file==='.' || $file==='..') + continue; + else if(is_dir($path)) + { + if(($this->_recursiveLevel<0 || $level<$this->_recursiveLevel) && $this->validateDirectory($path)) + $timestamps=array_merge($this->generateTimestamps($path,$level+1)); + } + else if($this->validateFile($path)) + $timestamps[$path]=filemtime($path); + } + closedir($dir); + return $timestamps; + } +} \ No newline at end of file -- cgit v1.2.3