sources = $sources; $this->analyzer = $analyzer; $this->settings = $settings; } /** * Returns the report, scanning only when the cache is cold. * * @return UsageReport */ public function get(): UsageReport { /* * The report is cached as serialised objects, stamped with the plugin * version: after an update changes those classes, an old entry could * unserialise with uninitialised properties, so it is never trusted. */ try { $cached = get_transient( self::TRANSIENT ); } catch ( \Throwable $e ) { $cached = null; } if ( is_array( $cached ) && BLOCKSIEVE_VERSION === ( $cached['version'] ?? null ) && ( $cached['report'] ?? null ) instanceof UsageReport ) { return $cached['report']; } return $this->refresh(); } /** * Runs a fresh scan and caches the result. * * @return UsageReport */ public function refresh(): UsageReport { $now = current_datetime(); $occurrences = array(); foreach ( $this->sources->collect() as $occurrence ) { $occurrences[] = $this->analyzer->analyze( $occurrence, $now ); } $report = new UsageReport( $occurrences, $now->getTimestamp(), $this->sources->truncated(), $this->sources->scanned() ); /** * Filters how long the visibility report stays cached. * * @param int $ttl Lifetime in seconds. */ $ttl = (int) apply_filters( 'blocksieve_report_ttl', $this->settings->report_ttl() ); set_transient( self::TRANSIENT, array( 'version' => BLOCKSIEVE_VERSION, 'report' => $report, ), max( Settings::MIN_REPORT_TTL, $ttl ) ); return $report; } /** * Drops the cached report so the next read rescans. * * @return void */ public function invalidate(): void { delete_transient( self::TRANSIENT ); } /** * Invalidates the cache when a post changes. * * Ignores revisions, autosaves and internal post types, which never render * blocks on the front end. * * @param int $post_id Post id. * @param \WP_Post $post Post object. * @return void */ public function on_post_change( $post_id, $post = null ): void { if ( $post instanceof \WP_Post && in_array( $post->post_type, self::IGNORED_POST_TYPES, true ) ) { return; } if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) { return; } $this->invalidate(); } }