132 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace Nextend\Framework\Cache;
 | |
| 
 | |
| use DateTime;
 | |
| 
 | |
| class CacheImage extends AbstractCache {
 | |
| 
 | |
|     protected $_storageEngine = 'filesystem';
 | |
| 
 | |
|     protected $lazy = false;
 | |
| 
 | |
|     public function __construct($group) {
 | |
|         parent::__construct($group, true);
 | |
|     }
 | |
| 
 | |
|     protected function getScope() {
 | |
|         return 'image';
 | |
|     }
 | |
| 
 | |
|     public function setLazy($lazy) {
 | |
|         $this->lazy = $lazy;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @param          $fileExtension
 | |
|      * @param callable $callable
 | |
|      * @param array    $parameters
 | |
|      * @param bool     $hash
 | |
|      *
 | |
|      * @return mixed
 | |
|      */
 | |
|     public function makeCache($fileExtension, $callable, $parameters = array(), $hash = false) {
 | |
| 
 | |
|         if (!$hash) {
 | |
|             $hash = $this->generateHash($fileExtension, $callable, $parameters);
 | |
|         }
 | |
| 
 | |
|         if (strpos($parameters[1], '?') !== false) {
 | |
|             $fileNameParts = explode('?', $parameters[1]);
 | |
|             $keepFileName  = pathinfo($fileNameParts[0], PATHINFO_FILENAME);
 | |
|         } else {
 | |
|             $keepFileName = pathinfo($parameters[1], PATHINFO_FILENAME);
 | |
|         }
 | |
| 
 | |
|         $fileName              = $hash . (!empty($keepFileName) ? '/' . $keepFileName : '');
 | |
|         $fileNameWithExtension = $fileName . '.' . $fileExtension;
 | |
| 
 | |
|         $isCached = $this->exists($fileNameWithExtension);
 | |
|         if ($isCached) {
 | |
|             if (!$this->testManifestFile($fileName, $parameters[1])) {
 | |
|                 $isCached = false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!$isCached) {
 | |
|             if ($this->lazy) {
 | |
|                 return $parameters[1];
 | |
|             }
 | |
| 
 | |
|             array_unshift($parameters, $this->getPath($fileNameWithExtension));
 | |
|             call_user_func_array($callable, $parameters);
 | |
| 
 | |
|             $this->createManifestFile($fileName, $parameters[2]);
 | |
|         }
 | |
| 
 | |
|         return $this->getPath($fileNameWithExtension);
 | |
|     }
 | |
| 
 | |
|     private function generateHash($fileExtension, $callable, $parameters) {
 | |
|         return md5(json_encode(array(
 | |
|             $fileExtension,
 | |
|             $callable,
 | |
|             $parameters
 | |
|         )));
 | |
|     }
 | |
| 
 | |
|     protected function testManifestFile($fileName, $originalFile) {
 | |
|         $manifestKey = $this->getManifestKey($fileName);
 | |
|         if ($this->exists($manifestKey)) {
 | |
| 
 | |
|             $manifestData = json_decode($this->get($manifestKey), true);
 | |
| 
 | |
|             $newManifestData = $this->getManifestData($originalFile);
 | |
|             if ($manifestData['mtime'] == $newManifestData['mtime']) {
 | |
|                 return true;
 | |
|             }
 | |
|         } else {
 | |
|             // Backward compatibility
 | |
|             $this->createManifestFile($fileName, $originalFile);
 | |
| 
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     protected function createManifestFile($fileName, $originalFile) {
 | |
| 
 | |
|         $this->set($this->getManifestKey($fileName), json_encode($this->getManifestData($originalFile)));
 | |
|     }
 | |
| 
 | |
|     private function getManifestData($originalFile) {
 | |
|         $manifestData = array();
 | |
|         if (strpos($originalFile, '//') !== false) {
 | |
|             $manifestData['mtime'] = $this->getRemoteMTime($originalFile);
 | |
|         } else {
 | |
|             $manifestData['mtime'] = filemtime($originalFile);
 | |
|         }
 | |
| 
 | |
|         return $manifestData;
 | |
|     }
 | |
| 
 | |
|     private function getRemoteMTime($url) {
 | |
|         if (ini_get('allow_url_fopen')) {
 | |
|             $h = get_headers($url, 1);
 | |
|             if (!$h || strpos($h[0], '200') !== false) {
 | |
|                 foreach ($h as $k => $v) {
 | |
|                     if (strtolower(trim($k)) == "last-modified") {
 | |
|                         return (new DateTime($v))->getTimestamp();
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     protected function getManifestKey($fileName) {
 | |
|         return $fileName . '.manifest';
 | |
|     }
 | |
| } |