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