term_id ) && function_exists( 'get_category_link' ) ) { $link = get_category_link( $cat->term_id ); if ( $link && ! is_wp_error( $link ) ) { $urls[] = $link; } } } } return array_values( array_unique( array_filter( $urls ) ) ); } /** * @param string[] $urls URLs. */ public static function purge_url( $url ) { $url = (string) $url; if ( $url ) { do_action( 'qwsc_cache_purged_urls', array( $url ) ); if ( class_exists( '\QWSpeedCache\Stats\Logger' ) ) { \QWSpeedCache\Stats\Logger::log( 'purge_url', $url ); } } } public function purge_urls( array $urls ) { $urls = array_values( array_filter( array_map( 'strval', $urls ) ) ); if ( ! empty( $urls ) ) { /** * Edge/CDN integrations (Cloudflare file purge, etc.). * * @param string[] $urls Absolute URLs. */ do_action( 'qwsc_cache_purged_urls', $urls ); } // No local URL→file index yet: full local purge for correctness. $this->purge_all(); } /** * @param int $post_id Post ID. * @param \WP_Post $post Post. * @param bool $update Update. */ public function on_save_post( $post_id, $post = null, $update = true ) { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } $post_id = (int) $post_id; if ( $post_id <= 0 ) { return; } if ( function_exists( 'wp_is_post_revision' ) && wp_is_post_revision( $post_id ) ) { return; } if ( function_exists( 'wp_is_post_autosave' ) && wp_is_post_autosave( $post_id ) ) { return; } $status = ( $post && isset( $post->post_status ) ) ? $post->post_status : get_post_status( $post_id ); if ( in_array( $status, array( 'auto-draft', 'inherit' ), true ) ) { return; } if ( in_array( $status, array( 'publish', 'private', 'future' ), true ) || $update ) { $this->purge_urls( self::urls_for_post( $post_id ) ); } } /** * @param int $post_id Post ID. */ public function on_deleted_post( $post_id ) { $this->purge_urls( self::urls_for_post( (int) $post_id ) ); } /** * @param int $term_id Term ID. * @param int $tt_id TT ID. * @param string $taxonomy Taxonomy. */ public function on_edited_term( $term_id, $tt_id = 0, $taxonomy = '' ) { $this->purge_all(); } /** * @param int $comment_id Comment ID. * @param int|string $approved Approved. */ public function on_comment( $comment_id, $approved = 1 ) { if ( 1 !== (int) $approved && '1' !== (string) $approved && 'approve' !== $approved ) { return; } $c = get_comment( $comment_id ); if ( $c && ! empty( $c->comment_post_ID ) ) { $this->purge_urls( self::urls_for_post( (int) $c->comment_post_ID ) ); } } /** * @param int $comment_id Comment ID. */ public function on_comment_edit( $comment_id ) { $c = get_comment( $comment_id ); if ( $c && ! empty( $c->comment_post_ID ) ) { $this->purge_urls( self::urls_for_post( (int) $c->comment_post_ID ) ); } } /** * @param string $new_status New. * @param string $old_status Old. * @param \WP_Comment $comment Comment. */ public function on_comment_status( $new_status, $old_status, $comment ) { if ( empty( $comment->comment_post_ID ) ) { return; } $this->purge_urls( self::urls_for_post( (int) $comment->comment_post_ID ) ); } public function ajax_clear_all() { check_ajax_referer( 'qwsc_clear_cache', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error(); } $result = self::purge_all(); if ( is_wp_error( $result ) ) { wp_send_json_error( array( 'message' => $result->get_error_message() ), 500 ); } wp_send_json_success( array( 'message' => __( 'Cache cleared successfully.', 'qw-optimize' ) ) ); } /** * Legacy method retained for third-party calls. The actual WordPress toolbar * is rendered by Admin\AdminBar so duplicate menu nodes cannot compete. * * @param \WP_Admin_Bar $wp_admin_bar WordPress admin bar instance. */ public function admin_bar( $wp_admin_bar ) { // Intentionally left blank. Admin\AdminBar owns the toolbar. } }