array( 'hourly', 300 ), self::CRITICAL => array( 'weekly', 600 ), self::GC => array( 'hourly', 900 ) ) as $hook => $when ) { if ( wp_next_scheduled( $hook ) && wp_get_schedule( $hook ) !== $when[0] ) { wp_unschedule_hook( $hook ); } if ( ! wp_next_scheduled( $hook ) ) { wp_schedule_event( time() + $when[1], $when[0], $hook ); } } } public static function clear() { foreach ( array( self::HEARTBEAT, self::CRITICAL, self::GC, self::CLAIM, ZeroConfig_Safe_Mode::EVENT_RUN, ZeroConfig_Safe_Mode::EVENT_POLL, ZeroConfig_Page_Cache::DEFERRED, ZeroConfig_CDN_Purge::EVENT, ZeroConfig_Warm::EVENT, ZeroConfig_API::EDGE_CHECK ) as $h ) { wp_unschedule_hook( $h ); // every event of the hook, whatever its args } } /** Finish a pending registration; retry a few times while the edge is still checking. */ public static function claim( $attempt = 1 ) { if ( ! ZeroConfig_Options::get( 'engine' ) || ZeroConfig_Options::is_connected() ) { return; } $r = ZeroConfig_API::claim_pending(); if ( 'pending' === $r && $attempt < 6 ) { wp_schedule_single_event( time() + 20, self::CLAIM, array( $attempt + 1 ) ); } } public static function heartbeat() { // Local chores first, so they run even when the service is unreachable. ZeroConfig_Page_Cache::write_config(); // picks up a changed nonce_life (no write when unchanged) ZeroConfig_Page_Cache::refresh_dropin(); // a plugin update (auto-updates too) brings a new drop-in ZeroConfig_Htaccess::refresh(); // a failed write must not leave old .htaccess rules for good ZeroConfig_Page_Cache::gc(); $before = ZeroConfig_Options::get( 'cdn_paused' ); $rules = (array) ZeroConfig_Options::get( 'rules' ); $res = ZeroConfig_API::heartbeat(); if ( is_wp_error( $res ) ) { return; } // Quota state or rules changed: cached HTML embeds CDN URLs, so purge. if ( ZeroConfig_Options::get( 'cdn_paused' ) !== $before || ZeroConfig_Options::get( 'rules' ) !== $rules ) { ZeroConfig_Page_Cache::purge_all( 'settings' ); } if ( ZeroConfig_Options::feature_on( 'critical' ) && ! ZeroConfig_Options::get( 'critical_css' ) ) { self::request_critical(); } // Once a day the "Is it working?" card is refreshed even when nobody purges anything. if ( time() - (int) ( ZeroConfig_Probe::health()['doctor']['at'] ?? 0 ) > DAY_IN_SECONDS ) { ZeroConfig_Doctor::run(); } } /** Ask the SaaS to (re)generate critical CSS for each template type. */ public static function request_critical() { if ( ! ZeroConfig_Options::feature_on( 'critical' ) || ! ZeroConfig_Options::is_connected() ) { return; } $urls = array( 'front' => home_url( '/' ) ); $post = get_posts( array( 'numberposts' => 1, 'post_status' => 'publish', 'fields' => 'ids' ) ); if ( $post ) { $urls['single'] = get_permalink( $post[0] ); } $page = get_posts( array( 'numberposts' => 1, 'post_type' => 'page', 'post_status' => 'publish', 'fields' => 'ids', 'exclude' => array( (int) get_option( 'page_on_front' ) ) ) ); // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- one id, one result if ( $page ) { $urls['page'] = get_permalink( $page[0] ); } if ( get_option( 'page_for_posts' ) ) { $urls['home'] = get_permalink( (int) get_option( 'page_for_posts' ) ); } $cat = get_categories( array( 'number' => 1, 'hide_empty' => true ) ); if ( $cat ) { $urls['archive'] = get_category_link( $cat[0] ); } if ( function_exists( 'wc_get_page_id' ) && wc_get_page_id( 'shop' ) > 0 ) { $urls['shop'] = get_permalink( wc_get_page_id( 'shop' ) ); $prod = ZeroConfig_Safe_Mode::sample_product(); // one with a gallery when there is one if ( $prod ) { $urls['product'] = get_permalink( $prod ); } } ZeroConfig_API::request_critical( $urls ); wp_schedule_single_event( time() + 180, self::CRITICAL ); } /** Pull generated critical CSS down. */ public static function critical() { if ( ! ZeroConfig_Options::feature_on( 'critical' ) ) { return; } $res = ZeroConfig_API::get_critical(); if ( is_wp_error( $res ) || empty( $res['critical_css'] ) || ! is_array( $res['critical_css'] ) ) { return; } $clean = ZeroConfig_API::clean_critical( $res['critical_css'] ); if ( $clean !== ZeroConfig_Options::get( 'critical_css' ) ) { ZeroConfig_Options::set( 'critical_css', $clean ); ZeroConfig_Page_Cache::purge_all( 'settings' ); ZeroConfig_Safe_Mode::schedule( 60 ); } } /** Remove expired cache files so the directory never grows unbounded. */ public static function gc() { ZeroConfig_Page_Cache::gc(); } }