forked from IBM-Cloud/get-started-php
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSagFileCache.php
More file actions
150 lines (119 loc) · 3.97 KB
/
SagFileCache.php
File metadata and controls
150 lines (119 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
require_once('SagCache.php');
require_once('SagException.php');
/**
* Cache to the local hard disk. Uses /tmp by default, but you can specify
* another location.
*
* Cache keys are used for file names and the contents are JSON. System file
* sizes are used to calculate the cache's current size.
*
* Every operation goes to the disk, so this cache will not be ideal for high
* I/O operations.
*
* @package Cache
* @version 0.9.0
*/
class SagFileCache extends SagCache {
private static $fileExt = ".sag";
private $fsLocation;
/**
* @param string $location The file system path to the directory that should
* be used to store the cache files. The local system's temp directory is
* used by default.
* @return SagFileCache
*/
public function __construct($location) {
if(!is_dir($location)) {
throw new SagException("The provided cache location is not a directory.");
}
if(!is_readable($location) || !is_writable($location)) {
throw new SagException("Insufficient privileges to the supplied cache directory.");
}
parent::__construct();
$this->fsLocation = rtrim($location, "/ \t\n\r\0\x0B");
/*
* Just update - don't freak out if the size isn't right, as the user might
* update it to non-default, they might not do anything with the cache,
* they might clean it themselves, etc. give them time. We'll freak when we
* add.
*/
foreach(glob($this->fsLocation."/*".self::$fileExt) as $file) {
self::addToSize(filesize($file));
}
}
/**
* Generates the full filename/path that would be used for a given URL's
* cache object.
*
* @param string $url The URL for the cached item.
* @return string
*/
public function makeFilename($url) {
return "$this->fsLocation/".self::makeKey($url).self::$fileExt;
}
public function set($url, &$item) {
if(empty($url)) {
throw new SagException('You need to provide a URL to cache.');
}
if(!parent::mayCache($item)) {
return false;
}
$serialized = json_encode($item);
$target = self::makeFilename($url);
// If it already exists, then remove the old version but keep a copy
if(is_file($target)) {
$oldCopy = self::get($url);
self::remove($url);
}
$fh = fopen($target, "w"); //in case self::remove() didn't get it?
fwrite($fh, $serialized, strlen($serialized)); //don't throw up if we fail - we're not mission critical
self::addToSize(filesize($target));
fclose($fh);
// Only return the $oldCopy if it exists
return (isset($oldCopy) && is_object($oldCopy)) ? $oldCopy : true;
}
public function get($url) {
$target = self::makeFilename($url);
if(!is_file($target)) {
return null;
}
if(!is_readable($target)) {
throw new SagException("Could not read the cache file for $url at $target - please check its permissions.");
}
return json_decode(file_get_contents($target));
}
public function remove($url) {
$target = $this->makeFilename($url);
return self::removeFile($target);
}
public function clear() {
$part = false;
foreach(glob($this->fsLocation."/*".self::$fileExt) as $file) {
if(!self::removeFile($file)) {
$part = true;
}
}
return !$part;
}
private function removeFile($path) {
$size = filesize($path);
if(!unlink($path)) {
return false;
}
self::addToSize(-$size);
return true;
}
}
?>