1<?php 2 3namespace Mpdf; 4 5use DirectoryIterator; 6 7class Cache 8{ 9 10 private $basePath; 11 12 private $cleanupInterval; 13 14 public function __construct($basePath, $cleanupInterval = 3600) 15 { 16 if (!is_int($cleanupInterval) && false !== $cleanupInterval) { 17 throw new \Mpdf\MpdfException('Cache cleanup interval has to be an integer or false'); 18 } 19 20 if (!$this->createBasePath($basePath)) { 21 throw new \Mpdf\MpdfException(sprintf('Temporary files directory "%s" is not writable', $basePath)); 22 } 23 24 $this->basePath = $basePath; 25 $this->cleanupInterval = $cleanupInterval; 26 } 27 28 protected function createBasePath($basePath) 29 { 30 if (!file_exists($basePath)) { 31 if (!$this->createBasePath(dirname($basePath))) { 32 return false; 33 } 34 35 if (!$this->createDirectory($basePath)) { 36 return false; 37 } 38 } 39 40 if (!is_writable($basePath) || !is_dir($basePath)) { 41 return false; 42 } 43 44 return true; 45 } 46 47 protected function createDirectory($basePath) 48 { 49 if (!mkdir($basePath)) { 50 return false; 51 } 52 53 if (!chmod($basePath, 0777)) { 54 return false; 55 } 56 57 return true; 58 } 59 60 public function tempFilename($filename) 61 { 62 return $this->getFilePath($filename); 63 } 64 65 public function has($filename) 66 { 67 return file_exists($this->getFilePath($filename)); 68 } 69 70 public function load($filename) 71 { 72 return file_get_contents($this->getFilePath($filename)); 73 } 74 75 public function write($filename, $data) 76 { 77 $tempFile = tempnam($this->basePath, 'cache_tmp_'); 78 file_put_contents($tempFile, $data); 79 chmod($tempFile, 0664); 80 81 $path = $this->getFilePath($filename); 82 rename($tempFile, $path); 83 84 return $path; 85 } 86 87 public function remove($filename) 88 { 89 return unlink($this->getFilePath($filename)); 90 } 91 92 public function clearOld() 93 { 94 $iterator = new DirectoryIterator($this->basePath); 95 96 /** @var \DirectoryIterator $item */ 97 foreach ($iterator as $item) { 98 if (!$item->isDot() 99 && $item->isFile() 100 && !$this->isDotFile($item) 101 && $this->isOld($item)) { 102 unlink($item->getPathname()); 103 } 104 } 105 } 106 107 private function getFilePath($filename) 108 { 109 return $this->basePath . '/' . $filename; 110 } 111 112 private function isOld(DirectoryIterator $item) 113 { 114 return $this->cleanupInterval 115 ? $item->getMTime() + $this->cleanupInterval < time() 116 : false; 117 } 118 119 public function isDotFile(DirectoryIterator $item) 120 { 121 return substr($item->getFilename(), 0, 1) === '.'; 122 } 123} 124