| @@ -124,9 +124,9 @@ | ||
| 124 | 124 | if( in_array( $template, $loop_templates ) ) { |
| 125 | 125 | $cache_file = $this->dir . '/' . $template . '/' . $key; |
| 126 | 126 | $array = wpforo_get_file_content( $cache_file ); |
| 127 | 127 | |
| 128 | - return @unserialize( $array ); | |
| 128 | + return @unserialize( $array, [ 'allowed_classes' => false ] ); | |
| 129 | 129 | } |
| 130 | 130 | } |
| 131 | 131 | } |
| 132 | 132 | } |
| @@ -137,9 +137,9 @@ | ||
| 137 | 137 | $domain_path = preg_replace('|https?://|i', '', get_site_url() ); |
| 138 | 138 | if( $this->exists( $key, 'item', $type, $sub_type ) ) { |
| 139 | 139 | $cache_file = $this->dir . '/item/' . $type . '/' . ( $sub_type ? $sub_type . '_' : '' ) . $key; |
| 140 | 140 | $array = wpforo_get_file_content( $cache_file ); |
| 141 | - $data = @unserialize( $array ); | |
| 141 | + $data = @unserialize( $array, [ 'allowed_classes' => false ] ); | |
| 142 | 142 | if( $type === 'url' ) { |
| 143 | 143 | // Always make sure the cached URLs are pointed to current website |
| 144 | 144 | if( strpos( (string) $data, $domain_path ) === FALSE ) return null; |
| 145 | 145 | } |
| @@ -442,22 +442,51 @@ | ||
| 442 | 442 | |
| 443 | 443 | public function check( $directory ) { |
| 444 | 444 | $directory = (string) $directory; |
| 445 | 445 | $directory = wpforo_fix_dir_sep( $directory ); |
| 446 | - $filecount = 0; | |
| 447 | - if( class_exists( 'FilesystemIterator' ) && is_dir( $directory ) ) { | |
| 448 | - $fi = new FilesystemIterator( $directory, FilesystemIterator::SKIP_DOTS ); | |
| 449 | - $filecount = iterator_count( $fi ); | |
| 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 ) ); | |
| 450 | 470 | } |
| 451 | - if( ! $filecount ) { | |
| 452 | - $directory_ns = trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*'; | |
| 453 | - $directory_ws = DIRECTORY_SEPARATOR . trim( $directory, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . '*'; | |
| 454 | - $files = glob( $directory_ns ); | |
| 455 | - if( empty( $files ) ) $files = glob( $directory_ws ); | |
| 456 | - $filecount = count( $files ); | |
| 457 | - } | |
| 458 | - if( $filecount > 1000 ) { | |
| 459 | - $this->clean_files( $directory ); | |
| 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 ); | |
| 460 | 489 | } |
| 461 | 490 | } |
| 462 | 491 | |
| 463 | 492 | public function clear_visitor_tracking() { |