*/ private const SHADOW_MAP = array( 'hp_message' => 'wpdo_comment_hp_message', 'hp_favorite' => 'wpdo_comment_hp_favorite', 'hp_offer' => 'wpdo_comment_hp_offer', 'hp_review' => 'wpdo_comment_hp_review', ); /** * Whether the router is bound this request. * * @var bool */ private static bool $bound = false; /** * Bind the comments_clauses filter (idempotent). * * Bootstrap calls this from each adapter's on_register_query_hooks() * so router activation follows the same gate as adapter binding. */ public static function register(): void { if ( self::$bound ) { return; } if ( ! self::is_enabled() ) { return; } add_filter( 'comments_clauses', array( __CLASS__, 'rewrite' ), 20, 2 ); self::$bound = true; } /** * Reset internal state (test only). * * @internal */ public static function reset_for_tests(): void { self::$bound = false; } /** * Whether router is enabled via the operator option. */ public static function is_enabled(): bool { if ( ! function_exists( 'get_option' ) ) { return false; } return (bool) (int) get_option( self::OPTION_ENABLED, 0 ); } /** * Filter callback: rewrite comments_clauses for known hp comment types. * * @param array $clauses SQL clauses (join, where, fields, ...). * @param \WP_Comment_Query $query The query object. * @return array Possibly-modified clauses. */ public static function rewrite( array $clauses, $query ): array { $type = self::query_comment_type( $query ); if ( '' === $type || ! isset( self::SHADOW_MAP[ $type ] ) ) { return $clauses; } global $wpdb; $shadow = $wpdb->prefix . self::SHADOW_MAP[ $type ]; $alias = 'wpdo_shadow'; // LEFT JOIN keeps row visibility when shadow lags (during backfill). $join = ( $clauses['join'] ?? '' ) . " LEFT JOIN `{$shadow}` AS {$alias} ON {$alias}.comment_id = {$wpdb->comments}.comment_ID"; // Filter pushdown: hp_message recipient lookup uses comment_karma in HP. // We rewrite WHERE clauses that filter by comment_karma (= recipient hack) // to use the indexed shadow column. $where = (string) ( $clauses['where'] ?? '' ); if ( 'hp_message' === $type && '' !== $where ) { $where = preg_replace( '/' . preg_quote( $wpdb->comments, '/' ) . '\.comment_karma\s*=\s*(\d+)/', $alias . '.recipient_id = $1', $where ); } $clauses['join'] = $join; $clauses['where'] = $where; /** * Filter: wpdo_hivepress_comment_router_clauses * * Allows fine-grained tweaks per comment_type. Intended for adapter * tests + future custom-column lookups. * * @param array $clauses Modified clauses. * @param string $type Matched comment_type. * @param string $alias Shadow table alias. */ return apply_filters( 'wpdo_hivepress_comment_router_clauses', $clauses, $type, $alias ); } /** * Extract the comment_type from a WP_Comment_Query. * * @param \WP_Comment_Query $query Query object. */ private static function query_comment_type( $query ): string { if ( ! is_object( $query ) || ! isset( $query->query_vars ) ) { return ''; } $type = $query->query_vars['type'] ?? ''; if ( is_array( $type ) ) { $type = reset( $type ); } return is_string( $type ) ? $type : ''; } } } // end if ( ! class_exists )