PluginProbe
WPSSO Core – Complete Schema Markup and Meta Tags / 22.7.0
WPSSO Core – Complete Schema Markup and Meta Tags v22.7.0
22.7.0 22.6.1 22.6.0 22.5.3 22.5.2 22.5.1 22.4.0 22.3.0 22.2.1 22.2.0 22.1.3 22.1.2 22.1.1 22.1.0 22.0.0 21.13.3 21.13.2 trunk 21.13.1
← All changes | lib/util-cache.php +1307 -0 22.4.022.7.0 View file →
@@ -1,0 +1,1307 @@
1 +<?php
2 +/*
3 + * License: GPLv3
4 + * License URI: https://www.gnu.org/licenses/gpl.txt
5 + * Copyright 2012-2026 Jean-Sebastien Morisset (https://wpsso.com/)
6 + */
7 +
8 +if ( ! defined( 'ABSPATH' ) ) {
9 +
10 + die( 'These aren\'t the droids you\'re looking for.' );
11 +}
12 +
13 +if ( ! defined( 'WPSSO_PLUGINDIR' ) ) {
14 +
15 + die( 'Do. Or do not. There is no try.' );
16 +}
17 +
18 +if ( ! class_exists( 'WpssoUtilCache' ) ) {
19 +
20 + class WpssoUtilCache {
21 +
22 + private $p; // Wpsso class object.
23 + private $u; // WpssoUtil class object.
24 +
25 + /*
26 + * Instantiated by WpssoUtil->__construct().
27 + */
28 + public function __construct( &$plugin, &$util ) {
29 +
30 + $this->p =& $plugin;
31 + $this->u =& $util;
32 +
33 + if ( $this->p->debug->enabled ) {
34 +
35 + $this->p->debug->mark();
36 + }
37 +
38 + add_action( 'wp_scheduled_delete', array( $this, 'clear_cache_files_expired' ) );
39 +
40 + add_action( 'wpsso_refresh_cache', array( $this, 'refresh' ), 10, 2 ); // Single scheduled task.
41 +
42 + if ( $this->is_disabled() ) {
43 +
44 + if ( $this->p->debug->enabled ) {
45 +
46 + $this->p->debug->log( 'plugin cache for head markup, xml feeds, and file content is disabled' );
47 + }
48 +
49 + $this->u->add_plugin_filters( $this, array(
50 + 'cache_expire_head_markup' => '__return_zero', // Used by WpssoHead->get_head_array().
51 + 'cache_expire_cmcf_feed_xml' => '__return_zero', // Used by WpssoCmcfXml->get().
52 + 'cache_expire_gmf_feed_xml' => '__return_zero', // Used by WpssoGmfXml->get().
53 + 'cache_expire_gmf_inventory_xml' => '__return_zero', // Used by WpssoGmfXml->get().
54 + 'cache_expire_file_content' => '__return_zero',
55 + ), -1000 );
56 +
57 + } else {
58 +
59 + if ( $this->p->debug->enabled ) {
60 +
61 + $this->p->debug->log( 'plugin cache for head markup, xml feeds, and file content is enabled' );
62 + }
63 +
64 + if ( ! empty( $this->p->options[ 'plugin_page_cache_active' ] ) ) {
65 +
66 + if ( $this->p->debug->enabled ) {
67 +
68 + $this->p->debug->log( 'plugin_page_cache_active option is true' );
69 + $this->p->debug->log( 'head markup cache is disabled' );
70 + }
71 +
72 + $this->u->add_plugin_filters( $this, array(
73 + 'cache_expire_head_markup' => '__return_hour_in_seconds', // Used by WpssoHead->get_head_array().
74 + ), -1000 );
75 +
76 + } else {
77 +
78 + if ( $this->p->debug->enabled ) {
79 +
80 + $this->p->debug->log( 'plugin_page_cache_active option is false' );
81 + $this->p->debug->log( 'head markup cache is enabled' );
82 + }
83 + }
84 + }
85 + }
86 +
87 + /*
88 + * The WPSSO_CACHE_DISABLE constant is true or the 'plugin_cache_disable' option is checked.
89 + *
90 + * See Wpsso->debug_reminder().
91 + * See WpssoUtilCache->__construct().
92 + */
93 + public function is_disabled() {
94 +
95 + if ( defined( 'WPSSO_CACHE_DISABLE' ) ) {
96 +
97 + $is_disabled = WPSSO_CACHE_DISABLE ? true : false;
98 +
99 + if ( $this->p->debug->enabled ) {
100 +
101 + $this->p->debug->log( 'WPSSO_CACHE_DISABLE defined and is ' . SucomUtil::get_bool_string( $is_disabled ) );
102 + }
103 +
104 + } else {
105 +
106 + $is_disabled = empty( $this->p->options[ 'plugin_cache_disable' ] ) ? false : true;
107 +
108 + if ( $this->p->debug->enabled ) {
109 +
110 + $this->p->debug->log( 'WPSSO_CACHE_DISABLE is not defined' );
111 +
112 + $this->p->debug->log( 'plugin_cache_disable option is ' . SucomUtil::get_bool_string( $is_disabled ) );
113 + }
114 + }
115 +
116 + return $is_disabled;
117 + }
118 +
119 + public function show_admin_notices() {
120 +
121 + if ( $this->p->debug->enabled ) {
122 +
123 + $this->p->debug->mark();
124 + }
125 +
126 + $user_id = get_current_user_id(); // Always returns an integer.
127 +
128 + if ( ! $this->show_refresh_running( $user_id ) ) {
129 +
130 + $this->show_refresh_pending( $user_id );
131 + }
132 + }
133 +
134 + /*
135 + * See WpssoCmcfRewrite::template_redirect().
136 + * See WpssoCmcfSubmenuGmfGeneral->add_form_buttons().
137 + * See WpssoCmcfSubmenuGmfGeneral->get_table_rows().
138 + * See WpssoGmfRewrite::template_redirect().
139 + * See WpssoGmfSubmenuGmfGeneral->add_form_buttons().
140 + * See WpssoGmfSubmenuGmfGeneral->get_table_rows().
141 + */
142 + public function is_refresh_running() {
143 +
144 + if ( $this->p->debug->enabled ) {
145 +
146 + $this->p->debug->mark();
147 + }
148 +
149 + $task_name = 'refresh the cache';
150 + $running_task = $this->get_running_task( $task_name, WPSSO_CACHE_REFRESH_MAX_TIME ); // Returns false or an array.
151 +
152 + return isset( $running_task[ 'user_id' ] ) ? true : false;
153 + }
154 +
155 + /*
156 + * See WpssoUtilCache->show_admin_notices().
157 + */
158 + public function show_refresh_running( $user_id = null ) {
159 +
160 + if ( $this->p->debug->enabled ) {
161 +
162 + $this->p->debug->mark();
163 + }
164 +
165 + $task_name = 'refresh the cache';
166 + $running_task = $this->get_running_task( $task_name, WPSSO_CACHE_REFRESH_MAX_TIME ); // Returns false or an array.
167 +
168 + if ( isset( $running_task[ 'user_id' ] ) ) { // Task is running.
169 +
170 + /*
171 + * Show the cache refresh status to the user who started the cache refresh.
172 + */
173 + $user_id = $this->u->maybe_change_user_id( $user_id ); // Maybe change textdomain for user ID.
174 +
175 + if ( $user_id === $running_task[ 'user_id' ] ) {
176 +
177 + $task_name_transl = _x( $task_name, 'task name', 'wpsso' );
178 + $notice_msg = sprintf( __( 'A task to %s is currently running.', 'wpsso' ), $task_name_transl ) . ' ';
179 + $notice_key = $task_name . '-task-info';
180 +
181 + if ( ! empty( $running_task[ 'task_info_transl' ] ) ) { // Null or string.
182 +
183 + $notice_msg .= $running_task[ 'task_info_transl' ] . ' ';
184 + }
185 +
186 + $this->p->notice->inf( $notice_msg, $user_id, $notice_key );
187 + }
188 +
189 + return true;
190 + }
191 +
192 + return false;
193 + }
194 +
195 + /*
196 + * See WpssoUtilCache->show_admin_notices().
197 + */
198 + public function show_refresh_pending( $user_id = null ) {
199 +
200 + if ( $this->p->debug->enabled ) {
201 +
202 + $this->p->debug->mark();
203 + }
204 +
205 + $event_hook = 'wpsso_refresh_cache';
206 + $crons = _get_cron_array();
207 +
208 + if ( ! is_array( $crons ) ) { // Just in case.
209 +
210 + return;
211 + }
212 +
213 + foreach ( $crons as $timestamp => $cron_hooks ) {
214 +
215 + if ( ! is_array( $cron_hooks ) ) { // Just in case.
216 +
217 + continue;
218 + }
219 +
220 + foreach ( $cron_hooks as $cron_hook => $hook_args ) {
221 +
222 + if ( ! is_array( $hook_args ) ) { // Just in case.
223 +
224 + continue;
225 +
226 + } elseif ( $event_hook !== $cron_hook ) { // Only check our own event hook.
227 +
228 + continue;
229 + }
230 +
231 + if ( $this->p->debug->enabled ) {
232 +
233 + $this->p->debug->log( 'event hook ' . $event_hook . ' found' );
234 +
235 + $this->p->debug->log_arr( 'hook_args', $hook_args );
236 + }
237 +
238 + /*
239 + * The $hook_key value is a checksum of the $hook_arr.
240 + *
241 + * The same task could be scheduled several times provided the $hook_arr elements are different.
242 + */
243 + foreach ( $hook_args as $hook_key => $hook_arr ) {
244 +
245 + if ( ! is_array( $hook_arr ) ) { // Just in case.
246 +
247 + continue;
248 + }
249 +
250 + $user_id = $this->u->maybe_change_user_id( $user_id ); // Maybe change textdomain for user ID.
251 + $task_name = 'refresh the cache';
252 + $task_name_transl = _x( 'refresh the cache', 'task name', 'wpsso' );
253 + $time_now = time();
254 + $human_time = human_time_diff( $time_now, $timestamp );
255 + $notice_key = $task_name . '-task-info';
256 + $event_args = $hook_arr[ 'args' ];
257 +
258 + if ( $time_now < $timestamp ) {
259 +
260 + if ( $this->p->debug->enabled ) {
261 +
262 + $this->p->debug->log( 'task to ' . $task_name . ' for user id ' . $event_args[ 0 ] .
263 + ' scheduled to start in ' . $human_time );
264 + }
265 +
266 + if ( $user_id === $event_args[ 0 ] ) {
267 +
268 + $notice_msg = sprintf( __( 'A background task will begin in %1$s to %2$s for posts, terms and users.',
269 + 'wpsso' ), $human_time, $task_name_transl );
270 +
271 + $this->p->notice->inf( $notice_msg, $user_id, $notice_key );
272 + }
273 +
274 + continue; // Get the next $hook_args.
275 + }
276 +
277 + if ( $this->p->debug->enabled ) {
278 +
279 + $this->p->debug->log( 'task to ' . $task_name . ' for user id ' . $event_args[ 0 ] .
280 + ' was scheduled to start ' . $human_time . ' ago' );
281 + }
282 +
283 + if ( $time_now > $timestamp + 60 && $user_id === $event_args[ 0 ] ) { // Add a 60 second buffer.
284 +
285 + $notice_msg = sprintf( __( 'A background task was scheduled to begin %1$s ago to %2$s for posts, terms and users.',
286 + 'wpsso' ), $human_time, $task_name_transl ) . ' ';
287 +
288 + $notice_msg .= sprintf( __( 'WordPress should have run the %s event hook at that time.',
289 + 'wpsso' ), '<code>' . $event_hook . '</code>' ) . ' ';
290 +
291 + $notice_msg .= sprintf( __( 'If the task does not run, this could indicate a problem with your hosting provider\'s event scheduler and/or a lack of support for the WordPress %s function.', 'wpsso' ), '<code>wp_schedule_single_event()</code>' ) . ' ';
292 +
293 + $notice_msg .= sprintf( __( 'You can activate a plugin like %s to manage scheduled events.',
294 + 'wpsso' ), '<a href="https://wordpress.org/plugins/wp-crontrol/">' .
295 + esc_html__( 'WP Crontrol', 'wp-crontrol' ) . '</a>' ) . ' ';
296 +
297 + $this->p->notice->warn( $notice_msg, $user_id, $notice_key );
298 + }
299 +
300 + } // End of $hook_args loop.
301 +
302 + return true; // Found one or more $event_hook.
303 +
304 + } // End of $cron_hooks loop.
305 +
306 + } // End of $crons loop.
307 +
308 + if ( $this->p->debug->enabled ) {
309 +
310 + $this->p->debug->log( 'event hook ' . $event_hook . ' not found' );
311 + }
312 +
313 + return false;
314 + }
315 +
316 + /*
317 + * See WpssoAdmin->activated_plugin().
318 + * See WpssoAdmin->wp_site_option_changed().
319 + * See WpssoAdmin->load_settings_page().
320 + * See WpssoOptions->save_options().
321 + * See WpssoRegister->activate_plugin().
322 + */
323 + public function schedule_refresh( $user_id = null, $clear_plugins = true ) {
324 +
325 + if ( $this->p->debug->enabled ) {
326 +
327 + $this->p->debug->mark();
328 + }
329 +
330 + $user_id = $this->u->maybe_change_user_id( $user_id ); // Maybe change textdomain for user ID.
331 + $task_name = 'refresh the cache';
332 + $task_name_transl = _x( 'refresh the cache', 'task name', 'wpsso' );
333 + $event_time = time() + WPSSO_SCHEDULE_SINGLE_EVENT_TIME; // Default event time is now + 10 seconds.
334 + $human_time = human_time_diff( 0, WPSSO_SCHEDULE_SINGLE_EVENT_TIME );
335 + $event_hook = 'wpsso_refresh_cache';
336 + $event_args = array( $user_id, $clear_plugins );
337 +
338 + if ( $user_id ) { // Just in case.
339 +
340 + $notice_msg = sprintf( __( 'A background task will begin in %1$s to %2$s for posts, terms and users.', 'wpsso' ),
341 + $human_time, $task_name_transl );
342 +
343 + $notice_key = $task_name . '-task-info';
344 +
345 + $this->p->notice->inf( $notice_msg, $user_id, $notice_key );
346 + }
347 +
348 + wp_schedule_single_event( $event_time, $event_hook, $event_args );
349 +
350 + do_action( 'wpsso_cache_refresh_scheduled', $event_time, $event_hook, $event_args );
351 + }
352 +
353 + /*
354 + * Called by the 'wpsso_refresh_cache' single scheduled event action.
355 + *
356 + * See wpsso_refresh_cache().
357 + * See WpssoRarActions->action_refresh_cache().
358 + */
359 + public function refresh( $user_id = null, $clear_plugins = true ) {
360 +
361 + if ( $this->p->debug->enabled ) {
362 +
363 + $this->p->debug->mark();
364 + }
365 +
366 + $user_id = $this->u->maybe_change_user_id( $user_id ); // Maybe change textdomain for user ID.
367 + $task_name = 'refresh the cache';
368 + $task_name_transl = _x( 'refresh the cache', 'task name', 'wpsso' );
369 +
370 + if ( ! $this->task_start( $user_id, $task_name, WPSSO_CACHE_REFRESH_MAX_TIME ) ) {
371 +
372 + return; // Stop here - background task already running.
373 + }
374 +
375 + if ( $user_id ) {
376 +
377 + $mtime_start = microtime( $get_float = true );
378 + $time_on_date = SucomUtil::sprintf_date_time( _x( '%2$s on %1$s', 'time on date', 'wpsso' ) );
379 + $notice_msg = sprintf( __( 'A task to %1$s was started at %2$s.', 'wpsso' ), $task_name_transl, $time_on_date );
380 + $notice_key = $task_name . '-task-info';
381 +
382 + $this->p->notice->inf( $notice_msg, $user_id, $notice_key );
383 + }
384 +
385 + if ( 0 === get_current_user_id() ) { // User is the scheduler.
386 +
387 + /*
388 + * Leave a few minutes for 'wpsso_cache_refreshed_notice' filters.
389 + */
390 + $other_refresh = SucomUtilWP::get_filter_hook_ids( 'wpsso_cache_refreshed_notice' );
391 + $max_time_secs = WPSSO_CACHE_REFRESH_MAX_TIME + ( 300 * count( $other_refresh ) );
392 +
393 + $this->set_task_limit( $user_id, $task_name, $max_time_secs );
394 + }
395 +
396 + if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
397 +
398 + /*
399 + * Register image sizes and include WooCommerce front-end libs.
400 + *
401 + * See WpssoIntegEcomWooCommerce->action_scheduled_task_started().
402 + * See WpssoUtil->action_scheduled_task_started().
403 + */
404 + do_action( 'wpsso_scheduled_task_started', $user_id );
405 + }
406 +
407 + /*
408 + * Clear cache files but preserve HTML files, like the YouTube video webpage HTML.
409 + */
410 + $this->clear_cache_files( $file_exp_secs = null, $include = array( '/\.(css|js|txt)$/' ) );
411 +
412 + /*
413 + * Refresh the Schema types transient cache.
414 + */
415 + $this->p->schema->refresh_schema_types();
416 +
417 + /*
418 + * Refresh the minimized notice stylesheet.
419 + */
420 + $this->p->notice->refresh_notice_style();
421 +
422 + /*
423 + * Refresh the cache for each public post, term, and user ID.
424 + */
425 + $total_count = array(
426 + 'post' => 0,
427 + 'term' => 0,
428 + 'user' => 0,
429 + );
430 +
431 + $notice_msg = '';
432 + $og_type_key = WpssoAbstractWpMeta::get_column_meta_keys( 'og_type' ); // Example: '_wpsso_head_info_og_type'.
433 + $abort_time = time() + WPSSO_CACHE_REFRESH_MAX_TIME; // 30 mins by default.
434 +
435 + foreach ( $total_count as $obj_name => &$count ) {
436 +
437 + /*
438 + * Refresh post, term, and user IDs with missing cache metadata first.
439 + */
440 + $prio_args = array(
441 + 'meta_query' => array(
442 + 'relation' => 'AND',
443 + array(
444 + 'key' => $og_type_key,
445 + 'compare' => 'NOT EXISTS',
446 + ),
447 + ),
448 + );
449 +
450 + $prio_ids = call_user_func( array( 'wpsso' . $obj_name, 'get_public_ids' ), $prio_args );
451 + $obj_ids = call_user_func( array( 'wpsso' . $obj_name, 'get_public_ids' ) );
452 +
453 + if ( ! empty( $prio_ids ) ) {
454 +
455 + $obj_ids = array_unique( $prio_ids + $obj_ids );
456 + }
457 +
458 + unset( $prio_args, $prio_ids );
459 +
460 + $obj_count = count( $obj_ids );
461 +
462 + foreach ( $obj_ids as $obj_num => $obj_id ) {
463 +
464 + $mod = $this->p->$obj_name->get_mod( $obj_id );
465 +
466 + $this->task_update( $task_name, sprintf( __( 'Processing %1$s ID #%2$d (%1$s %3$d of %4$d).', 'wpsso' ),
467 + $mod[ 'name_transl' ], $obj_id, $obj_num + 1, $obj_count ) );
468 +
469 + $this->refresh_mod_head_meta( $mod );
470 +
471 + $count++; // Reference to post, term, or user total count.
472 +
473 + if ( time() > $abort_time ) {
474 +
475 + $notice_msg .= sprintf( __( 'The cache refresh time limit of %s has been reached.', 'wpsso' ),
476 + human_time_diff( 0, WPSSO_CACHE_REFRESH_MAX_TIME ) ) . ' '; // 30 mins by default.
477 +
478 + $notice_msg .= sprintf( __( 'The cache refresh task aborted after %1$s ID #%2$d (%1$s %3$d of %4$d).', 'wpsso' ),
479 + $mod[ 'name_transl' ], $obj_id, $obj_num + 1, $obj_count ) . ' ';
480 +
481 + $error_pre = sprintf( __( '%s warning:', 'wpsso' ), __METHOD__ );
482 +
483 + SucomUtil::safe_error_log( $error_pre . ' ' . $notice_msg );
484 +
485 + break 2; // Stop here
486 + }
487 + }
488 + }
489 +
490 + unset( $mod, $obj_ids, $obj_id, $obj_num, $obj_count );
491 +
492 + $this->task_update( $task_name );
493 +
494 + /*
495 + * Create a notification for the end of this task.
496 + */
497 + $notice_msg .= sprintf( __( 'The transient cache for %1$d posts, %2$d terms, and %3$d users has been refreshed.',
498 + 'wpsso' ), $total_count[ 'post' ], $total_count[ 'term' ], $total_count[ 'user' ] ) . ' ';
499 +
500 + /*
501 + * The 'wpsso_cache_refreshed_notice' filter allows add-ons to execute additional refresh tasks and append
502 + * a notice message.
503 + *
504 + * See WpssoCmcfFilters->filter_cache_refreshed_notice().
505 + * See WpssoGmfFilters->filter_cache_refreshed_notice().
506 + */
507 + $notice_msg = trim( apply_filters( 'wpsso_cache_refreshed_notice', $notice_msg, $user_id ) ) . ' ';
508 +
509 + /*
510 + * Clear WP cache and known cache plugins.
511 + */
512 + $notice_msg .= $this->clear_cache( $clear_plugins );
513 +
514 + if ( $user_id && $notice_msg ) {
515 +
516 + $mtime_total = microtime( $get_float = true ) - $mtime_start;
517 + $human_time = human_time_diff( 0, $mtime_total );
518 + $human_mem = SucomUtil::format_human_bytes( memory_get_peak_usage(), $dec = 2 );
519 + $notice_msg .= sprintf( __( 'The total execution time for this task was %s (%s peak memory use).', 'wpsso' ), $human_time, $human_mem ) . ' ';
520 + $notice_key = $task_name . '-task-info';
521 +
522 + $this->p->notice->inf( $notice_msg, $user_id, $notice_key );
523 + }
524 +
525 + $this->task_end( $user_id, $task_name );
526 + }
527 +
528 + /*
529 + * See WpssoPost->after_insert_post().
530 + * See WpssoPost->ajax_get_metabox_sso().
531 + * See WpssoPost->load_meta_page().
532 + * See WpssoPost->refresh_cache().
533 + * See WpssoTerm->load_meta_page().
534 + * See WpssoTerm->refresh_cache().
535 + * See WpssoUser->load_meta_page().
536 + * See WpssoUser->refresh_cache().
537 + */
538 + public function refresh_mod_head_meta( array $mod ) {
539 +
540 + if ( $this->p->debug->enabled ) {
541 +
542 + $this->p->debug->mark();
543 + }
544 +
545 + $use_post = 'post' === $mod[ 'name' ] ? $mod[ 'id' ] : false;
546 + $head_tags = $this->p->head->get_head_array( $use_post, $mod, $read_cache = false );
547 + $head_info = $this->p->head->extract_head_info( $head_tags, $mod );
548 +
549 + return array( $head_tags, $head_info );
550 + }
551 +
552 + /*
553 + * See WpssoUser->add_person_role().
554 + * See WpssoUtilCache->refresh().
555 + */
556 + public function task_start( $user_id, $task_name, $cache_exp_secs ) {
557 +
558 + if ( $this->p->debug->enabled ) {
559 +
560 + $this->p->debug->mark();
561 + }
562 +
563 + $running_task = $this->get_running_task( $task_name, $cache_exp_secs ); // Returns false or an array.
564 +
565 + if ( isset( $running_task[ 'user_id' ] ) ) { // Task is running.
566 +
567 + $task_name_transl = _x( $task_name, 'task name', 'wpsso' );
568 + $notice_msg = sprintf( __( 'Ignoring request to %s - this task is already running.', 'wpsso' ), $task_name_transl );
569 + $notice_key = $task_name . '-task-ignored';
570 +
571 + $this->p->notice->warn( $notice_msg, $user_id, $notice_key );
572 +
573 + return false;
574 + }
575 +
576 + $task_cache_id = $this->get_task_cache_id( $task_name );
577 +
578 + return set_transient( $task_cache_id, array(
579 + 'user_id' => $user_id,
580 + 'task_name' => $task_name,
581 + 'task_start' => time(),
582 + 'task_limit' => time() + $cache_exp_secs,
583 + ), $cache_exp_secs );
584 +
585 + return true;
586 + }
587 +
588 + public function get_running_task( $task_name, $cache_exp_secs = null ) {
589 +
590 + if ( $this->p->debug->enabled ) {
591 +
592 + $this->p->debug->mark();
593 + }
594 +
595 + $task_cache_id = $this->get_task_cache_id( $task_name );
596 + $running_task = get_transient( $task_cache_id );
597 +
598 + if ( is_array( $running_task ) ) {
599 +
600 + if ( isset( $running_task[ 'user_id' ] ) ) { // Just in case.
601 +
602 + if ( null !== $cache_exp_secs ) { // Check that transient is not expired.
603 +
604 + if ( ! empty( $running_task[ 'task_start' ] ) ) {
605 +
606 + if ( $running_task[ 'task_start' ] < time() - $cache_exp_secs ) {
607 +
608 + delete_transient( $task_cache_id );
609 +
610 + return false;
611 + }
612 + }
613 + }
614 +
615 + return $running_task;
616 + }
617 +
618 + delete_transient( $task_cache_id ); // Remove invalid array.
619 + }
620 +
621 + return false;
622 + }
623 +
624 + public function task_update( $task_name, $task_info_transl = null ) {
625 +
626 + $running_task = $this->get_running_task( $task_name ); // Returns false or an array.
627 +
628 + if ( isset( $running_task[ 'user_id' ] ) ) { // Task is running.
629 +
630 + if ( isset( $running_task[ 'task_limit' ] ) ) { // Just in case.
631 +
632 + $task_cache_id = $this->get_task_cache_id( $task_name );
633 + $cache_exp_secs = $running_task[ 'task_limit' ] - time(); // Time left.
634 +
635 + $running_task[ 'task_info_transl' ] = $task_info_transl;
636 +
637 + return set_transient( $task_cache_id, $running_task, $cache_exp_secs );
638 + }
639 + }
640 +
641 + return false;
642 + }
643 +
644 + public function task_end( $user_id, $task_name ) {
645 +
646 + if ( $this->p->debug->enabled ) {
647 +
648 + $this->p->debug->mark();
649 + }
650 +
651 + $task_cache_id = $this->get_task_cache_id( $task_name );
652 +
653 + return delete_transient( $task_cache_id );
654 + }
655 +
656 + public function set_task_limit( $user_id, $task_name, $cache_exp_secs ) {
657 +
658 + if ( $this->p->debug->enabled ) {
659 +
660 + $this->p->debug->mark();
661 + }
662 +
663 + $ret = set_time_limit( $cache_exp_secs );
664 +
665 + if ( ! $ret ) {
666 +
667 + $human_time = human_time_diff( 0, $cache_exp_secs );
668 + $task_name_transl = _x( $task_name, 'task name', 'wpsso' );
669 + $error_pre = sprintf( __( '%s error:', 'wpsso' ), __METHOD__ );
670 + $notice_key = $task_name . '-task-set-time-limit-error';
671 + $notice_msg = sprintf( __( 'The PHP %1$s function failed to set a maximum execution time of %2$s to %3$s.', 'wpsso' ),
672 + '<code>set_time_limit()</code>', $human_time, $task_name_transl );
673 +
674 + $this->p->notice->err( $notice_msg, $user_id, $notice_key );
675 +
676 + SucomUtil::safe_error_log( $error_pre . ' ' . $notice_msg, $strip_html = true );
677 + }
678 +
679 + return $ret;
680 + }
681 +
682 + /*
683 + * Returns a transient cache id.
684 + *
685 + * See WpssoUser->add_person_role().
686 + * See WpssoUser->remove_person_role().
687 + * See WpssoUtilCache->refresh().
688 + * See WpssoUtilCache->get_running_task().
689 + */
690 + public function get_task_cache_id( $task_name ) {
691 +
692 + if ( $this->p->debug->enabled ) {
693 +
694 + $this->p->debug->mark();
695 + }
696 +
697 + return 'wpsso_!_' . md5( __CLASS__ . '::running-task-'. $task_name );
698 + }
699 +
700 + /*
701 + * Clear WP cache and (by default) all active known cache plugins.
702 + *
703 + * See WpssoUtilCache->refresh().
704 + */
705 + public function clear_cache( $clear_plugins = true ) {
706 +
707 + if ( $this->p->debug->enabled ) {
708 +
709 + $this->p->debug->mark();
710 + }
711 +
712 + /*
713 + * Prevent recursion in case a cache plugin calls our refresh method (which in turn calls this method).
714 + */
715 + static $do_once = null;
716 +
717 + if ( $do_once ) return; // Stop here.
718 +
719 + $do_once = true;
720 +
721 + $cleared_msg = __( 'The cache for <strong>%s</strong> has also been cleared.', 'wpsso' ) . ' ';
722 +
723 + $notice_msg = '';
724 +
725 + /*
726 + * WordPress object cache.
727 + */
728 + wp_cache_flush();
729 +
730 + $notice_msg .= sprintf( $cleared_msg, __( 'WordPress object cache', 'wpsso' ) );
731 +
732 + if ( ! $clear_plugins ) {
733 +
734 + return $notice_msg;
735 + }
736 +
737 + /*
738 + * Autoptimize.
739 + *
740 + * See https://wordpress.org/plugins/autoptimize/.
741 + *
742 + * Note that Autoptimize is not a page caching plugin - it optimizes CSS and JavaScript.
743 + */
744 + if ( $this->p->avail[ 'util' ][ 'autoptimize' ] ) {
745 +
746 + if ( method_exists( 'autoptimizeCache', 'clearall' ) ) { // Just in case.
747 +
748 + autoptimizeCache::clearall();
749 +
750 + $notice_msg .= sprintf( $cleared_msg, __( 'Autoptimize', 'wpsso' ) );
751 + }
752 + }
753 +
754 + /*
755 + * Cache Enabler.
756 + *
757 + * See https://wordpress.org/plugins/cache-enabler/.
758 + */
759 + if ( $this->p->avail[ 'cache' ][ 'enabler' ] ) {
760 +
761 + if ( method_exists( 'Cache_Enabler', 'clear_total_cache') ) {
762 +
763 + Cache_Enabler::clear_total_cache();
764 +
765 + $notice_msg .= sprintf( $cleared_msg, __( 'Cache Enabler', 'wpsso' ) );
766 + }
767 + }
768 +
769 + /*
770 + * Comet Cache.
771 + *
772 + * See https://wordpress.org/plugins/comet-cache/.
773 + */
774 + if ( $this->p->avail[ 'cache' ][ 'comet' ] ) {
775 +
776 + $GLOBALS[ 'comet_cache' ]->wipe_cache();
777 +
778 + $notice_msg .= sprintf( $cleared_msg, __( 'Comet Cache', 'wpsso' ) );
779 + }
780 +
781 + /*
782 + * Hummingbird Cache.
783 + *
784 + * See https://wordpress.org/plugins/hummingbird-performance/.
785 + */
786 + if ( $this->p->avail[ 'cache' ][ 'hummingbird' ] ) {
787 +
788 + if ( method_exists( '\Hummingbird\WP_Hummingbird', 'flush_cache' ) ) {
789 +
790 + \Hummingbird\WP_Hummingbird::flush_cache();
791 +
792 + $notice_msg .= sprintf( $cleared_msg, __( 'Hummingbird Cache', 'wpsso' ) );
793 + }
794 + }
795 +
796 + /*
797 + * LiteSpeed Cache.
798 + *
799 + * See https://wordpress.org/plugins/litespeed-cache/.
800 + */
801 + if ( $this->p->avail[ 'cache' ][ 'litespeed' ] ) {
802 +
803 + if ( method_exists( 'LiteSpeed_Cache_API', 'purge_all' ) ) {
804 +
805 + do_action( 'litespeed_purge_all', 'WPSSO Core' );
806 +
807 + $notice_msg .= sprintf( $cleared_msg, __( 'LiteSpeed Cache', 'wpsso' ) );
808 + }
809 + }
810 +
811 + /*
812 + * Pagely Cache.
813 + */
814 + if ( $this->p->avail[ 'cache' ][ 'pagely' ] ) {
815 +
816 + if ( method_exists( 'PagelyCachePurge', 'purgeAll' ) ) {
817 +
818 + PagelyCachePurge::purgeAll();
819 +
820 + $notice_msg .= sprintf( $cleared_msg, __( 'Pagely', 'wpsso' ) );
821 + }
822 + }
823 +
824 + /*
825 + * SiteGround Cache.
826 + */
827 + if ( $this->p->avail[ 'cache' ][ 'siteground' ] ) {
828 +
829 + sg_cachepress_purge_cache();
830 +
831 + $notice_msg .= sprintf( $cleared_msg, __( 'Siteground Cache', 'wpsso' ) );
832 + }
833 +
834 + /*
835 + * W3 Total Cache (aka W3TC).
836 + */
837 + if ( $this->p->avail[ 'cache' ][ 'w3tc' ] ) {
838 +
839 + w3tc_pgcache_flush();
840 +
841 + if ( function_exists( 'w3tc_objectcache_flush' ) ) {
842 +
843 + w3tc_objectcache_flush();
844 + }
845 +
846 + $notice_msg .= sprintf( $cleared_msg, __( 'W3 Total Cache', 'wpsso' ) );
847 + }
848 +
849 + /*
850 + * WP Engine Cache.
851 + */
852 + if ( $this->p->avail[ 'cache' ][ 'wp-engine' ] ) {
853 +
854 + if ( method_exists( 'WpeCommon', 'purge_memcached' ) ) {
855 +
856 + WpeCommon::purge_memcached();
857 + }
858 +
859 + if ( method_exists( 'WpeCommon', 'purge_varnish_cache' ) ) {
860 +
861 + WpeCommon::purge_varnish_cache();
862 + }
863 +
864 + $notice_msg .= sprintf( $cleared_msg, __( 'WP Engine Cache', 'wpsso' ) );
865 + }
866 +
867 + /*
868 + * WP Fastest Cache.
869 + *
870 + * See https://wordpress.org/plugins/wp-fastest-cache/.
871 + */
872 + if ( $this->p->avail[ 'cache' ][ 'wp-fastest' ] ) {
873 +
874 + wpfc_clear_all_cache( true );
875 +
876 + $notice_msg .= sprintf( $cleared_msg, __( 'WP Fastest Cache', 'wpsso' ) );
877 + }
878 +
879 + /*
880 + * WP Rocket Cache.
881 + */
882 + if ( $this->p->avail[ 'cache' ][ 'wp-rocket' ] ) {
883 +
884 + rocket_clean_domain();
885 +
886 + $notice_msg .= sprintf( $cleared_msg, __( 'WP Rocket Cache', 'wpsso' ) );
887 + }
888 +
889 + /*
890 + * WP Super Cache.
891 + *
892 + * See https://wordpress.org/plugins/wp-super-cache/.
893 + */
894 + if ( $this->p->avail[ 'cache' ][ 'wp-super' ] ) {
895 +
896 + wp_cache_clear_cache();
897 +
898 + $notice_msg .= sprintf( $cleared_msg, __( 'WP Super Cache', 'wpsso' ) );
899 + }
900 +
901 + return $notice_msg;
902 + }
903 +
904 + /*
905 + * Clear cache files older than WPSSO_CACHE_FILES_EXP_SECS.
906 + */
907 + public function clear_cache_files_expired() {
908 +
909 + return $this->clear_cache_files( WPSSO_CACHE_FILES_EXP_SECS );
910 + }
911 +
912 + /*
913 + * Clear cache files.
914 + *
915 + * See WpssoUtilCache->refresh().
916 + * See WpssoAdmin->load_settings_page().
917 + */
918 + public function clear_cache_files( $file_exp_secs = null, $include = array(), $exclude = array() ) {
919 +
920 + $cleared_count = 0;
921 + $cache_files = $this->get_cache_files(); // Excludes hidden files and index.php.
922 +
923 + foreach ( $cache_files as $cache_file ) {
924 +
925 + if ( ! empty( $include ) ) {
926 +
927 + foreach ( $include as $preg_match ) {
928 +
929 + if ( ! preg_match( $preg_match, $cache_file ) ) {
930 +
931 + if ( $this->p->debug->enabled ) {
932 +
933 + $this->p->debug->log( 'skipping ' . $cache_file . ' (not included)' );
934 + }
935 +
936 + continue 2;
937 + }
938 + }
939 + }
940 +
941 + if ( ! empty( $exclude ) ) {
942 +
943 + foreach ( $exclude as $preg_match ) {
944 +
945 + if ( preg_match( $preg_match, $cache_file ) ) {
946 +
947 + if ( $this->p->debug->enabled ) {
948 +
949 + $this->p->debug->log( 'skipping ' . $cache_file . ' (excluded)' );
950 + }
951 +
952 + continue 2;
953 + }
954 + }
955 + }
956 +
957 + if ( null !== $file_exp_secs ) {
958 +
959 + /*
960 + * Skip cache files that are newer than the expiration time.
961 + */
962 + if ( filemtime( $cache_file ) > time() - $file_exp_secs ) {
963 +
964 + if ( $this->p->debug->enabled ) {
965 +
966 + $this->p->debug->log( 'skipping ' . $cache_file . ' (newer than expiration time)' );
967 + }
968 +
969 + continue;
970 + }
971 + }
972 +
973 + if ( @unlink( $cache_file ) ) {
974 +
975 + if ( $this->p->debug->enabled ) {
976 +
977 + $this->p->debug->log( 'removed the cache file ' . $cache_file );
978 + }
979 +
980 + $cleared_count++;
981 +
982 + } else {
983 +
984 + if ( $this->p->debug->enabled ) {
985 +
986 + $this->p->debug->log( 'error removing cache file ' . $cache_file );
987 + }
988 +
989 + $error_pre = sprintf( '%s error:', __METHOD__ );
990 + $error_msg = sprintf( __( 'Error removing cache file %s.', 'wpsso' ), $cache_file );
991 +
992 + $this->p->notice->err( $error_msg );
993 +
994 + SucomUtil::safe_error_log( $error_pre . ' ' . $error_msg );
995 + }
996 + }
997 +
998 + return $cleared_count++;
999 + }
1000 +
1001 + /*
1002 + * See WpssoSubmenuTools->add_form_buttons().
1003 + */
1004 + public function count_cache_files() {
1005 +
1006 + $cache_files = $this->get_cache_files(); // Excludes hidden files and index.php.
1007 +
1008 + return count( $cache_files );
1009 + }
1010 +
1011 + public function get_cache_files() {
1012 +
1013 + $cache_files = array();
1014 +
1015 + if ( $dh = @opendir( WPSSO_CACHE_DIR ) ) {
1016 +
1017 + while ( $file_name = @readdir( $dh ) ) {
1018 +
1019 + $cache_file = WPSSO_CACHE_DIR . $file_name;
1020 +
1021 + if ( ! preg_match( '/^(\..*|index\.php)$/', $file_name ) && is_file( $cache_file ) ) {
1022 +
1023 + $cache_files[] = $cache_file;
1024 +
1025 + }
1026 + }
1027 +
1028 + closedir( $dh );
1029 +
1030 + } else {
1031 +
1032 + if ( $this->p->debug->enabled ) {
1033 +
1034 + $this->p->debug->log( 'failed to open the cache folder ' . WPSSO_CACHE_DIR . ' for reading' );
1035 + }
1036 +
1037 + $error_pre = sprintf( '%s error:', __METHOD__ );
1038 +
1039 + $error_msg = sprintf( __( 'Failed to open the cache folder %s for reading.', 'wpsso' ), WPSSO_CACHE_DIR );
1040 +
1041 + $this->p->notice->err( $error_msg );
1042 +
1043 + SucomUtil::safe_error_log( $error_pre . ' ' . $error_msg );
1044 + }
1045 +
1046 + return $cache_files;
1047 + }
1048 +
1049 + /*
1050 + * See WpssoAdmin->load_settings_page().
1051 + */
1052 + public function clear_ignored_urls() {
1053 +
1054 + return $this->p->cache->clear_ignored_urls();
1055 + }
1056 +
1057 + /*
1058 + * See WpssoSubmenuTools->add_form_buttons().
1059 + */
1060 + public function count_ignored_urls() {
1061 +
1062 + return $this->p->cache->count_ignored_urls();
1063 + }
1064 +
1065 + /*
1066 + * See WpssoSubmenuTools->add_form_buttons().
1067 + */
1068 + public function get_ignored_urls() {
1069 +
1070 + return $this->p->cache->get_ignored_urls();
1071 + }
1072 +
1073 + public function clear_db_transients_expired() {
1074 +
1075 + return $this->clear_db_transients( $key_prefix = '', $incl_shortened = true, $only_expired = true );
1076 + }
1077 +
1078 + /*
1079 + * Clear database transients, excluding transients that must be preserved (key begins with 'wpsso_!_'), and
1080 + * optionally exclude shortened URL transients.
1081 + *
1082 + * See WpssoAdmin->load_settings_page().
1083 + * See WpssoUtilCache->clear_db_transients_expired().
1084 + */
1085 + public function clear_db_transients( $key_prefix = '', $incl_shortened = true, $only_expired = false ) {
1086 +
1087 + $cleared_count = 0;
1088 +
1089 + $transients_subset = $this->get_db_transients_subset( $key_prefix, $incl_shortened, $only_expired );
1090 +
1091 + foreach ( $transients_subset as $key ) {
1092 +
1093 + if ( delete_transient( $key ) ) {
1094 +
1095 + $cleared_count++;
1096 + }
1097 + }
1098 +
1099 + return $cleared_count;
1100 + }
1101 +
1102 + public function count_db_transients_expired() {
1103 +
1104 + return $this->count_db_transients( $key_prefix = '', $incl_shortened = true, $only_expired = true );
1105 + }
1106 +
1107 + /*
1108 + * Count database transients, excluding transients that must be preserved (key begins with 'wpsso_!_'), and
1109 + * optionally exclude shortened URL transients.
1110 + *
1111 + * See WpssoSubmenuTools->add_form_buttons().
1112 + */
1113 + public function count_db_transients( $key_prefix = '', $incl_shortened = true, $only_expired = false ) {
1114 +
1115 + $transients_subset = $this->get_db_transients_subset( $key_prefix, $incl_shortened, $only_expired );
1116 +
1117 + return count( $transients_subset );
1118 + }
1119 +
1120 + /*
1121 + * A wrapper for WpssoUtilCache->get_db_transients_keys() to exclude transients that must be preserved (key begins
1122 + * with 'wpsso_!_'), and optionally exclude shortened URL transients.
1123 + *
1124 + * See WpssoUtilCache->clear_db_transients().
1125 + * See WpssoUtilCache->count_db_transients().
1126 + */
1127 + public function get_db_transients_subset( $key_prefix = '', $incl_shortened = true, $only_expired = false ) {
1128 +
1129 + $transients_subset = array();
1130 +
1131 + $transients_keys = $this->get_db_transients_keys( $key_prefix, $only_expired );
1132 +
1133 + foreach ( $transients_keys as $key ) {
1134 +
1135 + if ( '' !== $key_prefix ) { // We're only clearing a specific prefix.
1136 +
1137 + if ( 0 !== strpos( $key, $key_prefix ) ) { // Transient does not match that prefix.
1138 +
1139 + continue;
1140 + }
1141 + }
1142 +
1143 + if ( 0 === strpos( $key, 'wpsso_!_' ) ) { // Preserve transients that begin with "wpsso_!_".
1144 +
1145 + continue;
1146 +
1147 + } elseif ( ! $incl_shortened ) { // Not clearing short URLs.
1148 +
1149 + if ( 0 === strpos( $key, 'wpsso_s_' ) ) { // This is a shortened URL.
1150 +
1151 + continue;
1152 + }
1153 + }
1154 +
1155 + $transients_subset[] = $key;
1156 + }
1157 +
1158 + return $transients_subset;
1159 + }
1160 +
1161 + /*
1162 + * Get transients from the database, and optionally only those that are expired.
1163 + *
1164 + * See WpssoAdmin->show_metabox_cache_status().
1165 + * See WpssoUtilCache->get_db_transients_subset().
1166 + */
1167 + public function get_db_transients_keys( $key_prefix = '', $only_expired = false ) {
1168 +
1169 + global $wpdb;
1170 +
1171 + $transients_keys = array();
1172 + $transient_prefix = $only_expired ? '_transient_timeout_' : '_transient_';
1173 + $current_time = isset( $_SERVER[ 'REQUEST_TIME' ] ) ? (int) $_SERVER[ 'REQUEST_TIME' ] : time() ;
1174 +
1175 + $query = 'SELECT option_name';
1176 + $query .= ' FROM ' . $wpdb->options;
1177 + $query .= ' WHERE option_name LIKE \'' . $transient_prefix . $key_prefix . '%\'';
1178 +
1179 + if ( $only_expired ) { // Only check the value when querying for expires transients (ie. prefix is '_transient_timeout_').
1180 +
1181 + $query .= ' AND option_value < ' . $current_time; // Expiration time older than current time.
1182 + }
1183 +
1184 + $query .= ';'; // End of query.
1185 +
1186 + $result = $wpdb->get_col( $query );
1187 +
1188 + /*
1189 + * Remove '_transient_' or '_transient_timeout_' prefix from option name.
1190 + */
1191 + foreach( $result as $option_name ) {
1192 +
1193 + $transients_keys[] = str_replace( $transient_prefix, '', $option_name );
1194 + }
1195 +
1196 + return $transients_keys;
1197 + }
1198 +
1199 + /*
1200 + * See WpssoAdmin->show_metabox_cache_status().
1201 + */
1202 + public function get_db_transients_size_mb( $key_prefix = '' ) {
1203 +
1204 + global $wpdb;
1205 +
1206 + /*
1207 + * The CHAR_LENGTH() function returns the number of characters in a string. It is important to note that
1208 + * this function counts characters, not bytes, and it is Unicode-aware — meaning it accurately counts the
1209 + * number of multibyte characters in a string.
1210 + *
1211 + * The LENGTH() function, on the other hand, returns the length of a string in bytes. It differs from
1212 + * CHAR_LENGTH() because it is not Unicode-aware and counts bytes — which can yield different results,
1213 + * especially for multibyte character sets.
1214 + */
1215 + $query = 'SELECT LENGTH( option_value )';
1216 + $query .= ' FROM ' . $wpdb->options;
1217 + $query .= ' WHERE option_name LIKE \'_transient_' . $key_prefix . '%\'';
1218 + $query .= ';'; // End of query.
1219 +
1220 + $result = $wpdb->get_col( $query );
1221 +
1222 + return array_sum( $result ) / 1024 / 1024; // Return size in MB.
1223 + }
1224 +
1225 + /*
1226 + * See WpssoCmcfXml->get().
1227 + * See WpssoGmfXml->get().
1228 + * See WpssoAdmin->settings_sanitation().
1229 + * See WpssoAdmin->show_metabox_cache_status().
1230 + * See WpssoHead->get_head_array().
1231 + * See WpssoMessagesTooltipPlugin->get().
1232 + * See WpssoPage->get_the_content().
1233 + * See WpssoProMediaFacebook->filter_video_details().
1234 + * See WpssoProMediaSlideshare->filter_video_details().
1235 + * See WpssoProMediaVimeo->filter_video_details().
1236 + * See WpssoProMediaWistia->filter_video_details().
1237 + * See WpssoProMediaYoutube->filter_video_details().
1238 + * See WpssoProReviewJudgeme->filter_og().
1239 + * See WpssoProReviewShopperApproved->filter_og().
1240 + * See WpssoProReviewStamped->filter_og().
1241 + * See WpssoProUtilShorten->get_short_url().
1242 + * See WpssoSchema->get_schema_types().
1243 + * See WpssoSchema->get_schema_type_child_family().
1244 + * See WpssoSchema->get_schema_type_children().
1245 + * See WpssoSchema->get_schema_type_row_class().
1246 + * See WpssoUtil->get_image_url_info().
1247 + */
1248 + public function get_cache_exp_secs( $cache_key, $cache_type = 'transient', $mod = false ) {
1249 +
1250 + if ( $this->p->debug->enabled ) {
1251 +
1252 + $this->p->debug->mark();
1253 + }
1254 +
1255 + $cache_exp_secs = 0; // No caching by default.
1256 +
1257 + if ( empty( $this->p->cf[ 'wp' ][ 'cache' ][ $cache_type ][ $cache_key ] ) ) { // No cache expiration defined.
1258 +
1259 + return $cache_exp_secs;
1260 + }
1261 +
1262 + $cache_info = $this->p->cf[ 'wp' ][ 'cache' ][ $cache_type ][ $cache_key ];
1263 +
1264 + if ( isset( $cache_info[ 'value' ] ) ) { // Allow for 0.
1265 +
1266 + $cache_exp_secs = (int) $cache_info[ 'value' ];
1267 +
1268 + } elseif ( isset( $cache_info[ 'opt_key' ] ) && isset( $this->p->options[ $cache_info[ 'opt_key' ] ] ) ) { // Allow for 0.
1269 +
1270 + $cache_exp_secs = (int) $this->p->options[ $cache_info[ 'opt_key' ] ];
1271 + }
1272 +
1273 + if ( is_array( $mod ) ) {
1274 +
1275 + if ( ! empty( $cache_info[ 'conditional_values' ] ) ) {
1276 +
1277 + foreach ( $cache_info[ 'conditional_values' ] as $cond => $val ) {
1278 +
1279 + /*
1280 + * If the $mod array condition is true, use the associated value.
1281 + */
1282 + if ( ! empty( $mod[ $cond ] ) ) {
1283 +
1284 + $cache_exp_secs = (int) $val;
1285 +
1286 + break; // Stop here.
1287 + }
1288 + }
1289 + }
1290 + }
1291 +
1292 + if ( ! empty( $cache_info[ 'filter' ] ) ) {
1293 +
1294 + $filter_name = SucomUtil::sanitize_hookname( $cache_info[ 'filter' ] );
1295 +
1296 + if ( $this->p->debug->enabled ) {
1297 +
1298 + $this->p->debug->log( 'applying filters "' . $filter_name . '"' );
1299 + }
1300 +
1301 + $cache_exp_secs = (int) apply_filters( $filter_name, $cache_exp_secs, $cache_type, $mod );
1302 + }
1303 +
1304 + return $cache_exp_secs;
1305 + }
1306 + }
1307 +}