| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 | 
							- <?php
 
- namespace Gregwar\Cache;
 
- /**
 
-  * A cache system based on files
 
-  *
 
-  * @author Gregwar <g.passault@gmail.com>
 
-  */
 
- class Cache implements CacheInterface
 
- {
 
-     /**
 
-      * Cache directory
 
-      */
 
-     protected $cacheDirectory;
 
-     /**
 
-      * Use a different directory as actual cache
 
-      * @var string
 
-      */
 
-     protected $actualCacheDirectory = null;
 
-     /**
 
-      * Prefix directories size
 
-      *
 
-      * For instance, if the file is helloworld.txt and the prefix size is
 
-      * 5, the cache file will be: h/e/l/l/o/helloworld.txt
 
-      *
 
-      * This is useful to avoid reaching a too large number of files into the
 
-      * cache system directories
 
-      * @var int
 
-      */
 
-     protected $prefixSize = 5;
 
-     /**
 
-      * Directory mode
 
-      *
 
-      * Allows setting of the access mode for the directories created.
 
-      * @var int
 
-      */
 
-     protected $directoryMode = 0755;
 
-     /**
 
-      * Constructs the cache system
 
-      *
 
-      * @param string $cacheDirectory the cache directory
 
-      */
 
-     public function __construct($cacheDirectory = 'cache')
 
-     {
 
-         $this->cacheDirectory = $cacheDirectory;
 
-     }
 
-     /**
 
-      * Sets the cache directory
 
-      *
 
-      * @param string $cacheDirectory the cache directory
 
-      * @return self
 
-      */
 
-     public function setCacheDirectory($cacheDirectory)
 
-     {
 
-         $this->cacheDirectory = $cacheDirectory;
 
-         return $this;
 
-     }
 
-     /**
 
-      * Gets the cache directory
 
-      *
 
-      * @return string the cache directory
 
-      */
 
-     public function getCacheDirectory()
 
-     {
 
-         return $this->cacheDirectory;
 
-     }
 
-     /**
 
-      * Sets the actual cache directory
 
-      *
 
-      * @param string $actualCacheDirectory the actual cache directory
 
-      * @return self
 
-      */
 
-     public function setActualCacheDirectory($actualCacheDirectory = null)
 
-     {
 
-         $this->actualCacheDirectory = $actualCacheDirectory;
 
-         return $this;
 
-     }
 
-     /**
 
-      * Returns the actual cache directory
 
-      */
 
-     public function getActualCacheDirectory()
 
-     {
 
-         return $this->actualCacheDirectory ?: $this->cacheDirectory;
 
-     }
 
-     /**
 
-      * Change the prefix size
 
-      *
 
-      * @param int $prefixSize the size of the prefix directories
 
-      * @return self
 
-      */
 
-     public function setPrefixSize($prefixSize)
 
-     {
 
-         $this->prefixSize = $prefixSize;
 
-         return $this;
 
-     }
 
-     /**
 
-      * Change the directory mode
 
-      *
 
-      * @param int $directoryMode the directory mode to use
 
-      * @return self
 
-      */
 
-     public function setDirectoryMode($directoryMode)
 
-     {
 
-         if (!$directoryMode) {
 
-             $directoryMode = 0755;
 
-         }
 
-         $this->directoryMode = $directoryMode;
 
-         return $this;
 
-     }
 
-     /**
 
-      * Creates a directory
 
-      *
 
-      * @param string $directory the target directory
 
-      */
 
-     protected function mkdir($directory)
 
-     {
 
-         if (!is_dir($directory)) {
 
-             @mkdir($directory, $this->directoryMode, true);
 
-         }
 
-     }
 
-     /**
 
-      * Gets the cache file name
 
-      *
 
-      * @param string $filename the name of the cache file
 
-      * @param bool $actual get the actual file or the public file
 
-      * @param bool $mkdir a boolean to enable/disable the construction of the
 
-      *        cache file directory
 
-      * @return string
 
-      */
 
-     public function getCacheFile($filename, $actual = false, $mkdir = false)
 
-     {
 
-         $path = array();
 
-         // Getting the length of the filename before the extension
 
-         $parts = explode('.', $filename);
 
-         $len = strlen($parts[0]);
 
-         for ($i=0; $i<min($len, $this->prefixSize); $i++) {
 
-             $path[] = $filename[$i];
 
-         }
 
-         $path = implode('/', $path);
 
-         if ($mkdir) {
 
-             $actualDir = $this->getActualCacheDirectory() . '/' . $path;
 
-             $this->mkdir($actualDir);
 
-         }
 
-         $path .= '/' . $filename;
 
-         if ($actual) {
 
-             return $this->getActualCacheDirectory() . '/' . $path;
 
-         } else {
 
-             return $this->getCacheDirectory() . '/' . $path;
 
-         }
 
-     }
 
-     /**
 
-      * Checks that the cache conditions are respected
 
-      *
 
-      * @param string $cacheFile the cache file
 
-      * @param array $conditions an array of conditions to check
 
-      * @return bool
 
-      * @throws \Exception
 
-      */
 
-     protected function checkConditions($cacheFile, array $conditions = array())
 
-     {
 
-         // Implicit condition: the cache file should exist
 
-         if (!file_exists($cacheFile)) {
 
-             return false;
 
-         }
 
-         foreach ($conditions as $type => $value) {
 
-             switch ($type) {
 
-             case 'maxage':
 
-             case 'max-age':
 
-                 // Return false if the file is older than $value
 
-                 $age = time() - filemtime($cacheFile);
 
-                 if ($age > $value) {
 
-                     return false;
 
-                 }
 
-                 break;
 
-             case 'younger-than':
 
-             case 'youngerthan':
 
-                 // Return false if the file is older than the file $value, or the files $value
 
-                 $check = function($filename) use ($cacheFile) {
 
-                     return !file_exists($filename) || filemtime($cacheFile) < filemtime($filename);
 
-                 };
 
-                 if (!is_array($value)) {
 
-                     if (!$this->isRemote($value) && $check($value)) {
 
-                         return false;
 
-                     }
 
-                 } else {
 
-                     foreach ($value as $file) {
 
-                         if (!$this->isRemote($file) && $check($file)) {
 
-                             return false;
 
-                         }
 
-                     }
 
-                 }
 
-                 break;
 
-             default:
 
-                 throw new \Exception('Cache condition '.$type.' not supported');
 
-             }
 
-         }
 
-         return true;
 
-     }
 
-     /**
 
-      * Checks if the target filename exists in the cache and if the conditions
 
-      * are respected
 
-      *
 
-      * @param string $filename the filename
 
-      * @param array $conditions the conditions to respect
 
-      * @return bool
 
-      */
 
-     public function exists($filename, array $conditions = array())
 
-     {
 
-         $cacheFile = $this->getCacheFile($filename, true);
 
-         return $this->checkConditions($cacheFile, $conditions);
 
-     }
 
-     /**
 
-      * Alias for exists
 
-      *
 
-      * @param string $filename the filename
 
-      * @param array $conditions the conditions to respect
 
-      * @return bool
 
-      */
 
-     public function check($filename, array $conditions = array())
 
-     {
 
-         return $this->exists($filename, $conditions);
 
-     }
 
-     /**
 
-      * Write data in the cache
 
-      *
 
-      * @param string $filename the name of the cache file
 
-      * @param string $contents the contents to store
 
-      * @return self
 
-      */
 
-     public function set($filename, $contents = '')
 
-     {
 
-         $cacheFile = $this->getCacheFile($filename, true, true);
 
-         file_put_contents($cacheFile, $contents, \LOCK_EX);
 
-         return $this;
 
-     }
 
-     /**
 
-      * Alias for set()
 
-      *
 
-      * @param string $filename the name of the cache file
 
-      * @param string $contents the contents to store
 
-      * @return self
 
-      */
 
-     public function write($filename, $contents = '')
 
-     {
 
-         return $this->set($filename, $contents);
 
-     }
 
-     /**
 
-      * Get data from the cache
 
-      *
 
-      * @param string $filename the cache file name
 
-      * @param array $conditions
 
-      * @return null|string
 
-      */
 
-     public function get($filename, array $conditions = array())
 
-     {
 
-         if ($this->exists($filename, $conditions)) {
 
-             return file_get_contents($this->getCacheFile($filename, true));
 
-         } else {
 
-             return null;
 
-         }
 
-     }
 
-     /**
 
-      * Is this URL remote?
 
-      *
 
-      * @param string $file
 
-      * @return bool
 
-      */
 
-     protected function isRemote($file)
 
-     {
 
-         if (preg_match('/^([a-z]+):\/\//', $file, $match)) {
 
-             return ($match[1] != 'file');
 
-         }
 
-         return false;
 
-     }
 
-     /**
 
-      * Get or create the cache entry
 
-      *
 
-      * @param string $filename the cache file name
 
-      * @param array $conditions an array of conditions about expiration
 
-      * @param \Closure $function the closure to call if the file does not exist
 
-      * @param bool $file returns the cache file or the file contents
 
-      * @param bool $actual returns the actual cache file
 
-      * @return string
 
-      * @throws \InvalidArgumentException
 
-      */
 
-     public function getOrCreate($filename, array $conditions = array(), $function, $file = false, $actual = false)
 
-     {
 
-         if (!is_callable($function)) {
 
-             throw new \InvalidArgumentException('The argument $function should be callable');
 
-         }
 
-         $cacheFile = $this->getCacheFile($filename, true, true);
 
-         $data = null;
 
-         if (!$this->check($filename, $conditions)) {
 
-             if(file_exists($cacheFile)) {
 
-                 unlink($cacheFile);
 
-             }
 
-             $data = call_user_func($function, $cacheFile);
 
-             // Test if the closure wrote the file or if it returned the data
 
-             if (!file_exists($cacheFile)) {
 
-                 $this->set($filename, $data);
 
-             } else {
 
-                 $data = file_get_contents($cacheFile);
 
-             }
 
-         }
 
-         return $file ? $this->getCacheFile($filename, $actual) : file_get_contents($cacheFile);
 
-     }
 
-     /**
 
-      * Alias to getOrCreate with $file = true
 
-      *
 
-      * @param string $filename the cache file name
 
-      * @param array $conditions an array of conditions about expiration
 
-      * @param \Closure $function the closure to call if the file does not exist
 
-      * @param bool $actual returns the actual cache file
 
-      * @return string
 
-      * @throws \InvalidArgumentException
 
-      */
 
-     public function getOrCreateFile($filename, array $conditions = array(), $function, $actual = false)
 
-     {
 
-         return $this->getOrCreate($filename, $conditions, $function, true, $actual);
 
-     }
 
- }
 
 
  |