PluginProbe
wpForo Forum / 3.1.6
wpForo Forum v3.1.6
3.1.6 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 All 138 releases
wpforo / classes / Cache.php

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

617 lines 27.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 $dir = '';
12 public $locale = '';
13 public $special_key = '';
14 private $touched_postids = [];
15
16 function __construct() {
17 add_action( 'wpforo_after_init_folders', function( $folders ) {
18 $cache_dir = apply_filters('wpforo_cache_dir', $folders['cache']['dir'], $folders);
19 if( ! is_dir( $cache_dir ) ) $this->dir( $cache_dir );
20 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'tag' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'tag' );
21 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'tag' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'tag' );
22 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'url' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'url' );
23 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'avatar' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'avatar' );
24 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'reaction' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'reaction' );
25 if( ! is_dir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'option' ) ) $this->mkdir( $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'option' );
26
27 $this->dir = $cache_dir;
28 } );
29
30 if( apply_filters( 'wpforo_cache_by_usergroup', false ) ){
31 add_action( 'wpforo_after_init_current_user', function (){
32 $this->set_special_key();
33 } );
34 }
35
36 add_action( 'wpforo_after_set_locale', function( $locale ) {
37 $this->locale = $locale;
38 $this->set_special_key();
39 } );
40
41 add_action( 'wpforo_after_add_board', function( $board ){
42 if( $board['status'] ){
43 WPF()->change_board( $board['boardid'] );
44 wpforo_clean_cache();
45 }
46 } );
47
48 add_action( 'wpforo_after_edit_board', function( $boardid ){
49 $board = WPF()->board->_get_board( $boardid );
50 if( wpfval($board, 'status' ) ){
51 WPF()->change_board( $boardid );
52 wpforo_clean_cache();
53 }
54 } );
55
56 add_action( 'wpforo_after_add_reaction', [ $this, 'after_add_reaction' ] );
57 add_action( 'wpforo_after_edit_reaction', [ $this, 'after_edit_reaction' ] );
58 add_action( 'wpforo_before_delete_reaction', [ $this, 'before_delete_reaction' ], 10, 2 );
59 add_action( 'wpforo_after_delete_reaction', [ $this, 'after_delete_reaction' ] );
60 }
61
62 private function set_special_key(): void {
63 $this->special_key = (
64 apply_filters( 'wpforo_cache_by_usergroup', false )
65 ? implode( '-', WPF()->current_user_groupids ) . '-' : ''
66 ) . $this->locale;
67 }
68
69 public function get_key( $type = 'html' ) {
70 if( $type === 'html' ) {
71 $ug = WPF()->current_user_groupid;
72
73 return md5( preg_replace( '#(.+)\#.+?$#is', '$1', (string) $_SERVER['REQUEST_URI'] ) . $ug );
74 }
75 }
76
77 private function dir( $cache_dir ) {
78 $dirs = [
79 $cache_dir,
80 $cache_dir . DIRECTORY_SEPARATOR . 'forum',
81 $cache_dir . DIRECTORY_SEPARATOR . 'topic',
82 $cache_dir . DIRECTORY_SEPARATOR . 'post',
83 $cache_dir . DIRECTORY_SEPARATOR . 'tag',
84 $cache_dir . DIRECTORY_SEPARATOR . 'item',
85 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'forum',
86 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'topic',
87 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'post',
88 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'tag',
89 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'url',
90 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'avatar',
91 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'reaction',
92 $cache_dir . DIRECTORY_SEPARATOR . 'item' . DIRECTORY_SEPARATOR . 'option',
93 ];
94 $this->mkdir( $dirs );
95 }
96
97 private function mkdir( $dirs ) {
98 foreach( (array) $dirs as $dir ) {
99 wp_mkdir_p( $dir );
100 wpforo_write_file( $dir . '/index.html', '' );
101 wpforo_write_file( $dir . '/.htaccess', 'deny from all' );
102 }
103 }
104
105 public function on( $type = 'all' ){
106 if( $type !== 'all' ){
107 if( $type === 'forum' && !apply_filters( 'wpforo_cache_forum', true ) ) return false;
108 if( $type === 'topic' && !apply_filters( 'wpforo_cache_topic', true ) ) return false;
109 if( $type === 'post' && !apply_filters( 'wpforo_cache_post', true ) ) return false;
110 if( $type === 'tag' && !apply_filters( 'wpforo_cache_tag', true ) ) return false;
111 if( $type === 'url' && !apply_filters( 'wpforo_cache_url', true ) ) return false;
112 if( $type === 'reaction' && !apply_filters( 'wpforo_cache_reaction', true ) ) return false;
113 if( $type === 'avatar' && !apply_filters( 'wpforo_cache_avatar', true ) ) return false;
114 if( $type === 'option' && !apply_filters( 'wpforo_cache_option', true ) ) return false;
115 }
116 return wpforo_setting( 'board', 'cache' );
117 }
118
119 public function get( $key, $type = 'loop', $template = null ) {
120 $template = ( $template ) ?: WPF()->current_object['template'];
121 $loop_templates = [ 'forum', 'topic', 'post', 'tag' ];
122 if( $type === 'loop' && $template ) {
123 if( $this->exists( $key, $template ) ) {
124 if( in_array( $template, $loop_templates ) ) {
125 $cache_file = $this->dir . '/' . $template . '/' . $key;
126 $array = wpforo_get_file_content( $cache_file );
127
128 return @unserialize( $array, [ 'allowed_classes' => false ] );
129 }
130 }
131 }
132 }
133
134 public function get_item( $id, $type = 'post', $sub_type = '' ) {
135 if( $id ) {
136 $key = $id . '_' . $this->special_key;
137 $domain_path = preg_replace('|https?://|i', '', get_site_url() );
138 if( $this->exists( $key, 'item', $type, $sub_type ) ) {
139 $cache_file = $this->dir . '/item/' . $type . '/' . ( $sub_type ? $sub_type . '_' : '' ) . $key;
140 $array = wpforo_get_file_content( $cache_file );
141 $data = @unserialize( $array, [ 'allowed_classes' => false ] );
142 if( $type === 'url' ) {
143 // Always make sure the cached URLs are pointed to current website
144 if( strpos( (string) $data, $domain_path ) === FALSE ) return null;
145 }
146 return $data;
147 }
148 }
149 return null;
150 }
151
152 public function get_html() {
153 $template = WPF()->current_object['template'];
154 if( $template == 'forum' ) {
155 $key = $this->get_key();
156 if( $this->exists( $key, $template ) ) {
157 $cache_file = $this->dir . '/' . $template . '/' . $key;
158 $html = wpforo_get_file_content( $cache_file );
159
160 return $this->filter( $html );
161 }
162 }
163
164 return false;
165 }
166
167 public function html( $content ) {
168 /*$template = WPF()->current_object['template'];
169 if( $template === 'forum' ){
170 $key = $this->get_key();
171 $this->create_html( $content, $template, $key );
172 }*/
173 }
174
175 public function create( $mode = 'loop', $cache = [], $type = 'post' ) {
176 if( ! $this->on() ) return false;
177 $template = WPF()->current_object['template'];
178 if( $template == 'forum' ) {
179 $this->check( $this->dir . '/item/post' );
180 }
181
182 if( $mode === 'loop' && $template ) {
183 if( wpfval( $cache, 'tags' ) ) {
184 $this->create_files( $cache['tags'], 'tag' );
185 }
186 if( $template === 'forum' || $template === 'topic' || $template === 'post' ) {
187 $cache = WPF()->forum->get_cache( 'forums' );
188 $this->create_files( $cache, $template );
189 $cache = WPF()->topic->get_cache( 'topics' );
190 $this->create_files( $cache, $template );
191 $cache = WPF()->post->get_cache( 'posts' );
192 $this->create_files( $cache, $template );
193 }
194 } elseif( $mode === 'item' && ! empty( $cache ) ) {
195 $this->create_files( $cache, 'item', $type );
196 }
197 }
198
199 public function create_files( $cache = [], $template = '', $type = '' ) {
200 if( ! empty( $cache ) ) {
201 $type = ( $type ) ? $type . '/' : '';
202 foreach( $cache as $key => $object ) {
203 if( $template === 'item' ) $key = $key . '_' . $this->special_key;
204 if( ! $this->exists( $key, $template ) ) {
205 $object = serialize( $object );
206 wpforo_write_file( $this->dir . '/' . $template . '/' . $type . $key, $object );
207 }
208 }
209 }
210 }
211
212 public function create_html( $content, $template = '', $key = '' ) {
213 if( $content ) {
214 if( ! $this->exists( $key, $template ) ) {
215 wpforo_write_file( $this->dir . '/' . $template . '/' . $key, $content );
216 }
217 }
218 }
219
220 public function create_custom( $args = [], $items = [], $template = 'post', $items_count = 0 ) {
221 if( empty( $args ) || ! is_array( $args ) ) return;
222 if( empty( $items ) || ! is_array( $items ) ) return;
223 $cache = [];
224 $hach = serialize( $args );
225 $object_key = md5( $hach . WPF()->current_user_groupid );
226 $cache[ $object_key ]['items'] = $items;
227 $cache[ $object_key ]['items_count'] = $items_count;
228 $this->create_files( $cache, $template );
229 }
230
231 public function filter( $html = '' ) {
232 //exit();
233 $html = preg_replace( '|<div[\s\t]*id=\"wpf-msg-box\"|i', '<div style="display:none;"', (string) $html );
234
235 return $html;
236 }
237
238 #################################################################################
239
240 /**
241 * Cleans forum cache
242 *
243 * @param integer Item ID (e.g.: $topicid or $postid) | (!) ID is 0 on dome actions (e.g.: delete actions)
244 * @param string Item Type (e.g.: 'forum', 'topic', 'post', 'user', 'widget', etc...)
245 * @param array Item data as array
246 *
247 * @return void
248 * @since 1.2.1
249 *
250 */
251
252 public function clean( $id, $template, $item = [] ) {
253
254 $dirs = [];
255 $userid = ( isset( $item['userid'] ) && $item['userid'] ) ? $item['userid'] : 0;
256 $postid = ( isset( $item['postid'] ) && $item['postid'] ) ? $item['postid'] : 0;
257 $topicid = ( isset( $item['topicid'] ) && $item['topicid'] ) ? $item['topicid'] : 0;
258 $forumid = ( isset( $item['forumid'] ) && $item['forumid'] ) ? $item['forumid'] : 0;
259 $parentid = ( isset( $item['parentid'] ) && $item['parentid'] ) ? $item['parentid'] : 0;
260 $root = ( isset( $item['root'] ) && $item['root'] ) ? $item['root'] : 0;
261 $tagid = ( isset( $item['tagid'] ) && $item['tagid'] ) ? $item['tagid'] : 0;
262
263 if( isset( WPF()->forum ) && method_exists(WPF()->forum, 'reset') ) WPF()->forum->reset();
264 if( isset( WPF()->topic ) && method_exists(WPF()->topic, 'reset') ) WPF()->topic->reset();
265 if( isset( WPF()->post ) && method_exists(WPF()->post, 'reset') ) WPF()->post->reset();
266
267 if( $template === 'forum' || $template === 'forum-soft' ) {
268 $id = isset( $id ) ? $id : $forumid;
269 if( $template === 'forum' ) {
270 $dirs = [ $this->dir . '/forum', $this->dir . '/item/forum', $this->dir . '/item/url' ];
271 WPF()->seo->clear_cache();
272 }
273 if( $template === 'forum-soft' ) {
274 $dirs = [ $this->dir . '/forum' ];
275 }
276 if( $id ) {
277 $file = $this->dir . '/item/forum/' . $id . '_' . $this->special_key;
278 $this->clean_file( $file );
279 }
280 } elseif( $template === 'topic' || $template === 'topic-first-post' || $template === 'topic-soft' ) {
281 $id = isset( $id ) ? $id : $topicid;
282 if( $template === 'topic' || $template === 'topic-first-post' ) {
283 WPF()->seo->clear_cache();
284 $dirs = [ $this->dir . '/forum', $this->dir . '/topic', $this->dir . '/post' ];
285 }
286 if( $forumid ) {
287 $file = $this->dir . '/item/forum/' . $forumid . '_' . $this->special_key;
288 $this->clean_file( $file );
289 }
290 if( $id ) {
291 $file = $this->dir . '/item/topic/' . $id . '_' . $this->special_key;
292 $this->clean_file( $file );
293 $file = $this->dir . '/item/url/topic_' . $id . '_' . $this->special_key;
294 $this->clean_file( $file );
295 $postid = ( isset( $item['first_postid'] ) && $item['first_postid'] ) ? $item['first_postid'] : 0;
296 if( $postid ) $file = $this->dir . '/item/post/' . $postid . '_' . $this->special_key;
297 $this->clean_file( $file );
298 if( $template === 'topic' ) $this->clear_topic_posts_urls( $id );
299 }
300 WPF()->statistic_cache_clean();
301 $this->clear_visitor_tracking();
302 } elseif( $template === 'post' || $template === 'post-soft' ) {
303 $id = isset( $id ) ? $id : $postid;
304 if( $template === 'post' ) {
305 $dirs = [ $this->dir . '/forum', $this->dir . '/topic', $this->dir . '/post' ];
306 }
307 if( $forumid ) {
308 $file = $this->dir . '/item/forum/' . $forumid . '_' . $this->special_key;
309 $this->clean_file( $file );
310 }
311 if( $topicid ) {
312 $file = $this->dir . '/item/topic/' . $topicid . '_' . $this->special_key;
313 $this->clean_file( $file );
314 }
315 if( $parentid ) {
316 $file = $this->dir . '/item/post/' . $parentid . '_' . $this->special_key;
317 $this->clean_file( $file );
318 }
319 if( $root ) {
320 $file = $this->dir . '/item/post/' . $root . '_' . $this->special_key;
321 $this->clean_file( $file );
322 }
323 if( $id ) {
324 $file = $this->dir . '/item/post/' . $id . '_' . $this->special_key;
325 $this->clean_file( $file );
326 $file = $this->dir . '/item/url/post_' . $id . '_' . $this->special_key;
327 $this->clean_file( $file );
328 $this->clear_topic_next_posts_urls( $id, $topicid );
329 }
330 WPF()->statistic_cache_clean();
331 $this->clear_visitor_tracking();
332 } elseif( $template === 'tag' ) {
333 if( $id ) {
334 $file = $this->dir . '/item/tag/' . md5( $id ) . '_' . $this->special_key;
335 $this->clean_file( $file );
336 } else {
337 $dirs = [ $this->dir . '/tag' ];
338 }
339 } elseif( $template === 'option' ) {
340 $dirs = [ $this->dir . '/item/option' ];
341 } elseif( $template === 'url' ) {
342 $dirs = [ $this->dir . '/item/url' ];
343 } elseif( $template === 'avatar' ) {
344 if( $id ){
345 $file = $this->dir . '/item/avatar/' . $id . '_' . $this->special_key;
346 $this->clean_file( $file );
347 } else {
348 $dirs = [ $this->dir . '/item/avatar' ];
349 }
350 } elseif( $template === 'reaction' ) {
351 if( $id ){
352 $file = $this->dir . '/item/reaction/' . $id . '_' . $this->special_key;
353 $this->clean_file( $file );
354 $this->clean( $id, 'post' );
355 } else {
356 $dirs = [ $this->dir . '/item/reaction' ];
357 }
358 } elseif( $template === 'user' ) {
359 if( wpforo_setting( 'seo', 'seo_profile' ) ) WPF()->seo->clear_cache();
360 } elseif( $template === 'loop' ) {
361 $dirs = [ $this->dir . '/forum', $this->dir . '/topic', $this->dir . '/post' ];
362 WPF()->seo->clear_cache();
363 } elseif( $template === 'item' ) {
364 $dirs = [ $this->dir . '/item/post', $this->dir . '/item/topic', $this->dir . '/item/forum' ];
365 WPF()->seo->clear_cache();
366 } else {
367 $dirs = [
368 $this->dir . '/forum',
369 $this->dir . '/topic',
370 $this->dir . '/post',
371 $this->dir . '/tag',
372 $this->dir . '/item/post',
373 $this->dir . '/item/topic',
374 $this->dir . '/item/forum',
375 $this->dir . '/item/tag',
376 $this->dir . '/item/url',
377 $this->dir . '/item/avatar',
378 $this->dir . '/item/option',
379 //$this->dir . '/item/reaction',
380 ];
381 WPF()->seo->clear_cache();
382 }
383
384 if( ! empty( $dirs ) ) {
385 foreach( $dirs as $dir ) {
386 $this->clean_files( $dir );
387 }
388 }
389 }
390
391 public function clean_files( $directory ) {
392 $directory = (string) $directory;
393 $directory = wpforo_fix_dir_sep( $directory );
394 $directory_ns = trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*';
395 $directory_ws = DIRECTORY_SEPARATOR . trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*';
396 $glob = glob( $directory_ns );
397 if( empty( $glob ) ) $glob = glob( $directory_ws );
398 foreach( $glob as $item ) {
399 if( strpos( (string) $item, 'index.html' ) !== false || strpos( (string) $item, '.htaccess' ) !== false ) continue;
400 if( ! is_dir( $item ) && file_exists( $item ) ) {
401 @unlink( $item );
402 }
403 }
404 }
405
406 public function clean_file( $file ) {
407 if( ! is_dir( $file ) && file_exists( $file ) ) {
408 @unlink( $file );
409 }
410 }
411
412 public function clear_topic_posts_urls( $topicid ){
413 if( !$topicid ) return;
414 $post_ids = WPF()->db->get_results("SELECT `postid` FROM " . WPF()->tables->posts . " WHERE `topicid` = " . intval( $topicid ), ARRAY_A );
415 if( !empty( $post_ids ) ){
416 foreach( $post_ids as $post_id ){
417 $this->clean_file( $this->dir . '/item/post/' . $post_id['postid'] . '_' . $this->special_key );
418 $this->clean_file( $this->dir . '/item/url/post_' . $post_id['postid'] . '_' . $this->special_key );
419 }
420 }
421 }
422
423 public function clear_topic_next_posts_urls( $postid, $topicid ){
424 $topicid = ( $topicid ) ? : wpforo_post( $postid, 'topicid' );
425 $post_ids = WPF()->db->get_results("SELECT `postid` FROM " . WPF()->tables->posts . " WHERE `topicid` = " . intval( $topicid ) . " AND `postid` > " . intval( $postid ), ARRAY_A );
426 if( !empty( $post_ids ) ){
427 foreach( $post_ids as $post_id ){
428 $this->clean_file( $this->dir . '/item/post/' . $post_id['postid'] . '_' . $this->special_key );
429 $this->clean_file( $this->dir . '/item/url/post_' . $post_id['postid'] . '_' . $this->special_key );
430 }
431 }
432 }
433
434 public function exists( $key, $template, $type = '', $sub_type = '' ) {
435 $type = ( $type ) ? $type . '/' : '';
436 if( file_exists( $this->dir . '/' . $template . '/' . $type . ( $sub_type ? $sub_type . '_' : '' ) . $key ) ) {
437 return true;
438 } else {
439 return false;
440 }
441 }
442
443 public function check( $directory ) {
444 $directory = (string) $directory;
445 $directory = wpforo_fix_dir_sep( $directory );
446
447 if( ! class_exists( 'FilesystemIterator' ) || ! is_dir( $directory ) ) return;
448
449 $fi = new FilesystemIterator( $directory, FilesystemIterator::SKIP_DOTS );
450 $filecount = iterator_count( $fi );
451 if( ! $filecount ) return;
452
453 // Dynamic limit based on online members (scales with forum activity)
454 $stats = WPF()->statistic();
455 $online = max( 2, intval( $stats['online_members_count'] ) );
456 $max = $online * 500;
457 $max = max( 1000, min( $max, 50000 ) );
458
459 /**
460 * Filter the maximum cache files allowed per directory.
461 *
462 * @param int $max Maximum files (default: dynamic based on online users)
463 * @param string $directory The cache directory being checked
464 */
465 $max = (int) apply_filters( 'wpforo_cache_dir_max_files', $max, $directory );
466 if( $max === 0 ) return; // 0 = disable cache limit
467
468 if( $filecount > $max ) {
469 $this->clean_old_files( $directory, (int) ceil( $filecount * 0.5 ) );
470 }
471 }
472
473 private function clean_old_files( $directory, $delete_count ) {
474 $directory_ns = trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*';
475 $directory_ws = DIRECTORY_SEPARATOR . trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*';
476 $files = glob( $directory_ns );
477 if( empty( $files ) ) $files = glob( $directory_ws );
478 if( empty( $files ) ) return;
479
480 // Sort by modification time (oldest first)
481 usort( $files, function( $a, $b ) {
482 return filemtime( $a ) - filemtime( $b );
483 });
484
485 // Delete oldest 50%
486 foreach( array_slice( $files, 0, $delete_count ) as $file ) {
487 if( strpos( (string) $file, 'index.html' ) !== false || strpos( (string) $file, '.htaccess' ) !== false ) continue;
488 if( ! is_dir( $file ) && file_exists( $file ) ) @unlink( $file );
489 }
490 }
491
492 public function clear_visitor_tracking() {
493 $keep_vistors_data = apply_filters( 'wpforo_keep_visitors_data', 4000 );
494 $time = (int) time() - (int) $keep_vistors_data;
495 $online = (int) time() - (int) wpforo_setting( 'profiles', 'online_status_timeout' );
496 if( $time > 1 ) {
497 WPF()->db->query( "DELETE FROM `" . WPF()->tables->visits . "` WHERE `time` < " . intval( $time ) . " OR (`time` < " . intval( $online ) . " AND `userid` = 0)" );
498 }
499 }
500
501 public function cache_plugins(){
502 $board_paths = [];
503 $cache_plugins = [];
504
505 if( is_wpforo_multiboard() ){
506 $boards = WPF()->board->get_boards();
507 if(!empty($boards)){
508 foreach($boards as $board){
509 $board_paths[] = '/' . $board['slug'] . '/';
510 }
511 }
512 } else {
513 $board_paths[] = '/' . WPF()->board->get_current( 'slug' ) . '/';
514 }
515
516 $board_paths[] = '/' . wpforo_settings_get_slug('member') . '/';
517 $board_paths[] = '/' . wpforo_settings_get_slug('register') . '/';
518 $board_paths[] = '/' . wpforo_settings_get_slug('login') . '/';
519 $board_paths[] = '/' . wpforo_settings_get_slug('lostpassword') . '/';
520
521 if (function_exists("wpsc_init")) {
522 //WP Super Cache
523 $cache_plugins['WPSuper']['name'] = 'WP Super Cache';
524 $cache_plugins['WPSuper']['steps'][] = __('Please navigate in Dashboard to Settings > WP Super Cache', 'wpforo');
525 $cache_plugins['WPSuper']['steps'][] = __('Go to Advanced Tab, scroll down to "Rejected URL Strings" option', 'wpforo');
526 $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>';
527 $cache_plugins['WPSuper']['steps'][] = __('Save it and delete all caches.', 'wpforo');
528 }
529 if (defined("LSCWP_V")) {
530 //LiteSpeed Cache
531 $cache_plugins['LiteSpeed']['name'] = 'LiteSpeed Cache';
532 $cache_plugins['LiteSpeed']['steps'][] = __('Please navigate in Dashboard to LiteSpeed Cache > Cache admin page', 'wpforo');
533 $cache_plugins['LiteSpeed']['steps'][] = __('Go to Exclude Tab, find the "Do Not Cache URIs" option', 'wpforo');
534 $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>';
535 $cache_plugins['LiteSpeed']['steps'][] = __('Save it and delete all caches.', 'wpforo');
536 }
537 if (function_exists("rocket_clean_post")) {
538 //WP Rocket Cache
539 $cache_plugins['WPRocket']['name'] = 'WP Rocket Cache';
540 $cache_plugins['WPRocket']['steps'][] = __('Please navigate in Dashboard to WP Rocket > Advanced Rules Tab', 'wpforo');
541 $cache_plugins['WPRocket']['steps'][] = __('Scroll down to "Never cache (URLs)" option', 'wpforo');
542 $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>';
543 $cache_plugins['WPRocket']['steps'][] = __('Save it and delete all caches.', 'wpforo');
544 }
545 if (function_exists("wpfc_clear_post_cache_by_id")) {
546 //WP Fastest Cache
547 $cache_plugins['WPFastest']['name'] = 'WP Fastest Cache';
548 $cache_plugins['WPFastest']['steps'][] = __('Please navigate in Dashboard to WP Fastest Cache > Exclude Tab', 'wpforo');
549 $cache_plugins['WPFastest']['steps'][] = __('In the "Exclude Pages" section click the [Add New Rule] button', 'wpforo');
550 $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>';
551 $cache_plugins['WPFastest']['steps'][] = __('If you have more than one forum pages (boards) you should create separate rules for each forum board.', 'wpforo');
552 $cache_plugins['WPFastest']['steps'][] = __('Save rules and delete all caches.', 'wpforo');
553 }
554 if (function_exists("w3tc_flush_post")) {
555 //W3 Total Cache
556 $cache_plugins['W3Total']['name'] = 'W3 Total Cache';
557 $cache_plugins['W3Total']['steps'][] = __('Please navigate in Dashboard to Performance > Page Cache admin page', 'wpforo');
558 $cache_plugins['W3Total']['steps'][] = __('Go to Advanced Tab, scroll down to Rejected URL Strings option', 'wpforo');
559 $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>';
560 $cache_plugins['W3Total']['steps'][] = __('Save it and delete all caches.', 'wpforo');
561 }
562 if (is_callable(["WPO_Page_Cache", "delete_single_post_cache"])) {
563 //WP-Optimize Cache
564 $cache_plugins['WPOptimize']['name'] = 'WP-Optimize Cache';
565 $cache_plugins['WPOptimize']['steps'][] = __('Please navigate in Dashboard to WP-Optimize > Cache admin page', 'wpforo');
566 $cache_plugins['WPOptimize']['steps'][] = __('Go to Advanced Settings Tab, find the "URLs to exclude from caching" option', 'wpforo');
567 $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>';
568 $cache_plugins['WPOptimize']['steps'][] = __('Save it and delete all caches.', 'wpforo');
569 }
570 if (class_exists("\SiteGround_Optimizer\Supercacher\Supercacher")) {
571 //SiteGround Optimizer
572 $cache_plugins['SiteGround']['name'] = 'SiteGround Optimizer';
573 $cache_plugins['SiteGround']['steps'][] = __('Please navigate in Dashboard to SG Optimizer > Caching admin page', 'wpforo');
574 $cache_plugins['SiteGround']['steps'][] = __('Scroll to Exclude URLs from Caching section and click the "pencil" button, enable it, and click the button again', 'wpforo');
575 $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>';
576 $cache_plugins['SiteGround']['steps'][] = __('Save it and delete all caches.', 'wpforo');
577 }
578 return $cache_plugins;
579 }
580
581 public function cache_plugins_status(){
582 $not_exluded = [];
583 $cache_plugins = $this->cache_plugins();
584 $excluded = wpforo_get_option( 'wpforo_excluded_cache', '', false );
585 $excluded = explode(',', $excluded );
586 if( ! empty( $cache_plugins ) ){
587 foreach( $cache_plugins as $cache_plugin ){
588 if( ! in_array( $cache_plugin['name'], $excluded ) ){
589 $not_exluded[] = $cache_plugin;
590 }
591 }
592 }
593 return $not_exluded;
594 }
595
596 public function after_add_reaction( $reaction ) {
597 if( wpfval( $reaction, 'postid' ) ) {
598 WPF()->reaction->create_reaction_cache( $reaction['postid'] );
599 }
600 }
601
602 public function after_edit_reaction( $fields ) {
603 if( wpfval( $fields, 'postid' ) ) {
604 wpforo_clean_cache( 'reaction', $fields['postid'] );
605 }
606 }
607
608 public function before_delete_reaction( $args, $operator ) {
609 $this->touched_postids = WPF()->reaction->_get_reactions_col( 'postid', $args, $operator );
610 }
611
612 public function after_delete_reaction(){
613 foreach( array_unique(array_filter( $this->touched_postids )) as $postid ) wpforo_clean_cache( 'reaction', $postid );
614 }
615
616 }
617