PluginProbe ʕ •ᴥ•ʔ
10Web Booster – Website speed optimization, Cache & Page Speed optimizer / trunk
10Web Booster – Website speed optimization, Cache & Page Speed optimizer vtrunk
2.33.0 2.30.5 2.30.7 2.30.9 2.31.10 2.31.8 2.32.11 2.32.21 2.32.3 2.32.4 2.32.7 2.6.31 2.6.40 2.6.42 2.6.7 2.7.37 2.7.44 2.7.47 2.8.18 2.8.19 2.8.32 2.8.34 2.8.35 2.9.23 2.9.24 2.9.25 2.9.27 v2.27.4 trunk 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.17 2.0.18 2.0.21 2.0.22 2.0.25 2.0.26 2.0.27 2.0.3 2.0.7 2.0.9 2.10.46 2.10.65 2.10.66 2.10.68 2.11.41 2.11.42 2.11.43 2.12.15 2.12.21 2.12.22 2.12.23 2.12.26 2.13.37 2.13.40 2.13.41 2.13.42 2.13.44 2.13.45 2.13.47 2.14.49 2.14.50 2.15.18 2.17.21 2.17.23 2.18.17 2.19.44 2.19.45 2.19.46 2.19.49 2.2.12 2.2.15 2.2.16 2.2.18 2.2.8 2.20.31 2.20.32 2.20.33 2.21.11 2.21.12 2.21.16 2.21.25 2.22.32 2.23.13 2.23.15 2.23.16 2.23.18 2.24.12 2.24.14 2.24.18 2.25.14 2.26.6 2.28.10 2.28.13 2.28.14 2.28.7 2.29.1 2.29.2 2.29.3 2.3.0 2.3.1 2.3.2 2.3.3 2.30.18
tenweb-speed-optimizer / includes / OptimizerCacheStructure.php
tenweb-speed-optimizer / includes Last commit date
WebPageCache 8 months ago external 2 months ago ExcludeJsFromDelay.php 2 years ago OptimizerBanner.php 11 months ago OptimizerBase.php 2 years ago OptimizerCSSMin.php 2 years ago OptimizerCache.php 1 year ago OptimizerCacheStructure.php 2 years ago OptimizerCriticalCss.php 1 year ago OptimizerElementor.php 2 years ago OptimizerFonts.php 2 years ago OptimizerImages.php 1 year ago OptimizerLogger.php 1 year ago OptimizerMain.php 2 months ago OptimizerOnInit.php 11 months ago OptimizerScripts.php 2 years ago OptimizerSettings.php 2 months ago OptimizerStyles.php 2 years ago OptimizerUrl.php 1 year ago OptimizerUtils.php 2 months ago OptimizerWhiteLabel.php 2 years ago
OptimizerCacheStructure.php
345 lines
1 <?php
2
3 namespace TenWebOptimizer;
4
5 use DOMDocument;
6
7 /**
8 * Class OptimizerCacheStructure
9 */
10 class OptimizerCacheStructure
11 {
12 const TWO_CACHE_STRUCTURE_OPTION_PREFIX = 'two_cache_structure_';
13
14 const TWO_SOURCE_NAMES = [
15 'src',
16 'href',
17 'data-twodelayedjs',
18 'data-twodelayedcss'
19 ];
20
21 /**
22 * @var OptimizerCacheStructure
23 */
24 public static $instance;
25
26 /**
27 * @var array
28 */
29 private $structure;
30
31 /**
32 * @var mixed
33 */
34 private $pageUrlHash;
35
36 /**
37 * @var array
38 */
39 private $tagsToReplace;
40
41 /**
42 * @var array
43 */
44 private $tagsToAdd;
45
46 /**
47 * @var array
48 */
49 private $webFontList;
50
51 /**
52 * @var bool
53 */
54 private $isFromCache = false;
55
56 private $originalContent;
57
58 private $two_files_cache;
59
60 /**
61 * @var string
62 */
63 private $cacheHeaderString = 'BYPASS';
64
65 /**
66 * @var object
67 */
68 private $doc = null;
69
70 /**
71 * OptimizerCacheStructure constructor.
72 */
73 private function __construct()
74 {
75 //todo check multisite support
76 libxml_use_internal_errors(true);
77 $this->doc = new DOMDocument();
78 $this->pageUrlHash = md5(sanitize_text_field($_SERVER['REQUEST_URI'])); // phpcs:ignore
79 $this->structure = get_option(
80 self::TWO_CACHE_STRUCTURE_OPTION_PREFIX . $this->pageUrlHash,
81 [
82 'tagsToReplace' => [],
83 'tagsToAdd' => [],
84 'webFontList' => [],
85 ]
86 );
87
88 $this->tagsToReplace = !empty($this->structure['tagsToReplace']) ? $this->structure['tagsToReplace'] : [];
89 $this->tagsToAdd = !empty($this->structure['tagsToAdd']) ? $this->structure['tagsToAdd'] : [];
90 $this->webFontList = !empty($this->structure['webFontList']) ? $this->structure['webFontList'] : [];
91 global $TwoSettings;
92 $this->two_files_cache = $TwoSettings->get_settings('two_files_cache');
93 global $disableTwoCacheStructureCache;
94
95 if ($disableTwoCacheStructureCache === true) {
96 $this->disableCache();
97 }
98 }
99
100 /**
101 * Checks if there is cache structure data in cache
102 *
103 * @return bool
104 */
105 public function check($content)
106 {
107 if ($this->getCacheStatus()) {
108 if (is_array($this->tagsToReplace) && is_array($this->tagsToAdd)) {
109 foreach ($this->tagsToReplace as $replace_tag) {
110 $replace = $replace_tag['replace'];
111
112 if (!empty($replace) && $replace != strip_tags($replace)) { // phpcs:ignore
113 if (false === strpos($content, $replace) || !$this->getTagSource($replace)) {
114 return false;
115 }
116 }
117 }
118
119 foreach ($this->tagsToAdd as $add_tag) {
120 $replace = $add_tag['tag'];
121
122 if (!empty($replace) && $replace != strip_tags($replace)) { // phpcs:ignore
123 if (!$this->getTagSource($replace)) {
124 return false;
125 }
126 }
127 }
128 }
129
130 return !empty($this->tagsToReplace) && !empty($this->tagsToAdd);
131 }
132
133 return false;
134 }
135
136 /**
137 * Makes edits on main content data retrieved from cached
138 *
139 * @return mixed|string|string[]
140 */
141 public function retrieve($content)
142 {
143 $this->originalContent = $content;
144
145 if ($this->check($content)) {
146 foreach ($this->tagsToReplace as $tagToReplace) {
147 if ($tagToReplace['search'] !== '') {
148 $pos = strpos($content, $tagToReplace['search']);
149
150 if ($pos !== false) {
151 $content = substr_replace($content, $tagToReplace['replace'], $pos, strlen($tagToReplace['search']));
152 }
153 }
154 }
155
156 foreach ($this->tagsToAdd as $tagToAdd) {
157 $content = OptimizerUtils::inject_in_html($content, $tagToAdd['tag'], $tagToAdd['where']);
158 }
159
160 $this->isFromCache = true;
161 $this->cacheHeaderString = 'HIT';
162
163 return $content;
164 }
165
166 return $this->originalContent;
167 }
168
169 /**
170 * Updates cache structure in DB
171 *
172 * @return bool
173 */
174 public function set()
175 {
176 global $disableTwoCacheStructureCache;
177
178 if (!empty($this->structure['tagsToAdd']) && !empty($this->structure['tagsToReplace']) && $this->getCacheStatus() && $disableTwoCacheStructureCache !== true) {
179 $this->cacheHeaderString = 'MISS';
180 $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field($_SERVER['REQUEST_URI']) : '';
181 $timestamp_size = mb_strlen(gmdate('Y-m-d_H:i:s') . ' ' . $request_uri, '8bit');
182 $structure_size = mb_strlen(serialize((array) $this->structure), '8bit'); // phpcs:ignore
183 $total_size = (int) $timestamp_size + (int) $structure_size;
184
185 if (get_option(self::TWO_CACHE_STRUCTURE_OPTION_PREFIX . 'size')) {
186 $total_size = $total_size + (int) get_option(self::TWO_CACHE_STRUCTURE_OPTION_PREFIX . 'size');
187 }
188 update_option(self::TWO_CACHE_STRUCTURE_OPTION_PREFIX . 'size', $total_size, 'no');
189 update_option(self::TWO_CACHE_STRUCTURE_OPTION_PREFIX . 'TIMESTAMP_' . $this->pageUrlHash, gmdate('Y-m-d_H:i:s') . ' ' . $request_uri, 'no'); // phpcs:ignore
190
191 return update_option(self::TWO_CACHE_STRUCTURE_OPTION_PREFIX . $this->pageUrlHash, $this->structure, 'no');
192 }
193
194 return false;
195 }
196
197 /**
198 * init Singleton
199 *
200 * @return OptimizerCacheStructure
201 */
202 public static function init()
203 {
204 if (self::$instance === null) {
205 self::$instance = new self();
206 }
207
208 return self::$instance;
209 }
210
211 /**
212 * Whether the content data was populated from cache
213 *
214 * @return bool
215 */
216 public function isFromCache()
217 {
218 if ($this->getCacheStatus()) {
219 return $this->isFromCache;
220 }
221
222 return false;
223 }
224
225 /**
226 * Returns webFontList
227 *
228 * @return array|mixed
229 */
230 public function getWebFontList()
231 {
232 return $this->webFontList;
233 }
234
235 /**
236 * Adds array of tags that are needed to replace
237 */
238 public function addToTagsToReplace($search, $replace)
239 {
240 $this->structure['tagsToReplace'][] = [
241 'search' => $search,
242 'replace' => $replace
243 ];
244 }
245
246 /**
247 * Adds array of what tags and where
248 */
249 public function addToTagsToAdd($tag, $where)
250 {
251 $this->structure['tagsToAdd'][] = [
252 'tag' => $tag,
253 'where' => $where
254 ];
255 }
256
257 /**
258 * Adds font list array to cache structure
259 */
260 public function addToWebFontList($fonts)
261 {
262 $this->structure['webFontList'] = $fonts;
263 }
264
265 /**
266 * Returns Cache Status
267 *
268 * @return bool
269 */
270 public function getCacheStatus()
271 {
272 return $this->two_files_cache === 'on';
273 }
274
275 /**
276 * Returns Cache Status
277 */
278 public function disableCache()
279 {
280 $this->two_files_cache = '';
281 }
282
283 /**
284 * FLushes cache structure in DB
285 */
286 public static function flushAllCache()
287 {
288 global $wpdb;
289 $wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE '" . self::TWO_CACHE_STRUCTURE_OPTION_PREFIX . "%'"); // phpcs:ignore
290 }
291
292 public function addCacheHeaders()
293 {
294 header('X-TWO-Cache: ' . $this->cacheHeaderString);
295 }
296
297 /**
298 * Sets cache status
299 *
300 * @param string $status
301 */
302 public function setCacheHeaderString($status)
303 {
304 $this->cacheHeaderString = $status;
305 }
306
307 /**
308 * Check cache file
309 *
310 * @param string $data
311 *
312 * @return bool
313 */
314 private function getTagSource($data)
315 {
316 $this->doc->loadHTML($data);
317 $libxml_errors = libxml_get_errors();
318
319 if (empty($libxml_errors)) {
320 $tags = $this->doc->getElementsByTagName('*');
321
322 foreach (self::TWO_SOURCE_NAMES as $name) {
323 foreach ($tags as $tag) {
324 $source = $tag->getAttribute($name);
325
326 if (!empty($source)) {
327 $url_data = wp_parse_url($source);
328
329 if (isset($_SERVER['HTTP_HOST']) && isset($url_data['host']) && $_SERVER['HTTP_HOST'] == $url_data['host']) {
330 $file_path = WP_ROOT_DIR . $url_data['path'];
331
332 if (!file_exists($file_path)) {
333 return false;
334 }
335 }
336 }
337 }
338 }
339 }
340 libxml_clear_errors();
341
342 return true;
343 }
344 }
345