PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 1.30.0
Independent Analytics – WordPress Analytics Plugin v1.30.0
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / eftec / bladeone / lib / BladeOneCache.php
independent-analytics / vendor / eftec / bladeone / lib Last commit date
BladeOne.php 2 years ago BladeOneCache.php 2 years ago BladeOneCacheRedis.php 2 years ago BladeOneCustom.php 2 years ago bladeonecli 2 years ago
BladeOneCache.php
314 lines
1 <?php
2
3 /** @noinspection UnknownInspectionInspection */
4 /** @noinspection TypeUnsafeComparisonInspection */
5 namespace IAWP_SCOPED\eftec\bladeone;
6
7 use Exception;
8 use function fclose;
9 use function file_put_contents;
10 use function filemtime;
11 use function filesize;
12 use function fopen;
13 use function fwrite;
14 use function is_array;
15 use function is_object;
16 use function ob_get_contents;
17 use function print_r;
18 use function strlen;
19 use function substr;
20 use function time;
21 /**
22 * trait BladeOneCache
23 * Copyright (c) 2016 Jorge Patricio Castro Castillo MIT License. Don't delete this comment, its part of the license.
24 * Extends the tags of the class BladeOne. Its optional
25 * It adds the next tags to the template
26 * <code>
27 * @ cache([cacheid],[duration=86400]). The id is optional. The duration of the cache is in seconds
28 * // content here
29 * @ endcache()
30 * </code>
31 * It also adds a new function (optional) to the business or logic layer
32 * <code>
33 * if ($blade->cacheExpired('hellocache',1,5)) { //'helloonecache' =template, =1 id cache, 5=duration (seconds)
34 * // cache expired, so we should do some stuff (such as read from the database)
35 * }
36 * </code>
37 *
38 * @package BladeOneCache
39 * @version 3.42 2020-04-25
40 * @link https://github.com/EFTEC/BladeOne
41 * @author Jorge Patricio Castro Castillo <jcastro arroba eftec dot cl>
42 */
43 trait BladeOneCache
44 {
45 protected $curCacheId = 0;
46 protected $curCacheDuration = 0;
47 protected $curCachePosition = 0;
48 protected $cacheRunning = \false;
49 protected $cachePageRunning = \false;
50 protected $cacheLog;
51 /**
52 * @var array avoids comparing the file different times. It also avoids race conditions.
53 */
54 private $cacheExpired = [];
55 /**
56 * @var string=['get','post','getpost','request',null][$i]
57 */
58 private $cacheStrategy;
59 /** @var array|null */
60 private $cacheStrategyIndex;
61 /**
62 * @return null|string $cacheStrategy=['get','post','getpost','request',null][$i]
63 */
64 public function getCacheStrategy() : ?string
65 {
66 return $this->cacheStrategy;
67 }
68 /**
69 * It sets the cache log. If not cache log then it does not generate a log file<br>
70 * The cache log stores each time a template is creates or expired.<br>
71 *
72 * @param string $file
73 */
74 public function setCacheLog($file) : void
75 {
76 $this->cacheLog = $file;
77 }
78 public function writeCacheLog($txt, $nivel) : void
79 {
80 if (!$this->cacheLog) {
81 return;
82 // if there is not a file assigned then it skips saving.
83 }
84 $fz = @filesize($this->cacheLog);
85 if (is_object($txt) || is_array($txt)) {
86 $txt = print_r($txt, \true);
87 }
88 // Rewrite file if more than 100000 bytes
89 $mode = $fz > 100000 ? 'w' : 'a';
90 $fp = fopen($this->cacheLog, $mode);
91 if ($fp === \false) {
92 return;
93 }
94 switch ($nivel) {
95 case 1:
96 $txtNivel = 'expired';
97 break;
98 case 2:
99 $txtNivel = 'new';
100 break;
101 default:
102 $txtNivel = 'other';
103 }
104 $txtarg = \json_encode($this->cacheUniqueGUID(\false));
105 fwrite($fp, \date('c') . "\t{$txt}\t{$txtNivel}\t{$txtarg}\n");
106 fclose($fp);
107 }
108 /**
109 * It sets the strategy of the cache page.
110 *
111 * @param null|string $cacheStrategy =['get','post','getpost','request',null][$i]
112 * @param array|null $index if null then it reads all indexes. If not, it reads an indexes.
113 */
114 public function setCacheStrategy($cacheStrategy, $index = null) : void
115 {
116 $this->cacheStrategy = $cacheStrategy;
117 $this->cacheStrategyIndex = $index;
118 }
119 /**
120 * It obtains a unique GUID based in:<br>
121 * <b>get</b>= parameters from the url<br>
122 * <b>post</b>= parameters sends via post<br>
123 * <b>getpost</b> = a mix between get and post<br>
124 * <b>request</b> = get, post and cookies (including sessions)<br>
125 * MD5 could generate colisions (2^64 = 18,446,744,073,709,551,616) but the end hash is the sum of the hash of
126 * the page + this GUID.
127 *
128 * @param bool $serialize if true then it serializes using md5
129 * @return string|null
130 */
131 private function cacheUniqueGUID($serialize = \true) : ?string
132 {
133 switch ($this->cacheStrategy) {
134 case 'get':
135 $r = $_GET;
136 break;
137 case 'post':
138 $r = $_POST;
139 break;
140 case 'getpost':
141 $arr = \array_merge($_GET, $_POST);
142 $r = $arr;
143 break;
144 case 'request':
145 $r = $_REQUEST;
146 break;
147 default:
148 $r = null;
149 }
150 if ($this->cacheStrategyIndex === null || !is_array($r)) {
151 $r = \serialize($r);
152 } else {
153 $copy = [];
154 foreach ($r as $key => $item) {
155 if (\in_array($key, $this->cacheStrategyIndex, \true)) {
156 $copy[$key] = $item;
157 }
158 }
159 $r = \serialize($copy);
160 }
161 return $serialize === \true ? \md5($r) : $r;
162 }
163 public function compileCache($expression) : string
164 {
165 // get id of template
166 // if the file exists then
167 // compare date.
168 // if the date is too old then re-save.
169 // else
170 // save for the first time.
171 return $this->phpTag . "echo \$this->cacheStart{$expression}; if(!\$this->cacheRunning) { ?>";
172 }
173 public function compileEndCache($expression) : string
174 {
175 return $this->phpTag . "} // if cacheRunning\necho \$this->cacheEnd{$expression}; ?>";
176 }
177 /**
178 * It gets the filename of the compiled file (cached). If cache is not enabled, then it
179 * returns the regular file.
180 *
181 * @param string $view
182 * @return string The full filename
183 */
184 private function getCompiledFileCache($view) : string
185 {
186 $id = $this->cacheUniqueGUID();
187 if ($id !== null) {
188 return \str_replace($this->compileExtension, '_cache' . $id . $this->compileExtension, $this->getCompiledFile($view));
189 }
190 return $this->getCompiledFile($view);
191 }
192 /**
193 * run the blade engine. It returns the result of the code.
194 *
195 * @param string $view The name of the cache. Ex: "folder.folder.view" ("/folder/folder/view.blade")
196 * @param array $variables An associative arrays with the values to display.
197 * @param int $ttl time to live (in second).
198 * @return string
199 * @throws Exception
200 */
201 public function runCache($view, $variables = [], $ttl = 86400) : string
202 {
203 $this->cachePageRunning = \true;
204 $cacheStatus = $this->cachePageExpired($view, $ttl);
205 if ($cacheStatus !== 0) {
206 $this->writeCacheLog($view, $cacheStatus);
207 $this->cacheStart('_page_', $ttl);
208 $content = $this->run($view, $variables);
209 // if no cache, then it runs normally.
210 $this->fileName = $view;
211 // sometimes the filename is replaced (@include), so we restore it
212 $this->cacheEnd($content);
213 // and it stores as a cache paged.
214 } else {
215 $content = $this->getFile($this->getCompiledFileCache($view));
216 }
217 $this->cachePageRunning = \false;
218 return $content;
219 }
220 /**
221 * Returns true if the block cache expired (or doesn't exist), otherwise false.
222 *
223 * @param string $templateName name of the template to use (such hello for template hello.blade.php)
224 * @param string $id (id of cache, optional, if not id then it adds automatically a number)
225 * @param int $cacheDuration (duration of the cache in seconds)
226 * @return int 0=cache exists, 1= cache expired, 2=not exists, string= the cache file (if any)
227 */
228 public function cacheExpired($templateName, $id, $cacheDuration) : int
229 {
230 if ($this->getMode() & 1) {
231 return 2;
232 // forced mode, hence it always expires. (fast mode is ignored).
233 }
234 $compiledFile = $this->getCompiledFile($templateName) . '_cache' . $id;
235 return $this->cacheExpiredInt($compiledFile, $cacheDuration);
236 }
237 /**
238 * It returns true if the whole page expired.
239 *
240 * @param string $templateName
241 * @param int $cacheDuration is seconds.
242 * @return int 0=cache exists, 1= cache expired, 2=not exists, string= the cache content (if any)
243 */
244 public function cachePageExpired($templateName, $cacheDuration) : int
245 {
246 if ($this->getMode() & 1) {
247 return 2;
248 // forced mode, hence it always expires. (fast mode is ignored).
249 }
250 $compiledFile = $this->getCompiledFileCache($templateName);
251 return $this->CacheExpiredInt($compiledFile, $cacheDuration);
252 }
253 /**
254 * This method is used by cacheExpired() and cachePageExpired()
255 *
256 * @param string $compiledFile
257 * @param int $cacheDuration is seconds.
258 * @return int|mixed 0=cache exists, 1= cache expired, 2=not exists, string= the cache content (if any)
259 */
260 private function cacheExpiredInt($compiledFile, $cacheDuration)
261 {
262 if (isset($this->cacheExpired[$compiledFile])) {
263 // if the information is already in the array then returns it.
264 return $this->cacheExpired[$compiledFile];
265 }
266 $date = @filemtime($compiledFile);
267 if ($date) {
268 if ($date + $cacheDuration < time()) {
269 $this->cacheExpired[$compiledFile] = 1;
270 return 2;
271 // time-out.
272 }
273 } else {
274 $this->cacheExpired[$compiledFile] = 2;
275 return 1;
276 // no file
277 }
278 $this->cacheExpired[$compiledFile] = 0;
279 return 0;
280 // cache active.
281 }
282 public function cacheStart($id = '', $cacheDuration = 86400) : void
283 {
284 $this->curCacheId = $id == '' ? $this->curCacheId + 1 : $id;
285 $this->curCacheDuration = $cacheDuration;
286 $this->curCachePosition = strlen(ob_get_contents());
287 if ($this->cachePageRunning) {
288 $compiledFile = $this->getCompiledFileCache($this->fileName);
289 } else {
290 $compiledFile = $this->getCompiledFile() . '_cache' . $this->curCacheId;
291 }
292 if ($this->cacheExpired('', $id, $cacheDuration) !== 0) {
293 $this->cacheRunning = \false;
294 } else {
295 $this->cacheRunning = \true;
296 $content = $this->getFile($compiledFile);
297 echo $content;
298 }
299 }
300 public function cacheEnd($txt = null) : void
301 {
302 if (!$this->cacheRunning) {
303 $txt = $txt ?? substr(ob_get_contents(), $this->curCachePosition);
304 if ($this->cachePageRunning) {
305 $compiledFile = $this->getCompiledFileCache($this->fileName);
306 } else {
307 $compiledFile = $this->getCompiledFile() . '_cache' . $this->curCacheId;
308 }
309 file_put_contents($compiledFile, $txt);
310 }
311 $this->cacheRunning = \false;
312 }
313 }
314