PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.2.0
Independent Analytics – WordPress Analytics Plugin v2.2.0
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
315 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 * @internal
43 */
44 trait BladeOneCache
45 {
46 protected $curCacheId = 0;
47 protected $curCacheDuration = 0;
48 protected $curCachePosition = 0;
49 protected $cacheRunning = \false;
50 protected $cachePageRunning = \false;
51 protected $cacheLog;
52 /**
53 * @var array avoids comparing the file different times. It also avoids race conditions.
54 */
55 private $cacheExpired = [];
56 /**
57 * @var string=['get','post','getpost','request',null][$i]
58 */
59 private $cacheStrategy;
60 /** @var array|null */
61 private $cacheStrategyIndex;
62 /**
63 * @return null|string $cacheStrategy=['get','post','getpost','request',null][$i]
64 */
65 public function getCacheStrategy() : ?string
66 {
67 return $this->cacheStrategy;
68 }
69 /**
70 * It sets the cache log. If not cache log then it does not generate a log file<br>
71 * The cache log stores each time a template is creates or expired.<br>
72 *
73 * @param string $file
74 */
75 public function setCacheLog($file) : void
76 {
77 $this->cacheLog = $file;
78 }
79 public function writeCacheLog($txt, $nivel) : void
80 {
81 if (!$this->cacheLog) {
82 return;
83 // if there is not a file assigned then it skips saving.
84 }
85 $fz = @filesize($this->cacheLog);
86 if (is_object($txt) || is_array($txt)) {
87 $txt = print_r($txt, \true);
88 }
89 // Rewrite file if more than 100000 bytes
90 $mode = $fz > 100000 ? 'w' : 'a';
91 $fp = fopen($this->cacheLog, $mode);
92 if ($fp === \false) {
93 return;
94 }
95 switch ($nivel) {
96 case 1:
97 $txtNivel = 'expired';
98 break;
99 case 2:
100 $txtNivel = 'new';
101 break;
102 default:
103 $txtNivel = 'other';
104 }
105 $txtarg = \json_encode($this->cacheUniqueGUID(\false));
106 fwrite($fp, \date('c') . "\t{$txt}\t{$txtNivel}\t{$txtarg}\n");
107 fclose($fp);
108 }
109 /**
110 * It sets the strategy of the cache page.
111 *
112 * @param null|string $cacheStrategy =['get','post','getpost','request',null][$i]
113 * @param array|null $index if null then it reads all indexes. If not, it reads an indexes.
114 */
115 public function setCacheStrategy($cacheStrategy, $index = null) : void
116 {
117 $this->cacheStrategy = $cacheStrategy;
118 $this->cacheStrategyIndex = $index;
119 }
120 /**
121 * It obtains a unique GUID based in:<br>
122 * <b>get</b>= parameters from the url<br>
123 * <b>post</b>= parameters sends via post<br>
124 * <b>getpost</b> = a mix between get and post<br>
125 * <b>request</b> = get, post and cookies (including sessions)<br>
126 * MD5 could generate colisions (2^64 = 18,446,744,073,709,551,616) but the end hash is the sum of the hash of
127 * the page + this GUID.
128 *
129 * @param bool $serialize if true then it serializes using md5
130 * @return string|null
131 */
132 private function cacheUniqueGUID($serialize = \true) : ?string
133 {
134 switch ($this->cacheStrategy) {
135 case 'get':
136 $r = $_GET;
137 break;
138 case 'post':
139 $r = $_POST;
140 break;
141 case 'getpost':
142 $arr = \array_merge($_GET, $_POST);
143 $r = $arr;
144 break;
145 case 'request':
146 $r = $_REQUEST;
147 break;
148 default:
149 $r = null;
150 }
151 if ($this->cacheStrategyIndex === null || !is_array($r)) {
152 $r = \serialize($r);
153 } else {
154 $copy = [];
155 foreach ($r as $key => $item) {
156 if (\in_array($key, $this->cacheStrategyIndex, \true)) {
157 $copy[$key] = $item;
158 }
159 }
160 $r = \serialize($copy);
161 }
162 return $serialize === \true ? \md5($r) : $r;
163 }
164 public function compileCache($expression) : string
165 {
166 // get id of template
167 // if the file exists then
168 // compare date.
169 // if the date is too old then re-save.
170 // else
171 // save for the first time.
172 return $this->phpTag . "echo \$this->cacheStart{$expression}; if(!\$this->cacheRunning) { ?>";
173 }
174 public function compileEndCache($expression) : string
175 {
176 return $this->phpTag . "} // if cacheRunning\necho \$this->cacheEnd{$expression}; ?>";
177 }
178 /**
179 * It gets the filename of the compiled file (cached). If cache is not enabled, then it
180 * returns the regular file.
181 *
182 * @param string $view
183 * @return string The full filename
184 */
185 private function getCompiledFileCache($view) : string
186 {
187 $id = $this->cacheUniqueGUID();
188 if ($id !== null) {
189 return \str_replace($this->compileExtension, '_cache' . $id . $this->compileExtension, $this->getCompiledFile($view));
190 }
191 return $this->getCompiledFile($view);
192 }
193 /**
194 * run the blade engine. It returns the result of the code.
195 *
196 * @param string $view The name of the cache. Ex: "folder.folder.view" ("/folder/folder/view.blade")
197 * @param array $variables An associative arrays with the values to display.
198 * @param int $ttl time to live (in second).
199 * @return string
200 * @throws Exception
201 */
202 public function runCache($view, $variables = [], $ttl = 86400) : string
203 {
204 $this->cachePageRunning = \true;
205 $cacheStatus = $this->cachePageExpired($view, $ttl);
206 if ($cacheStatus !== 0) {
207 $this->writeCacheLog($view, $cacheStatus);
208 $this->cacheStart('_page_', $ttl);
209 $content = $this->run($view, $variables);
210 // if no cache, then it runs normally.
211 $this->fileName = $view;
212 // sometimes the filename is replaced (@include), so we restore it
213 $this->cacheEnd($content);
214 // and it stores as a cache paged.
215 } else {
216 $content = $this->getFile($this->getCompiledFileCache($view));
217 }
218 $this->cachePageRunning = \false;
219 return $content;
220 }
221 /**
222 * Returns true if the block cache expired (or doesn't exist), otherwise false.
223 *
224 * @param string $templateName name of the template to use (such hello for template hello.blade.php)
225 * @param string $id (id of cache, optional, if not id then it adds automatically a number)
226 * @param int $cacheDuration (duration of the cache in seconds)
227 * @return int 0=cache exists, 1= cache expired, 2=not exists, string= the cache file (if any)
228 */
229 public function cacheExpired($templateName, $id, $cacheDuration) : int
230 {
231 if ($this->getMode() & 1) {
232 return 2;
233 // forced mode, hence it always expires. (fast mode is ignored).
234 }
235 $compiledFile = $this->getCompiledFile($templateName) . '_cache' . $id;
236 return $this->cacheExpiredInt($compiledFile, $cacheDuration);
237 }
238 /**
239 * It returns true if the whole page expired.
240 *
241 * @param string $templateName
242 * @param int $cacheDuration is seconds.
243 * @return int 0=cache exists, 1= cache expired, 2=not exists, string= the cache content (if any)
244 */
245 public function cachePageExpired($templateName, $cacheDuration) : int
246 {
247 if ($this->getMode() & 1) {
248 return 2;
249 // forced mode, hence it always expires. (fast mode is ignored).
250 }
251 $compiledFile = $this->getCompiledFileCache($templateName);
252 return $this->CacheExpiredInt($compiledFile, $cacheDuration);
253 }
254 /**
255 * This method is used by cacheExpired() and cachePageExpired()
256 *
257 * @param string $compiledFile
258 * @param int $cacheDuration is seconds.
259 * @return int|mixed 0=cache exists, 1= cache expired, 2=not exists, string= the cache content (if any)
260 */
261 private function cacheExpiredInt($compiledFile, $cacheDuration)
262 {
263 if (isset($this->cacheExpired[$compiledFile])) {
264 // if the information is already in the array then returns it.
265 return $this->cacheExpired[$compiledFile];
266 }
267 $date = @filemtime($compiledFile);
268 if ($date) {
269 if ($date + $cacheDuration < time()) {
270 $this->cacheExpired[$compiledFile] = 1;
271 return 2;
272 // time-out.
273 }
274 } else {
275 $this->cacheExpired[$compiledFile] = 2;
276 return 1;
277 // no file
278 }
279 $this->cacheExpired[$compiledFile] = 0;
280 return 0;
281 // cache active.
282 }
283 public function cacheStart($id = '', $cacheDuration = 86400) : void
284 {
285 $this->curCacheId = $id == '' ? $this->curCacheId + 1 : $id;
286 $this->curCacheDuration = $cacheDuration;
287 $this->curCachePosition = strlen(ob_get_contents());
288 if ($this->cachePageRunning) {
289 $compiledFile = $this->getCompiledFileCache($this->fileName);
290 } else {
291 $compiledFile = $this->getCompiledFile() . '_cache' . $this->curCacheId;
292 }
293 if ($this->cacheExpired('', $id, $cacheDuration) !== 0) {
294 $this->cacheRunning = \false;
295 } else {
296 $this->cacheRunning = \true;
297 $content = $this->getFile($compiledFile);
298 echo $content;
299 }
300 }
301 public function cacheEnd($txt = null) : void
302 {
303 if (!$this->cacheRunning) {
304 $txt = $txt ?? substr(ob_get_contents(), $this->curCachePosition);
305 if ($this->cachePageRunning) {
306 $compiledFile = $this->getCompiledFileCache($this->fileName);
307 } else {
308 $compiledFile = $this->getCompiledFile() . '_cache' . $this->curCacheId;
309 }
310 file_put_contents($compiledFile, $txt);
311 }
312 $this->cacheRunning = \false;
313 }
314 }
315