1 | <?php |
||
2 | |||
3 | /** |
||
4 | * JPGraph v4.0.3 |
||
5 | */ |
||
6 | |||
7 | namespace Amenadiel\JpGraph\Image; |
||
8 | |||
9 | use Amenadiel\JpGraph\Util; |
||
10 | |||
11 | /** |
||
12 | * @class ImgStreamCache |
||
13 | * // Description: Handle caching of graphs to files. All image output goes |
||
14 | * // through this class |
||
15 | */ |
||
16 | class ImgStreamCache |
||
17 | { |
||
18 | private $cache_dir; |
||
19 | private $timeout = 0; |
||
20 | |||
21 | // Infinite timeout |
||
22 | |||
23 | /** |
||
24 | * CONSTRUCTOR. |
||
25 | * |
||
26 | * @param mixed $aCacheDir |
||
27 | */ |
||
28 | 21 | public function __construct($aCacheDir = CACHE_DIR) |
|
29 | { |
||
30 | 21 | $this->cache_dir = $aCacheDir; |
|
31 | 21 | } |
|
32 | |||
33 | /** |
||
34 | * PUBLIC METHODS. |
||
35 | * |
||
36 | * @param mixed $aTimeout |
||
37 | */ |
||
38 | // Specify a timeout (in minutes) for the file. If the file is older then the |
||
39 | // timeout value it will be overwritten with a newer version. |
||
40 | // If timeout is set to 0 this is the same as infinite large timeout and if |
||
41 | // timeout is set to -1 this is the same as infinite small timeout |
||
42 | 21 | public function SetTimeout($aTimeout) |
|
43 | { |
||
44 | 21 | $this->timeout = $aTimeout; |
|
45 | 21 | } |
|
46 | |||
47 | // Output image to browser and also write it to the cache |
||
48 | 21 | public function PutAndStream($aImage, $aCacheFileName, $aInline, $aStrokeFileName) |
|
49 | { |
||
50 | // Check if we should always stroke the image to a file |
||
51 | 21 | if (_FORCE_IMGTOFILE) { |
|
52 | $aStrokeFileName = _FORCE_IMGDIR . Util\Helper::GenImgName(); |
||
53 | } |
||
54 | |||
55 | 21 | if ($aStrokeFileName != '') { |
|
56 | if ($aStrokeFileName == 'auto') { |
||
57 | $aStrokeFileName = Util\Helper::GenImgName(); |
||
58 | } |
||
59 | |||
60 | if (file_exists($aStrokeFileName)) { |
||
61 | // Wait for lock (to make sure no readers are trying to access the image) |
||
62 | $fd = fopen($aStrokeFileName, 'w'); |
||
63 | $lock = flock($fd, LOCK_EX); |
||
0 ignored issues
–
show
Unused Code
introduced
by
![]() |
|||
64 | |||
65 | // Since the image write routines only accepts a filename which must not |
||
66 | // exist we need to delete the old file first |
||
67 | if (!@unlink($aStrokeFileName)) { |
||
68 | $lock = flock($fd, LOCK_UN); |
||
69 | Util\JpGraphError::RaiseL(25111, $aStrokeFileName); |
||
70 | //(" Can't delete cached image $aStrokeFileName. Permission problem?"); |
||
71 | } |
||
72 | $aImage->Stream($aStrokeFileName); |
||
73 | $lock = flock($fd, LOCK_UN); |
||
74 | fclose($fd); |
||
75 | } else { |
||
76 | $aImage->Stream($aStrokeFileName); |
||
77 | } |
||
78 | |||
79 | return; |
||
80 | } |
||
81 | |||
82 | 21 | if ($aCacheFileName != '' && USE_CACHE) { |
|
83 | $aCacheFileName = $this->cache_dir . $aCacheFileName; |
||
84 | if (file_exists($aCacheFileName)) { |
||
85 | if (!$aInline) { |
||
86 | // If we are generating image off-line (just writing to the cache) |
||
87 | // and the file exists and is still valid (no timeout) |
||
88 | // then do nothing, just return. |
||
89 | $diff = time() - filemtime($aCacheFileName); |
||
90 | if ($diff < 0) { |
||
91 | Util\JpGraphError::RaiseL(25112, $aCacheFileName); |
||
92 | //(" Cached imagefile ($aCacheFileName) has file date in the future!!"); |
||
93 | } |
||
94 | if ($this->timeout > 0 && ($diff <= $this->timeout * 60)) { |
||
95 | return; |
||
96 | } |
||
97 | } |
||
98 | |||
99 | // Wait for lock (to make sure no readers are trying to access the image) |
||
100 | $fd = fopen($aCacheFileName, 'w'); |
||
101 | $lock = flock($fd, LOCK_EX); |
||
102 | |||
103 | if (!@unlink($aCacheFileName)) { |
||
104 | $lock = flock($fd, LOCK_UN); |
||
105 | Util\JpGraphError::RaiseL(25113, $aStrokeFileName); |
||
106 | //(" Can't delete cached image $aStrokeFileName. Permission problem?"); |
||
107 | } |
||
108 | $aImage->Stream($aCacheFileName); |
||
109 | $lock = flock($fd, LOCK_UN); |
||
110 | fclose($fd); |
||
111 | } else { |
||
112 | $this->MakeDirs(dirname($aCacheFileName)); |
||
113 | if (!is_writeable(dirname($aCacheFileName))) { |
||
114 | Util\JpGraphError::RaiseL(25114, $aCacheFileName); |
||
115 | //('PHP has not enough permissions to write to the cache file '.$aCacheFileName.'. Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.'); |
||
116 | } |
||
117 | $aImage->Stream($aCacheFileName); |
||
118 | } |
||
119 | |||
120 | $res = true; |
||
121 | // Set group to specified |
||
122 | if (CACHE_FILE_GROUP != '') { |
||
0 ignored issues
–
show
|
|||
123 | $res = @chgrp($aCacheFileName, CACHE_FILE_GROUP); |
||
124 | } |
||
125 | if (CACHE_FILE_MOD != '') { |
||
0 ignored issues
–
show
|
|||
126 | $res = @chmod($aCacheFileName, CACHE_FILE_MOD); |
||
127 | } |
||
128 | if (!$res) { |
||
129 | Util\JpGraphError::RaiseL(25115, $aStrokeFileName); |
||
130 | //(" Can't set permission for cached image $aStrokeFileName. Permission problem?"); |
||
131 | } |
||
132 | |||
133 | $aImage->Destroy(); |
||
134 | if ($aInline) { |
||
135 | if ($fh = @fopen($aCacheFileName, 'rb')) { |
||
136 | $aImage->Headers(); |
||
137 | fpassthru($fh); |
||
138 | |||
139 | return; |
||
140 | } |
||
141 | Util\JpGraphError::RaiseL(25116, $aFile); //(" Cant open file from cache [$aFile]"); |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
142 | } |
||
143 | 21 | } elseif ($aInline) { |
|
144 | 21 | $aImage->Headers(); |
|
145 | 21 | $aImage->Stream(); |
|
146 | |||
147 | 21 | return; |
|
148 | } |
||
149 | } |
||
150 | |||
151 | public function IsValid($aCacheFileName) |
||
152 | { |
||
153 | $aCacheFileName = $this->cache_dir . $aCacheFileName; |
||
154 | if (USE_CACHE && file_exists($aCacheFileName)) { |
||
155 | $diff = time() - filemtime($aCacheFileName); |
||
156 | if ($this->timeout > 0 && ($diff > $this->timeout * 60)) { |
||
157 | return false; |
||
158 | } |
||
159 | |||
160 | return true; |
||
161 | } |
||
162 | |||
163 | return false; |
||
164 | } |
||
165 | |||
166 | public function StreamImgFile($aImage, $aCacheFileName) |
||
167 | { |
||
168 | $aCacheFileName = $this->cache_dir . $aCacheFileName; |
||
169 | if ($fh = @fopen($aCacheFileName, 'rb')) { |
||
170 | $lock = flock($fh, LOCK_SH); |
||
0 ignored issues
–
show
|
|||
171 | $aImage->Headers(); |
||
172 | fpassthru($fh); |
||
173 | $lock = flock($fh, LOCK_UN); |
||
174 | fclose($fh); |
||
175 | |||
176 | return true; |
||
177 | } |
||
178 | Util\JpGraphError::RaiseL(25117, $aCacheFileName); //(" Can't open cached image \"$aCacheFileName\" for reading."); |
||
179 | } |
||
180 | |||
181 | // Check if a given image is in cache and in that case |
||
182 | // pass it directly on to web browser. Return false if the |
||
183 | // image file doesn't exist or exists but is to old |
||
184 | public function GetAndStream($aImage, $aCacheFileName) |
||
185 | { |
||
186 | if ($this->Isvalid($aCacheFileName)) { |
||
187 | return $this->StreamImgFile($aImage, $aCacheFileName); |
||
188 | } else { |
||
189 | return false; |
||
190 | } |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * PRIVATE METHODS. |
||
195 | * |
||
196 | * @param mixed $aFile |
||
197 | */ |
||
198 | |||
199 | // Create all necessary directories in a path |
||
200 | public function MakeDirs($aFile) |
||
201 | { |
||
202 | $dirs = []; |
||
203 | // In order to better work when open_basedir is enabled |
||
204 | // we do not create directories in the root path |
||
205 | while ($aFile != '/' && !(file_exists($aFile))) { |
||
206 | $dirs[] = $aFile . '/'; |
||
207 | $aFile = dirname($aFile); |
||
208 | } |
||
209 | for ($i = safe_count($dirs) - 1; $i >= 0; --$i) { |
||
210 | if (!@mkdir($dirs[$i], 0777)) { |
||
211 | Util\JpGraphError::RaiseL(25118, $aFile); //(" Can't create directory $aFile. Make sure PHP has write permission to this directory."); |
||
212 | } |
||
213 | // We also specify mode here after we have changed group. |
||
214 | // This is necessary if Apache user doesn't belong the |
||
215 | // default group and hence can't specify group permission |
||
216 | // in the previous mkdir() call |
||
217 | if (CACHE_FILE_GROUP != '') { |
||
218 | $res = true; |
||
0 ignored issues
–
show
|
|||
219 | $res = @chgrp($dirs[$i], CACHE_FILE_GROUP); |
||
220 | $res = @chmod($dirs[$i], 0777); |
||
221 | if (!$res) { |
||
222 | Util\JpGraphError::RaiseL(25119, $aFile); //(" Can't set permissions for $aFile. Permission problems?"); |
||
223 | } |
||
224 | } |
||
225 | } |
||
226 | |||
227 | return true; |
||
228 | } |
||
229 | } // @class Cache |
||
230 |