PluginProbe
wpForo Forum / 2.0.8
wpForo Forum v2.0.8
3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.2 All 137 releases
wpforo / classes / Cache.php

Cache.php in wpForo Forum 2.0.8, at classes/Cache.php

464 lines 20.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace wpforo\classes;
4
5 use FilesystemIterator;
6
7 // Exit if accessed directly
8 if( ! defined( 'ABSPATH' ) ) exit;
9
10 class Cache {
11 public $object;
12 public $dir;
13 public $lang;
14
15 function __construct() {
16 add_action( 'wpforo_after_init_folders', function( $folders ) {
17 $cache_dir = $folders['cache']['dir'];
18 if( ! is_dir( $cache_dir ) ) $this->dir( $cache_dir );
19 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'tag' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'tag' );
20 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'tag' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'tag' );
21 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'option' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'option' );
22
23 $this->dir = $cache_dir;
24 } );
25
26 add_action( 'wpforo_after_set_locale', function( $locale ) { $this->lang = $locale; } );
27
28 add_action( 'wpforo_after_add_board', function( $board ){
29 if( $board['status'] ){
30 WPF()->change_board( $board['boardid'] );
31 wpforo_clean_cache();
32 }
33 } );
34
35 add_action( 'wpforo_after_edit_board', function( $boardid ){
36 $board = WPF()->board->_get_board( $boardid );
37 if( wpfval($board, 'status' ) ){
38 WPF()->change_board( $boardid );
39 wpforo_clean_cache();
40 }
41 } );
42 }
43
44 public function get_key( $type = 'html' ) {
45 if( $type === 'html' ) {
46 $ug = WPF()->current_user_groupid;
47
48 return md5( preg_replace( '#(.+)\#.+?$#is', '$1', $_SERVER['REQUEST_URI'] ) . $ug );
49 }
50 }
51
52 private function dir( $cache_dir ) {
53 $dirs = [
54 $cache_dir,
55 $cache_dir . DIRECTORY_SEPARATOR . 'forum',
56 $cache_dir . DIRECTORY_SEPARATOR . 'topic',
57 $cache_dir . DIRECTORY_SEPARATOR . 'post',
58 $cache_dir . DIRECTORY_SEPARATOR . 'tag',
59 $cache_dir . DIRECTORY_SEPARATOR . 'item',
60 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'forum',
61 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'topic',
62 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'post',
63 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'tag',
64 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'option',
65 ];
66 $this->mkdir( $dirs );
67 }
68
69 private function mkdir( $dirs ) {
70 foreach( (array) $dirs as $dir ) {
71 wp_mkdir_p( $dir );
72 wpforo_write_file( $dir . '/index.html', '' );
73 wpforo_write_file( $dir . '/.htaccess', 'deny from all' );
74 }
75 }
76
77 public function on(){
78 return wpforo_setting( 'board', 'cache' );
79 }
80
81 public function get( $key, $type = 'loop', $template = null ) {
82 $template = ( $template ) ?: WPF()->current_object['template'];
83 $loop_templates = [ 'forum', 'topic', 'post', 'tag', 'option' ];
84 if( $type === 'loop' && $template ) {
85 if( $this->exists( $key, $template ) ) {
86 if( in_array( $template, $loop_templates ) ) {
87 $cache_file = $this->dir . '/' . $template . '/' . $key;
88 $array = wpforo_get_file_content( $cache_file );
89
90 return @unserialize( $array );
91 }
92 }
93 }
94 }
95
96 public function get_item( $id, $type = 'post' ) {
97 if( $id ) {
98 $key = $id . '_' . $this->lang;
99 if( $this->exists( $key, 'item', $type ) ) {
100 $cache_file = $this->dir . '/item/' . $type . '/' . $key;
101 $array = wpforo_get_file_content( $cache_file );
102
103 return @unserialize( $array );
104 }
105 }
106 }
107
108 public function get_html() {
109 $template = WPF()->current_object['template'];
110 if( $template == 'forum' ) {
111 $key = $this->get_key();
112 if( $this->exists( $key, $template ) ) {
113 $cache_file = $this->dir . '/' . $template . '/' . $key;
114 $html = wpforo_get_file_content( $cache_file );
115
116 return $this->filter( $html );
117 }
118 }
119
120 return false;
121 }
122
123 public function html( $content ) {
124 /*$template = WPF()->current_object['template'];
125 if( $template === 'forum' ){
126 $key = $this->get_key();
127 $this->create_html( $content, $template, $key );
128 }*/
129 }
130
131 public function create( $mode = 'loop', $cache = [], $type = 'post' ) {
132 if( ! $this->on() ) return false;
133 $template = WPF()->current_object['template'];
134 if( $template == 'forum' ) {
135 $this->check( $this->dir . '/item/post' );
136 }
137
138 if( $mode === 'loop' && $template ) {
139 if( wpfval( $cache, 'tags' ) ) {
140 $this->create_files( $cache['tags'], 'tag' );
141 }
142 if( $template === 'forum' || $template === 'topic' || $template === 'post' ) {
143 $cache = WPF()->forum->get_cache( 'forums' );
144 $this->create_files( $cache, $template );
145 $cache = WPF()->topic->get_cache( 'topics' );
146 $this->create_files( $cache, $template );
147 $cache = WPF()->post->get_cache( 'posts' );
148 $this->create_files( $cache, $template );
149 }
150 } elseif( $mode === 'item' && ! empty( $cache ) ) {
151 $this->create_files( $cache, 'item', $type );
152 }
153 }
154
155 public function create_files( $cache = [], $template = '', $type = '' ) {
156 if( ! empty( $cache ) ) {
157 $type = ( $type ) ? $type . '/' : '';
158 foreach( $cache as $key => $object ) {
159 if( $template == 'item' ) $key = $key . '_' . $this->lang;
160 if( ! $this->exists( $key, $template ) ) {
161 $object = serialize( $object );
162 wpforo_write_file( $this->dir . '/' . $template . '/' . $type . $key, $object );
163 }
164 }
165 }
166 }
167
168 public function create_html( $content, $template = '', $key = '' ) {
169 if( $content ) {
170 if( ! $this->exists( $key, $template ) ) {
171 wpforo_write_file( $this->dir . '/' . $template . '/' . $key, $content );
172 }
173 }
174 }
175
176 public function create_custom( $args = [], $items = [], $template = 'post', $items_count = 0 ) {
177 if( empty( $args ) || ! is_array( $args ) ) return;
178 if( empty( $items ) || ! is_array( $items ) ) return;
179 $cache = [];
180 $hach = serialize( $args );
181 $object_key = md5( $hach . WPF()->current_user_groupid );
182 $cache[ $object_key ]['items'] = $items;
183 $cache[ $object_key ]['items_count'] = $items_count;
184 $this->create_files( $cache, $template );
185 }
186
187 public function filter( $html = '' ) {
188 //exit();
189 $html = preg_replace( '|<div[\s\t]*id=\"wpf\-msg\-box\"|is', '<div style="display:none;"', $html );
190
191 return $html;
192 }
193
194 #################################################################################
195
196 /**
197 * Cleans forum cache
198 *
199 * @param integer Item ID (e.g.: $topicid or $postid) | (!) ID is 0 on dome actions (e.g.: delete actions)
200 * @param string Item Type (e.g.: 'forum', 'topic', 'post', 'user', 'widget', etc...)
201 * @param array Item data as array
202 *
203 * @return NULL
204 * @since 1.2.1
205 *
206 */
207
208 public function clean( $id, $template, $item = [] ) {
209
210 $dirs = [];
211 $userid = ( isset( $item['userid'] ) && $item['userid'] ) ? $item['userid'] : 0;
212 $postid = ( isset( $item['postid'] ) && $item['postid'] ) ? $item['postid'] : 0;
213 $topicid = ( isset( $item['topicid'] ) && $item['topicid'] ) ? $item['topicid'] : 0;
214 $forumid = ( isset( $item['forumid'] ) && $item['forumid'] ) ? $item['forumid'] : 0;
215 $parentid = ( isset( $item['parentid'] ) && $item['parentid'] ) ? $item['parentid'] : 0;
216 $root = ( isset( $item['root'] ) && $item['root'] ) ? $item['root'] : 0;
217 $tagid = ( isset( $item['tagid'] ) && $item['tagid'] ) ? $item['tagid'] : 0;
218
219 WPF()->forum->reset();
220 WPF()->topic->reset();
221 WPF()->post->reset();
222
223 if( $template === 'forum' || $template === 'forum-soft' ) {
224 $id = isset( $id ) ? $id : $forumid;
225 if( $template === 'forum' ) {
226 $dirs = [ $this->dir . '/forum', $this->dir . '/item/forum' ];
227 WPF()->seo->clear_cache();
228 } elseif( $template === 'forum-soft' ) {
229 $dirs = [ $this->dir . '/forum' ];
230 }
231 if( $id ) {
232 $file = $this->dir . '/item/forum/' . $id . '_' . $this->lang;
233 $this->clean_file( $file );
234 }
235 } elseif( $template === 'topic' || $template === 'topic-soft' ) {
236 $id = isset( $id ) ? $id : $topicid;
237 if( $template === 'topic' ) {
238 WPF()->seo->clear_cache();
239 $dirs = [ $this->dir . '/forum', $this->dir . '/item/forum', $this->dir . '/topic', $this->dir . '/post' ];
240 }
241 if( $template === 'topic-soft' && $forumid ) {
242 $file = $this->dir . '/item/forum/' . $forumid . '_' . $this->lang;
243 $this->clean_file( $file );
244 }
245 if( $id ) {
246 $file = $this->dir . '/item/topic/' . $id . '_' . $this->lang;
247 $this->clean_file( $file );
248 $postid = ( isset( $item['first_postid'] ) && $item['first_postid'] ) ? $item['first_postid'] : 0;
249 if( $postid ) $file = $this->dir . '/item/post/' . $postid . '_' . $this->lang;
250 $this->clean_file( $file );
251 }
252 WPF()->statistic_cache_clean();
253 $this->clear_visitor_tracking();
254 } elseif( $template === 'post' || $template === 'post-soft' ) {
255 $id = isset( $id ) ? $id : $postid;
256 if( $template === 'post' ) {
257 $dirs = [ $this->dir . '/forum', $this->dir . '/topic', $this->dir . '/post' ];
258 }
259 if( $forumid ) {
260 $file = $this->dir . '/item/forum/' . $forumid . '_' . $this->lang;
261 $this->clean_file( $file );
262 }
263 if( $topicid ) {
264 $file = $this->dir . '/item/topic/' . $topicid . '_' . $this->lang;
265 $this->clean_file( $file );
266 }
267 if( $parentid ) {
268 $file = $this->dir . '/item/post/' . $parentid . '_' . $this->lang;
269 $this->clean_file( $file );
270 }
271 if( $root ) {
272 $file = $this->dir . '/item/post/' . $root . '_' . $this->lang;
273 $this->clean_file( $file );
274 }
275 if( $id ) {
276 $file = $this->dir . '/item/post/' . $id . '_' . $this->lang;
277 $this->clean_file( $file );
278 }
279 WPF()->statistic_cache_clean();
280 $this->clear_visitor_tracking();
281 } elseif( $template === 'tag' ) {
282 if( $id ) {
283 $file = $this->dir . '/item/tag/' . md5( $id ) . '_' . $this->lang;
284 $this->clean_file( $file );
285 } else {
286 $dirs = [ $this->dir . '/tag' ];
287 }
288 } elseif( $template === 'option' ) {
289 $dirs = [ $this->dir . '/item/option/' ];
290 } elseif( $template === 'user' ) {
291 if( wpforo_setting( 'seo', 'seo_profile' ) ) WPF()->seo->clear_cache();
292 } elseif( $template === 'loop' ) {
293 $dirs = [ $this->dir . '/forum', $this->dir . '/topic', $this->dir . '/post' ];
294 WPF()->seo->clear_cache();
295 } elseif( $template === 'item' ) {
296 $dirs = [ $this->dir . '/item/post', $this->dir . '/item/topic', $this->dir . '/item/forum' ];
297 WPF()->seo->clear_cache();
298 } else {
299 $dirs = [ $this->dir . '/forum', $this->dir . '/topic', $this->dir . '/post', $this->dir . '/tag', $this->dir . '/item/post', $this->dir . '/item/topic', $this->dir . '/item/forum', $this->dir . '/item/tag', $this->dir . '/item/option/' ];
300 WPF()->seo->clear_cache();
301 }
302
303 if( ! empty( $dirs ) ) {
304 foreach( $dirs as $dir ) {
305 $this->clean_files( $dir );
306 }
307 }
308
309 }
310
311 public function clean_files( $directory ) {
312 $directory = wpforo_fix_dir_sep( $directory );
313 $directory_ns = trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*';
314 $directory_ws = DIRECTORY_SEPARATOR . trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*';
315 $glob = glob( $directory_ns );
316 if( empty( $glob ) ) $glob = glob( $directory_ws );
317 foreach( $glob as $item ) {
318 if( strpos( $item, 'index.html' ) !== false || strpos( $item, '.htaccess' ) !== false ) continue;
319 if( ! is_dir( $item ) && file_exists( $item ) ) {
320 @unlink( $item );
321 }
322 }
323 }
324
325 public function clean_file( $file ) {
326 if( ! is_dir( $file ) && file_exists( $file ) ) {
327 @unlink( $file );
328 }
329 }
330
331 public function exists( $key, $template, $type = '' ) {
332 $type = ( $type ) ? $type . '/' : '';
333 if( file_exists( $this->dir . '/' . $template . '/' . $type . $key ) ) {
334 return true;
335 } else {
336 return false;
337 }
338 }
339
340 public function check( $directory ) {
341 $directory = wpforo_fix_dir_sep( $directory );
342 $filecount = 0;
343 if( class_exists( 'FilesystemIterator' ) && is_dir( $directory ) ) {
344 $fi = new FilesystemIterator( $directory, FilesystemIterator::SKIP_DOTS );
345 $filecount = iterator_count( $fi );
346 }
347 if( ! $filecount ) {
348 $directory_ns = trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*';
349 $directory_ws = DIRECTORY_SEPARATOR . trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*';
350 $files = glob( $directory_ns );
351 if( empty( $files ) ) $files = glob( $directory_ws );
352 $filecount = count( $files );
353 }
354 if( $filecount > 1000 ) {
355 $this->clean_files( $directory );
356 }
357 }
358
359 public function clear_visitor_tracking() {
360 $keep_vistors_data = apply_filters( 'wpforo_keep_visitors_data', 4000 );
361 $time = (int) current_time( 'timestamp', 1 ) - (int) $keep_vistors_data;
362 $online = (int) current_time( 'timestamp', 1 ) - (int) wpforo_setting( 'profiles', 'online_status_timeout' );
363 if( $time > 1 ) {
364 WPF()->db->query( "DELETE FROM `" . WPF()->tables->visits . "` WHERE `time` < " . intval( $time ) . " OR (`time` < " . intval( $online ) . " AND `userid` = 0)" );
365 }
366 }
367
368 public function cache_plugins(){
369 $board_paths = [];
370 $cache_plugins = [];
371
372 if( is_wpforo_multiboard() ){
373 $boards = WPF()->board->get_boards();
374 if(!empty($boards)){
375 foreach($boards as $board){
376 $board_paths[] = '/' . $board['slug'] . '/';
377 }
378 }
379 } else {
380 $board_paths[] = '/' . WPF()->board->get_current( 'slug' ) . '/';
381 }
382
383 $board_paths[] = '/' . wpforo_settings_get_slug('member') . '/';
384 $board_paths[] = '/' . wpforo_settings_get_slug('register') . '/';
385 $board_paths[] = '/' . wpforo_settings_get_slug('login') . '/';
386 $board_paths[] = '/' . wpforo_settings_get_slug('lostpassword') . '/';
387
388 if (function_exists("wpsc_init")) {
389 //WP Super Cache
390 $cache_plugins['WPSuper']['name'] = 'WP Super Cache';
391 $cache_plugins['WPSuper']['steps'][] = __('Please navigate in Dashboard to Settings > WP Super Cache', 'wpforo');
392 $cache_plugins['WPSuper']['steps'][] = __('Go to Advanced Tab, scroll down to "Rejected URL Strings" option', 'wpforo');
393 $cache_plugins['WPSuper']['steps'][] = __('Insert the URL path(s) of your forum page(s) one per line in the option textarea:', 'wpforo') . ' <br><code>' . implode('</code> <br> <code>', $board_paths) . '</code>';
394 $cache_plugins['WPSuper']['steps'][] = __('Save it and delete all caches.', 'wpforo');
395 }
396 if (defined("LSCWP_V")) {
397 //LiteSpeed Cache
398 $cache_plugins['LiteSpeed']['name'] = 'LiteSpeed Cache';
399 $cache_plugins['LiteSpeed']['steps'][] = __('Please navigate in Dashboard to LiteSpeed Cache > Cache admin page', 'wpforo');
400 $cache_plugins['LiteSpeed']['steps'][] = __('Go to Exclude Tab, find the "Do Not Cache URIs" option', 'wpforo');
401 $cache_plugins['LiteSpeed']['steps'][] = __('Insert the URL path(s) of your forum page(s) one per line in the option textarea:', 'wpforo') . ' <br><code>' . implode('</code> <br> <code>', $board_paths) . '</code>';
402 $cache_plugins['LiteSpeed']['steps'][] = __('Save it and delete all caches.', 'wpforo');
403 }
404 if (function_exists("rocket_clean_post")) {
405 //WP Rocket Cache
406 $cache_plugins['WPRocket']['name'] = 'WP Rocket Cache';
407 $cache_plugins['WPRocket']['steps'][] = __('Please navigate in Dashboard to WP Rocket > Advanced Rules Tab', 'wpforo');
408 $cache_plugins['WPRocket']['steps'][] = __('Scroll down to "Never cache (URLs)" option', 'wpforo');
409 $cache_plugins['WPRocket']['steps'][] = __('Insert the URL path(s) of your forum page(s) one per line with wildcard (.*) in the option textarea:', 'wpforo') . ' <br><code>' . implode('</code> <br> <code>', array_map( function ( $value ){ return $value . '(.*)'; }, $board_paths)) . '</code>';
410 $cache_plugins['WPRocket']['steps'][] = __('Save it and delete all caches.', 'wpforo');
411 }
412 if (function_exists("wpfc_clear_post_cache_by_id")) {
413 //WP Fastest Cache
414 $cache_plugins['WPFastest']['name'] = 'WP Fastest Cache';
415 $cache_plugins['WPFastest']['steps'][] = __('Please navigate in Dashboard to WP Fastest Cache > Exclude Tab', 'wpforo');
416 $cache_plugins['WPFastest']['steps'][] = __('In the "Exclude Pages" section click the [Add New Rule] button', 'wpforo');
417 $cache_plugins['WPFastest']['steps'][] = __('Select [Start with] option in the drop-down menu and insert the URL path(s) of your forum page(s) one per rule in the next field:', 'wpforo') . ' <br><code>' . implode('</code> <br> <code>', $board_paths) . '</code>';
418 $cache_plugins['WPFastest']['steps'][] = __('If you have more than one forum pages (boards) you should create separate rules for each forum board.', 'wpforo');
419 $cache_plugins['WPFastest']['steps'][] = __('Save rules and delete all caches.', 'wpforo');
420 }
421 if (function_exists("w3tc_flush_post")) {
422 //W3 Total Cache
423 $cache_plugins['W3Total']['name'] = 'W3 Total Cache';
424 $cache_plugins['W3Total']['steps'][] = __('Please navigate in Dashboard to Performance > Page Cache admin page', 'wpforo');
425 $cache_plugins['W3Total']['steps'][] = __('Go to Advanced Tab, scroll down to Rejected URL Strings option', 'wpforo');
426 $cache_plugins['W3Total']['steps'][] = __('Scroll to Advanced section and insert the URL path(s) of your forum page(s) one per line in the "Never cache the following pages" textarea:', 'wpforo') . ' <br><code>' . implode('</code> <br> <code>', $board_paths) . '</code>';
427 $cache_plugins['W3Total']['steps'][] = __('Save it and delete all caches.', 'wpforo');
428 }
429 if (is_callable(["WPO_Page_Cache", "delete_single_post_cache"])) {
430 //WP-Optimize Cache
431 $cache_plugins['WPOptimize']['name'] = 'WP-Optimize Cache';
432 $cache_plugins['WPOptimize']['steps'][] = __('Please navigate in Dashboard to WP-Optimize > Cache admin page', 'wpforo');
433 $cache_plugins['WPOptimize']['steps'][] = __('Go to Advanced Settings Tab, find the "URLs to exclude from caching" option', 'wpforo');
434 $cache_plugins['WPOptimize']['steps'][] = __('Insert the URL path(s) of your forum page(s) one per line with wildcard [*] in the option textarea:', 'wpforo') . ' <br><code>' . implode('</code> <br> <code>', array_map( function ( $value ){ return $value . '*'; }, $board_paths)) . '</code>';
435 $cache_plugins['WPOptimize']['steps'][] = __('Save it and delete all caches.', 'wpforo');
436 }
437 if (class_exists("\SiteGround_Optimizer\Supercacher\Supercacher")) {
438 //SiteGround Optimizer
439 $cache_plugins['SiteGround']['name'] = 'SiteGround Optimizer';
440 $cache_plugins['SiteGround']['steps'][] = __('Please navigate in Dashboard to SG Optimizer > Caching admin page', 'wpforo');
441 $cache_plugins['SiteGround']['steps'][] = __('Scroll to Exclude URLs from Caching section and click the "pencil" button, enable it, and click the button again', 'wpforo');
442 $cache_plugins['SiteGround']['steps'][] = __('Insert the URL path(s) of your forum page(s) with wildcard [*] in the pop-up filed:', 'wpforo') . ' <br><code>' . implode('</code> <br> <code>', array_map( function ( $value ){ return $value . '*'; }, $board_paths)) . '</code>';
443 $cache_plugins['SiteGround']['steps'][] = __('Save it and delete all caches.', 'wpforo');
444 }
445 return $cache_plugins;
446 }
447
448 public function cache_plugins_status(){
449 $not_exluded = [];
450 $cache_plugins = $this->cache_plugins();
451 $excluded = wpforo_get_option( 'wpforo_excluded_cache', null, false );
452 $excluded = explode(',', $excluded );
453 if( ! empty( $cache_plugins ) ){
454 foreach( $cache_plugins as $cache_plugin ){
455 if( ! in_array( $cache_plugin['name'], $excluded ) ){
456 $not_exluded[] = $cache_plugin;
457 }
458 }
459 }
460 return $not_exluded;
461 }
462
463 }
464