chore: initial snapshot of 2meet-data-optimizer-hivepress-addon v0.1.0
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_Query interceptor for hp_listing meta queries.
|
||||
*
|
||||
* @package WP_Data_Optimizer
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Query interceptor for hp_listing meta queries.
|
||||
*
|
||||
* The hpct_listing_meta is a key-value table (like wp_postmeta), so each
|
||||
* meta_query condition needs its own JOIN alias with a meta_key condition:
|
||||
*
|
||||
* LEFT JOIN wp_hpct_listing_meta AS wpdo_lm_0
|
||||
* ON (wp_posts.ID = wpdo_lm_0.listing_id AND wpdo_lm_0.meta_key = 'hp_price')
|
||||
* WHERE wpdo_lm_0.meta_value >= 100
|
||||
*
|
||||
* All hp_* and _hp_* meta keys are intercepted. Any other meta keys are
|
||||
* left in the meta_query to be handled by wp_postmeta as usual.
|
||||
*/
|
||||
class TMDO_Listing_Meta_Query extends TMDO_Query_Interceptor_Base {
|
||||
|
||||
/**
|
||||
* Returns the module identifier.
|
||||
*
|
||||
* @return string Module name.
|
||||
*/
|
||||
protected function get_module(): string {
|
||||
return 'listing_meta';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the post types this interceptor handles.
|
||||
*
|
||||
* @return string[] Post type slugs.
|
||||
*/
|
||||
protected function get_post_types(): array {
|
||||
return array( 'hp_listing' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom table name.
|
||||
*
|
||||
* @return string Table name without prefix.
|
||||
*/
|
||||
protected function get_table(): string {
|
||||
return 'hpct_listing_meta';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the join column for this KV table.
|
||||
*
|
||||
* @return string Join column name.
|
||||
*/
|
||||
protected function get_join_column(): string {
|
||||
return 'listing_id';
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used — this class overrides pre_get_posts directly.
|
||||
*
|
||||
* @return array Empty array.
|
||||
*/
|
||||
protected function get_meta_key_map(): array {
|
||||
return array();
|
||||
}
|
||||
|
||||
// ── Override pre_get_posts for KV-table pattern ───────────────────────
|
||||
|
||||
/**
|
||||
* Intercepts pre_get_posts to handle KV-table meta_query conditions.
|
||||
*
|
||||
* @param \WP_Query $query The WP_Query object.
|
||||
* @return void
|
||||
*/
|
||||
public function pre_get_posts( \WP_Query $query ): void {
|
||||
if ( ! $this->should_intercept( $query ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$raw_meta_query = (array) $query->get( 'meta_query' );
|
||||
if ( empty( $raw_meta_query ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$our_clauses = array();
|
||||
$remaining = array();
|
||||
|
||||
foreach ( $raw_meta_query as $k => $clause ) {
|
||||
if ( 'relation' === $k || ! is_array( $clause ) || ! isset( $clause['key'] ) ) {
|
||||
$remaining[ $k ] = $clause;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $this->is_hp_key( $clause['key'] ) ) {
|
||||
$our_clauses[] = array(
|
||||
'meta_key' => $clause['key'],
|
||||
'value' => $clause['value'] ?? '',
|
||||
'compare' => strtoupper( trim( $clause['compare'] ?? '=' ) ),
|
||||
'type' => strtoupper( trim( $clause['type'] ?? 'CHAR' ) ),
|
||||
);
|
||||
} else {
|
||||
$remaining[ $k ] = $clause;
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $our_clauses ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $raw_meta_query['relation'] ) && ! isset( $remaining['relation'] ) ) {
|
||||
$remaining['relation'] = $raw_meta_query['relation'];
|
||||
}
|
||||
|
||||
$query->set( 'meta_query', $remaining );
|
||||
$query->set( $this->query_var(), $our_clauses );
|
||||
}
|
||||
|
||||
// ── Override posts_join for KV-table: one JOIN alias per condition ─────
|
||||
|
||||
/**
|
||||
* Appends LEFT JOINs for each KV-table meta_query condition.
|
||||
*
|
||||
* @param string $join Current JOIN SQL.
|
||||
* @param \WP_Query $query The WP_Query object.
|
||||
* @return string Modified JOIN SQL.
|
||||
*/
|
||||
public function posts_join( ?string $join, \WP_Query $query ): string {
|
||||
$join = (string) ( $join ?? '' );
|
||||
$clauses = $this->get_clauses( $query );
|
||||
if ( empty( $clauses ) ) {
|
||||
return $join;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$table = TMDO_DB::table( $this->get_table() );
|
||||
$join_col = esc_sql( $this->get_join_column() );
|
||||
|
||||
foreach ( $clauses as $i => $clause ) {
|
||||
$alias = $this->alias_for( $i );
|
||||
$meta_key = $clause['meta_key'];
|
||||
|
||||
if ( false === strpos( $join, "`{$alias}`" ) ) {
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $table from TMDO_DB::table(); $alias and $join_col are sanitize_key()-validated.
|
||||
$join .= $wpdb->prepare(
|
||||
" LEFT JOIN `{$table}` AS `{$alias}`"
|
||||
. " ON (`{$wpdb->posts}`.`ID` = `{$alias}`.`{$join_col}`"
|
||||
. " AND `{$alias}`.`meta_key` = %s)",
|
||||
$meta_key
|
||||
);
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
}
|
||||
}
|
||||
|
||||
return $join;
|
||||
}
|
||||
|
||||
// ── Override posts_where for KV-table ─────────────────────────────────
|
||||
|
||||
/**
|
||||
* Appends WHERE conditions for KV-table meta_value comparisons.
|
||||
*
|
||||
* @param string $where Current WHERE SQL.
|
||||
* @param \WP_Query $query The WP_Query object.
|
||||
* @return string Modified WHERE SQL.
|
||||
*/
|
||||
public function posts_where( ?string $where, \WP_Query $query ): string {
|
||||
$where = (string) ( $where ?? '' );
|
||||
$clauses = $this->get_clauses( $query );
|
||||
if ( empty( $clauses ) ) {
|
||||
return $where;
|
||||
}
|
||||
|
||||
foreach ( $clauses as $i => $clause ) {
|
||||
$alias = $this->alias_for( $i );
|
||||
$col = "`{$alias}`.`meta_value`";
|
||||
$compare = $this->sanitize_compare( $clause['compare'] );
|
||||
$type = $clause['type'];
|
||||
$value = $clause['value'];
|
||||
|
||||
$where .= $this->build_condition( $col, $compare, $type, $value );
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
// ── Override posts_groupby ─────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Ensures GROUP BY is set when KV-table clauses are active.
|
||||
*
|
||||
* @param string $groupby Current GROUP BY SQL.
|
||||
* @param \WP_Query $query The WP_Query object.
|
||||
* @return string Modified GROUP BY SQL.
|
||||
*/
|
||||
public function posts_groupby( ?string $groupby, \WP_Query $query ): string {
|
||||
$groupby = (string) ( $groupby ?? '' );
|
||||
$clauses = $this->get_clauses( $query );
|
||||
if ( empty( $clauses ) ) {
|
||||
return $groupby;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
if ( '' === trim( $groupby ) ) {
|
||||
$groupby = "`{$wpdb->posts}`.`ID`";
|
||||
}
|
||||
|
||||
return $groupby;
|
||||
}
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Generates a unique SQL alias for a KV-table JOIN at a given index.
|
||||
*
|
||||
* @param int $index Zero-based clause index.
|
||||
* @return string SQL alias string.
|
||||
*/
|
||||
private function alias_for( int $index ): string {
|
||||
return "wpdo_lm_{$index}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a meta key belongs to HivePress (hp_ or _hp_ prefix).
|
||||
*
|
||||
* @param string $meta_key Meta key to check.
|
||||
* @return bool True if the key is an HP key.
|
||||
*/
|
||||
private function is_hp_key( string $meta_key ): bool {
|
||||
return str_starts_with( $meta_key, 'hp_' ) || str_starts_with( $meta_key, '_hp_' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_Query interceptor for hp_membership post type.
|
||||
*
|
||||
* @package WP_Data_Optimizer
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Query interceptor for hp_membership post type.
|
||||
*
|
||||
* Intercepted meta keys:
|
||||
* hp_plan => plan_id (BIGINT)
|
||||
* hp_user => user_id (BIGINT)
|
||||
* hp_price => price (VARCHAR)
|
||||
* hp_order => order_id (BIGINT)
|
||||
* hp_start_date => start_date (DATETIME)
|
||||
* hp_end_date => end_date (DATETIME)
|
||||
*/
|
||||
class TMDO_Memberships_Query extends TMDO_Query_Interceptor_Base {
|
||||
|
||||
/**
|
||||
* Returns the module identifier.
|
||||
*
|
||||
* @return string Module name.
|
||||
*/
|
||||
protected function get_module(): string {
|
||||
return 'memberships';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the post types this interceptor handles.
|
||||
*
|
||||
* @return string[] Post type slugs.
|
||||
*/
|
||||
protected function get_post_types(): array {
|
||||
return array( 'hp_membership' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom table name.
|
||||
*
|
||||
* @return string Table name without prefix.
|
||||
*/
|
||||
protected function get_table(): string {
|
||||
return 'hpct_memberships';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the meta_key to column mapping for hpct_memberships.
|
||||
*
|
||||
* @return array<string, string> Meta key to column name map.
|
||||
*/
|
||||
protected function get_meta_key_map(): array {
|
||||
return array(
|
||||
'hp_plan' => 'plan_id',
|
||||
'hp_user' => 'user_id',
|
||||
'hp_price' => 'price',
|
||||
'hp_order' => 'order_id',
|
||||
'hp_start_date' => 'start_date',
|
||||
'hp_end_date' => 'end_date',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_Query interceptor for hp_message post type.
|
||||
*
|
||||
* @package WP_Data_Optimizer
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Query interceptor for hp_message post type.
|
||||
*
|
||||
* Intercepted meta keys:
|
||||
* hp_sender => sender_id (BIGINT)
|
||||
* hp_recipient => recipient_id (BIGINT)
|
||||
* hp_listing => listing_id (BIGINT)
|
||||
* hp_read => is_read (TINYINT)
|
||||
*/
|
||||
class TMDO_Messages_Query extends TMDO_Query_Interceptor_Base {
|
||||
|
||||
/**
|
||||
* Returns the module identifier.
|
||||
*
|
||||
* @return string Module name.
|
||||
*/
|
||||
protected function get_module(): string {
|
||||
return 'messages';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the post types this interceptor handles.
|
||||
*
|
||||
* @return string[] Post type slugs.
|
||||
*/
|
||||
protected function get_post_types(): array {
|
||||
return array( 'hp_message' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom table name.
|
||||
*
|
||||
* @return string Table name without prefix.
|
||||
*/
|
||||
protected function get_table(): string {
|
||||
return 'hpct_messages';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the meta_key to column mapping for hpct_messages.
|
||||
*
|
||||
* @return array<string, string> Meta key to column name map.
|
||||
*/
|
||||
protected function get_meta_key_map(): array {
|
||||
return array(
|
||||
'hp_sender' => 'sender_id',
|
||||
'hp_recipient' => 'recipient_id',
|
||||
'hp_listing' => 'listing_id',
|
||||
'hp_read' => 'is_read',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_Query interceptor for hp_request post type.
|
||||
*
|
||||
* @package WP_Data_Optimizer
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Query interceptor for hp_request post type.
|
||||
*
|
||||
* Intercepted meta keys:
|
||||
* hp_vendor => vendor_id (BIGINT)
|
||||
* hp_listing => listing_id (BIGINT)
|
||||
* hp_budget => budget (VARCHAR)
|
||||
*/
|
||||
class TMDO_Requests_Query extends TMDO_Query_Interceptor_Base {
|
||||
|
||||
/**
|
||||
* Returns the module identifier.
|
||||
*
|
||||
* @return string Module name.
|
||||
*/
|
||||
protected function get_module(): string {
|
||||
return 'requests';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the post types this interceptor handles.
|
||||
*
|
||||
* @return string[] Post type slugs.
|
||||
*/
|
||||
protected function get_post_types(): array {
|
||||
return array( 'hp_request' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom table name.
|
||||
*
|
||||
* @return string Table name without prefix.
|
||||
*/
|
||||
protected function get_table(): string {
|
||||
return 'hpct_requests';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the meta_key to column mapping for hpct_requests.
|
||||
*
|
||||
* @return array<string, string> Meta key to column name map.
|
||||
*/
|
||||
protected function get_meta_key_map(): array {
|
||||
return array(
|
||||
'hp_vendor' => 'vendor_id',
|
||||
'hp_listing' => 'listing_id',
|
||||
'hp_budget' => 'budget',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_Query interceptor for hp_review post type.
|
||||
*
|
||||
* @package WP_Data_Optimizer
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Query interceptor for hp_review post type.
|
||||
*
|
||||
* Rewrites meta_query conditions for known review meta keys to query
|
||||
* hpct_reviews directly, eliminating wp_postmeta JOIN for review queries.
|
||||
*
|
||||
* Intercepted meta keys:
|
||||
* hp_listing => listing_id (BIGINT)
|
||||
* _hp_vendor => vendor_id (BIGINT)
|
||||
* hp_rating => rating (TINYINT)
|
||||
*/
|
||||
class TMDO_Reviews_Query extends TMDO_Query_Interceptor_Base {
|
||||
|
||||
/**
|
||||
* Returns the module identifier.
|
||||
*
|
||||
* @return string Module name.
|
||||
*/
|
||||
protected function get_module(): string {
|
||||
return 'reviews';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the post types this interceptor handles.
|
||||
*
|
||||
* @return string[] Post type slugs.
|
||||
*/
|
||||
protected function get_post_types(): array {
|
||||
return array( 'hp_review' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom table name.
|
||||
*
|
||||
* @return string Table name without prefix.
|
||||
*/
|
||||
protected function get_table(): string {
|
||||
return 'hpct_reviews';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the meta_key to column mapping for hpct_reviews.
|
||||
*
|
||||
* @return array<string, string> Meta key to column name map.
|
||||
*/
|
||||
protected function get_meta_key_map(): array {
|
||||
return array(
|
||||
'hp_listing' => 'listing_id',
|
||||
'_hp_vendor' => 'vendor_id',
|
||||
'hp_rating' => 'rating',
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user