add current dev version (WIP)
[GitHub/Stricted/Domain-Control-Panel.git] / lib / system / cache / source / DiskCacheSource.class.php
1 <?php
2 namespace dns\system\cache\source;
3
4 /**
5 * DiskCacheSource is an implementation of CacheSource that stores the cache as simple files in the file system.
6 *
7 * @author Alexander Ebert, Marcel Werk
8 * @copyright 2001-2014 WoltLab GmbH
9 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
10 * @package com.woltlab.wcf
11 * @subpackage system.cache.source
12 * @category Community Framework
13 */
14 class DiskCacheSource implements ICacheSource {
15 /**
16 * @see \dns\system\cache\source\ICacheSource::flush()
17 */
18 public function flush($cacheName, $useWildcard) {
19 if ($useWildcard) {
20 $this->removeFiles('cache.'.$cacheName.'*.php');
21 }
22 else {
23 $this->removeFiles('cache.'.$cacheName.'.php');
24 }
25 }
26
27 /**
28 * @see \dns\system\cache\source\ICacheSource::flushAll()
29 */
30 public function flushAll() {
31 $this->removeFiles('cache.*.php');
32 }
33
34 /**
35 * @see \dns\system\cache\source\ICacheSource::get()
36 */
37 public function get($cacheName, $maxLifetime) {
38 $filename = $this->getFilename($cacheName);
39 if ($this->needRebuild($filename, $maxLifetime)) {
40 return null;
41 }
42
43 // load cache
44 try {
45 return $this->readCache($cacheName, $filename);
46 }
47 catch (\Exception $e) {
48 return null;
49 }
50 }
51
52 /**
53 * @see \dns\system\cache\source\ICacheSource::set()
54 */
55 public function set($cacheName, $value, $maxLifetime) {
56 $filename = $this->getFilename($cacheName);
57 $content = "<?php exit; /* cache: ".$cacheName." (generated at ".gmdate('r').") DO NOT EDIT THIS FILE */ ?>\n";
58 $content .= serialize($value);
59
60 if (!file_exists($filename)) {
61 @touch($filename);
62 }
63
64 $handler = fOpen($filename, "a+");
65 fWrite($handler, $content);
66 fClose($handler);
67 }
68
69 /**
70 * Returns cache filename.
71 *
72 * @param string $cacheName
73 * @return string
74 */
75 protected function getFilename($cacheName) {
76 return DNS_DIR.'/cache/cache.'.$cacheName.'.php';
77 }
78
79 /**
80 * Removes files matching given pattern.
81 *
82 * @param string $pattern
83 */
84 protected function removeFiles($pattern) {
85 $directory = DNS_DIR.'cache/';
86
87 foreach (glob($directory.$pattern) as $filename) {
88 @unlink($filename);
89 }
90 }
91
92 /**
93 * Determines wheater the cache needs to be rebuild or not.
94 *
95 * @param string $filename
96 * @param integer $maxLifetime
97 * @return boolean
98 */
99 protected function needRebuild($filename, $maxLifetime) {
100 // cache does not exist
101 if (!file_exists($filename)) {
102 return true;
103 }
104
105 // cache is empty
106 if (!@filesize($filename)) {
107 return true;
108 }
109
110 // cache resource was marked as obsolete
111 if (($mtime = filemtime($filename)) <= 1) {
112 return true;
113 }
114
115 // maxlifetime expired
116 if ($maxLifetime > 0 && (time() - $mtime) > $maxLifetime) {
117 return true;
118 }
119
120 // do not rebuild cache
121 return false;
122 }
123
124 /**
125 * Loads the file of a cached resource.
126 *
127 * @param string $cacheName
128 * @param string $filename
129 * @return mixed
130 */
131 protected function readCache($cacheName, $filename) {
132 // get file contents
133 $contents = file_get_contents($filename);
134
135 // find first newline
136 $position = strpos($contents, "\n");
137 if ($position === false) {
138 throw new \Exception("Unable to load cache resource '".$cacheName."'");
139 }
140
141 // cut contents
142 $contents = substr($contents, $position + 1);
143
144 // unserialize
145 $value = @unserialize($contents);
146 if ($value === false) {
147 throw new \Exception("Unable to load cache resource '".$cacheName."'");
148 }
149
150 return $value;
151 }
152 }