PluginProbe
Translate and Go multilingual – Automatic AI translation – wpLingua / 2.12.2
Translate and Go multilingual – Automatic AI translation – wpLingua v2.12.2
2.16.7 2.16.6 2.16.5 2.16.4 2.16.3 2.16.2 2.16.1 2.16.0 2.15.2 2.15.1 2.15.0 2.14.3 2.14.2 2.14.1 2.14.0 2.13.1 2.13.0 2.12.3 2.12.2 2.12.1 trunk 1.0.3 1.0.4 1.0.5 1.1.0 All 112 releases
wplingua / inc / cache.php

cache.php in Translate and Go multilingual – Automatic AI translation – wpLingua 2.12.2, at inc/cache.php

515 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // If this file is called directly, abort.
4 if ( ! defined( 'WPINC' ) ) {
5 die;
6 }
7
8
9 // ------------------------------------------------------------------------
10 // Manage cache on "init" hoot
11 // ------------------------------------------------------------------------
12
13 /**
14 * Do not cache page for connected editor
15 *
16 * @return void
17 */
18 function wplng_init_manage_cache() {
19 if ( current_user_can( 'edit_posts' ) ) {
20 wplng_do_not_cache_page();
21 }
22 }
23
24
25 // ------------------------------------------------------------------------
26 // Global cache functions
27 // ------------------------------------------------------------------------
28
29 /**
30 * Prevent the current page from being cached
31 *
32 * Sets HTTP no-cache headers and defines constants used by popular
33 * WordPress caching plugins to bypass caching for the current request.
34 *
35 * @return void
36 */
37 function wplng_do_not_cache_page() {
38
39 // Set HTTP no-cache header
40 nocache_headers();
41
42 // DONOTCACHEPAGE - Standard WordPress
43 // - WP Super Cache
44 // - W3 Total Cache
45 // - WP Rocket
46 if ( ! defined( 'DONOTCACHEPAGE' ) ) {
47 define( 'DONOTCACHEPAGE', true );
48 }
49
50 // LiteSpeed Cache
51 if ( ! defined( 'LSCACHE_NO_CACHE' ) ) {
52 define( 'LSCACHE_NO_CACHE', true );
53 }
54
55 // Comet Cache
56 if ( ! defined( 'COMET_CACHE_ALLOWED' ) ) {
57 define( 'COMET_CACHE_ALLOWED', false );
58 }
59
60 // Cache Enabler
61 if ( ! defined( 'CE_CACHE_BYPASS' ) ) {
62 define( 'CE_CACHE_BYPASS', true );
63 }
64
65 // WP Fastest Cache
66 if ( ! defined( 'WPFC_NO_CACHE' ) ) {
67 define( 'WPFC_NO_CACHE', true );
68 }
69
70 // Breeze (Cloudways)
71 if ( ! defined( 'DONOTCACHEDB' ) ) {
72 define( 'DONOTCACHEDB', true );
73 }
74
75 // Object cache
76 if ( ! defined( 'DONOTCACHEOBJECT' ) ) {
77 define( 'DONOTCACHEOBJECT', true );
78 }
79 }
80
81
82 /**
83 * Clear all website caches
84 *
85 * Flushes the WordPress object cache and triggers cache clearing
86 * for all detected caching plugins and services.
87 *
88 * @return void
89 */
90 function wplng_clear_website_cache() {
91
92 // WordPress Cache
93 wp_cache_flush();
94
95 // LiteSpeed Cache
96 if ( has_action( 'litespeed_purge_all' ) ) {
97 do_action( 'litespeed_purge_all' );
98 }
99
100 // WP Super Cache
101 if ( function_exists( 'wp_cache_clear_cache' ) ) {
102 wp_cache_clear_cache();
103 }
104
105 // W3 Total Cache
106 if ( function_exists( 'w3tc_flush_all' ) ) {
107 w3tc_flush_all();
108 }
109
110 // WP Fastest Cache
111 if ( function_exists( 'wpfc_clear_all_cache' ) ) {
112 wpfc_clear_all_cache();
113 }
114
115 // WP Rocket
116 if ( function_exists( 'rocket_clean_domain' ) ) {
117 if ( did_action( 'wp_rocket_loaded' ) ) {
118 rocket_clean_domain();
119 } else {
120 add_action( 'wp_rocket_loaded', 'rocket_clean_domain' );
121 }
122 }
123
124 // Autoptimize
125 if ( class_exists( 'autoptimizeCache' )
126 && method_exists( 'autoptimizeCache', 'clearall' )
127 ) {
128 autoptimizeCache::clearall();
129 }
130
131 // Comet Cache
132 if ( class_exists( 'comet_cache' )
133 && method_exists( 'comet_cache', 'clear' )
134 ) {
135 comet_cache::clear();
136 }
137
138 // Hummingbird
139 if ( has_action( 'wphb_clear_page_cache' ) ) {
140 do_action( 'wphb_clear_page_cache' );
141 }
142
143 // SG Optimizer (SiteGround)
144 if ( function_exists( 'sg_cachepress_purge_cache' ) ) {
145 sg_cachepress_purge_cache();
146 }
147
148 // Breeze (Cloudways)
149 if ( has_action( 'breeze_clear_all_cache' ) ) {
150 do_action( 'breeze_clear_all_cache' );
151 }
152
153 // Cache Enabler
154 if ( class_exists( 'Cache_Enabler' )
155 && method_exists( 'Cache_Enabler', 'clear_total_cache' )
156 ) {
157 Cache_Enabler::clear_total_cache();
158 }
159
160 // Swift Performance
161 if ( class_exists( 'Swift_Performance_Cache' )
162 && method_exists( 'Swift_Performance_Cache', 'clear_all_cache' )
163 ) {
164 Swift_Performance_Cache::clear_all_cache();
165 }
166
167 // Nginx Helper
168 if ( has_action( 'rt_nginx_helper_purge_all' ) ) {
169 do_action( 'rt_nginx_helper_purge_all' );
170 }
171
172 // WP-Optimize
173 if ( class_exists( 'WP_Optimize' )
174 && function_exists( 'wpo_cache_flush' )
175 ) {
176 wpo_cache_flush();
177 }
178
179 // Kinsta Cache
180 if ( class_exists( 'Kinsta\Cache' )
181 && wp_get_environment_type() === 'production'
182 ) {
183 wp_remote_get(
184 home_url( '/?kinsta-clear-cache-all' ),
185 array( 'blocking' => false )
186 );
187 }
188
189 // Cloudflare
190 if ( has_action( 'cloudflare_purge_everything' ) ) {
191 do_action( 'cloudflare_purge_everything' );
192 }
193 }
194
195
196 // ------------------------------------------------------------------------
197 // Translations cache functions
198 // ------------------------------------------------------------------------
199
200 /**
201 * Clear cached translations
202 *
203 * Deletes the translations transient and clears the website cache.
204 *
205 * @return void
206 */
207 function wplng_clear_translations_cache() {
208 delete_transient( 'wplng_cached_translations' );
209 wplng_clear_website_cache();
210 }
211
212
213 /**
214 * Clear cached translations when a translation post is trashed or untrashed
215 *
216 * @param int $post_id The ID of the post being trashed or untrashed.
217 * @return void
218 */
219 function wplng_clear_translations_cache_trash_untrash( $post_id ) {
220
221 if ( 'wplng_translation' !== get_post_type( $post_id ) ) {
222 return;
223 }
224
225 wplng_clear_translations_cache();
226 }
227
228
229 // ------------------------------------------------------------------------
230 // Slug cache functions
231 // ------------------------------------------------------------------------
232
233 /**
234 * Clear cached slugs
235 *
236 * Deletes the slugs transient and clears the website cache.
237 *
238 * @return void
239 */
240 function wplng_clear_slugs_cache() {
241 delete_transient( 'wplng_cached_slugs' );
242 wplng_clear_website_cache();
243 }
244
245
246 /**
247 * Clear cached slugs when a slug post is trashed or untrashed
248 *
249 * @param int $post_id The ID of the post being trashed or untrashed.
250 * @return void
251 */
252 function wplng_clear_slugs_cache_trash_untrash( $post_id ) {
253
254 if ( 'wplng_slug' !== get_post_type( $post_id ) ) {
255 return;
256 }
257
258 wplng_clear_slugs_cache();
259 }
260
261 // ------------------------------------------------------------------------
262 // wpLingua file cache functions
263 // ------------------------------------------------------------------------
264
265 /**
266 * Write data to a cache file in the wpLingua cache directory.
267 *
268 * Creates the cache directory structure and protection files if needed,
269 * then writes the provided data to the specified file.
270 *
271 * @param string $file_name Relative path to the cache file (from WPLNG_CACHE_DIR).
272 * @param string $data Data to write to the file.
273 * @return int|false Number of bytes written, or false on failure.
274 */
275 function wplng_put_cache_file( $file_name, $data ) {
276
277 // Create main wpLingua cache folder if not exist
278 if ( ! is_dir( WPLNG_CACHE_DIR ) ) {
279 if ( ! wp_mkdir_p( WPLNG_CACHE_DIR ) ) {
280 return false;
281 }
282 }
283
284 // Create minimal protections in main folder (only once per request)
285 static $main_protection_checked = false;
286
287 if ( ! $main_protection_checked ) {
288
289 // Create .htaccess if not exists
290 if ( ! file_exists( WPLNG_CACHE_DIR . '/.htaccess' ) ) {
291
292 $htaccess = '##############################' . PHP_EOL;
293 $htaccess .= '# File generated by wpLingua #' . PHP_EOL;
294 $htaccess .= '##############################' . PHP_EOL;
295 $htaccess .= PHP_EOL;
296 $htaccess .= '# Disable files listing' . PHP_EOL;
297 $htaccess .= 'Options -Indexes' . PHP_EOL;
298 $htaccess .= PHP_EOL;
299 $htaccess .= '# Deny all HTTP access to this directory' . PHP_EOL;
300 $htaccess .= '<IfModule mod_authz_core.c>' . PHP_EOL;
301 $htaccess .= ' Require all denied' . PHP_EOL;
302 $htaccess .= '</IfModule>' . PHP_EOL;
303 $htaccess .= PHP_EOL;
304 $htaccess .= '<IfModule !mod_authz_core.c>' . PHP_EOL;
305 $htaccess .= ' Deny from all' . PHP_EOL;
306 $htaccess .= '</IfModule>' . PHP_EOL;
307
308 file_put_contents( WPLNG_CACHE_DIR . '/.htaccess', $htaccess );
309 }
310
311 // Create an empty index.html file in main folder
312 wplng_create_cache_index_html( WPLNG_CACHE_DIR );
313
314 $main_protection_checked = true;
315 }
316
317 // Create the subfolder if needed
318 $dir = dirname( WPLNG_CACHE_DIR . $file_name );
319 if ( ! is_dir( $dir ) ) {
320 if ( ! wp_mkdir_p( $dir ) ) {
321 return false;
322 }
323 }
324
325 // Create index.html in all directories between main path and target directory
326 wplng_create_cache_index_html_recursive( $dir );
327
328 // Write the cache file
329 return file_put_contents( WPLNG_CACHE_DIR . $file_name, $data );
330 }
331
332
333 /**
334 * Create an empty index.html file in the specified directory.
335 *
336 * @param string $dir_path Absolute path to the directory.
337 * @return bool True if file exists or was created, false on failure.
338 */
339 function wplng_create_cache_index_html( $dir_path ) {
340
341 $index_file = rtrim( $dir_path, '/\\' ) . '/index.html';
342
343 if ( file_exists( $index_file ) ) {
344 return true;
345 }
346
347 return file_put_contents( $index_file, '' ) !== false;
348 }
349
350
351 /**
352 * Create index.html files in all directories from WPLNG_CACHE_DIR to the target directory.
353 *
354 * @param string $target_dir Absolute path to the target directory.
355 * @return void
356 */
357 function wplng_create_cache_index_html_recursive( $target_dir ) {
358
359 $target_dir = wp_normalize_path( $target_dir );
360 $base_path = wp_normalize_path( WPLNG_CACHE_DIR );
361
362 // Ensure target is within cache path
363 if ( strpos( $target_dir, $base_path ) !== 0 ) {
364 return;
365 }
366
367 // Get relative path from base
368 $relative_path = substr( $target_dir, strlen( $base_path ) );
369 $relative_path = trim( $relative_path, '/' );
370
371 if ( empty( $relative_path ) ) {
372 return;
373 }
374
375 // Build each subdirectory and create index.html
376 $parts = explode( '/', $relative_path );
377 $current_path = $base_path;
378
379 foreach ( $parts as $part ) {
380 $current_path .= '/' . $part;
381 if ( is_dir( $current_path ) ) {
382 wplng_create_cache_index_html( $current_path );
383 }
384 }
385 }
386
387
388 /**
389 * Read data from a cache file in the wpLingua cache directory.
390 *
391 * @param string $file_name Relative path to the cache file (from WPLNG_CACHE_DIR).
392 * @return string|false File contents, or false if file doesn't exist or isn't readable.
393 */
394 function wplng_get_cache_file( $file_name ) {
395
396 $file_path = WPLNG_CACHE_DIR . $file_name;
397
398 if ( ! is_readable( $file_path ) ) {
399 return false;
400 }
401
402 return file_get_contents( $file_path );
403 }
404
405
406 /**
407 * Clear wpLingua cache folder or a specific file/directory.
408 *
409 * @param string|false $file Relative path to delete, or false to delete entire cache folder.
410 * @return bool True on success, false on failure.
411 */
412 function wplng_clear_folder_cache( $file = false ) {
413
414 if ( $file === false ) {
415 $path = WPLNG_CACHE_DIR;
416 } else {
417 $path = wp_normalize_path( WPLNG_CACHE_DIR . $file );
418
419 // Security: ensure path is within cache directory
420 if ( strpos( $path, wp_normalize_path( WPLNG_CACHE_DIR ) ) !== 0 ) {
421 return false;
422 }
423 }
424
425 if ( ! file_exists( $path ) ) {
426 return true;
427 }
428
429 if ( is_file( $path ) ) {
430 return @unlink( $path );
431 }
432
433 return wplng_delete_directory( $path );
434 }
435
436
437 /**
438 * Clear wpLingua cache when WordPress core, plugins, themes or translations are updated.
439 *
440 * Hooked to:
441 * - upgrader_process_complete (core, plugins, themes, translations updates)
442 * - activated_plugin
443 * - deactivated_plugin
444 * - switch_theme
445 *
446 * @param mixed $upgrader_or_plugin WP_Upgrader instance or plugin slug (depends on hook).
447 * @param array $options Array of update data (only for upgrader_process_complete).
448 * @return void
449 */
450 function wplng_clear_cache_on_update( $upgrader_or_plugin = null, $options = array() ) {
451
452 // For upgrader_process_complete hook, check update type
453 if ( ! empty( $options ) && is_array( $options ) ) {
454
455 $type = isset( $options['type'] ) ? $options['type'] : '';
456
457 // Clear cache for core, plugin, theme or translation updates
458 if ( in_array( $type, array( 'core', 'plugin', 'theme', 'translation' ), true ) ) {
459 wplng_clear_folder_cache();
460 }
461
462 return;
463 }
464
465 // For other hooks (activated_plugin, deactivated_plugin, switch_theme)
466 wplng_clear_folder_cache();
467 }
468
469
470 /**
471 * Recursively delete a directory and all its contents.
472 *
473 * Only deletes directories within WPLNG_CACHE_DIR for security.
474 *
475 * @param string $dir_path Absolute path to the directory.
476 * @return bool True on success, false on failure.
477 */
478 function wplng_delete_directory( $dir_path ) {
479
480 $dir_path = wp_normalize_path( $dir_path );
481 $base_path = wp_normalize_path( WPLNG_CACHE_DIR );
482
483 // Security: ensure path is within cache directory
484 if ( strpos( $dir_path, $base_path ) !== 0 ) {
485 return false;
486 }
487
488 if ( ! is_dir( $dir_path ) ) {
489 return false;
490 }
491
492 $items = scandir( $dir_path );
493
494 if ( $items === false ) {
495 return false;
496 }
497
498 foreach ( $items as $item ) {
499
500 if ( $item === '.' || $item === '..' ) {
501 continue;
502 }
503
504 $item_path = $dir_path . '/' . $item;
505
506 if ( is_dir( $item_path ) ) {
507 wplng_delete_directory( $item_path );
508 } else {
509 @unlink( $item_path );
510 }
511 }
512
513 return @rmdir( $dir_path );
514 }
515