AIDF_VERSION, 'files' => array(), ); } $cache['files'][ $file_slug ] = $content; update_option( self::OPTION, $cache, false ); } /** * Regenerate and cache every active file type in one pass. * * Runs the full generation pipeline, so it must only be called in a fully * loaded context (admin, cron, or the front-end template_redirect path) — * never from the early plugins_loaded server. * * @return void */ public static function warm() { if ( ! class_exists( 'AIDF_Generator' ) || ! class_exists( 'AIDF_Plugin' ) ) { return; } $settings = AIDF_Plugin::get_settings(); $active = isset( $settings['active_files'] ) ? (array) $settings['active_files'] : array(); $files = array(); foreach ( $active as $slug ) { // llm.txt is served as a 301 redirect to llms.txt; nothing to cache. if ( 'llm-txt' === $slug ) { continue; } $content = AIDF_Generator::generate( $slug ); if ( false !== $content ) { $files[ $slug ] = $content; } } update_option( self::OPTION, array( 'v' => AIDF_VERSION, 'files' => $files, ), false ); } /** * Delete the cache. * * @return void */ public static function invalidate() { delete_option( self::OPTION ); } /** * Handle an identity-settings change: rebuild the cache immediately. * * A settings save is a deliberate content change made in the admin, so the * small cost of warming synchronously keeps the front end permanently fast. * * @return void */ public static function on_settings_change() { self::invalidate(); self::warm(); } /** * Handle a post/page save: invalidate and warm in the background. * * Only publish-worthy page and post edits affect generated content, so * revisions, autosaves, and unrelated post types are ignored to avoid churn. * * @param int $post_id Saved post ID. * @param WP_Post|null $post Saved post object. * @return void */ public static function on_save_post( $post_id, $post = null ) { if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) { return; } if ( $post instanceof WP_Post && ! in_array( $post->post_type, array( 'page', 'post' ), true ) ) { return; } self::invalidate(); self::schedule_warm(); } /** * Handle a relevant option change (site title / tagline). * * @return void */ public static function on_option_change() { self::invalidate(); self::schedule_warm(); } /** * Queue a single background warm run if one is not already scheduled. * * @return void */ public static function schedule_warm() { if ( ! wp_next_scheduled( self::WARM_HOOK ) ) { wp_schedule_single_event( time() + 10, self::WARM_HOOK ); } } }