refactor(2meet-data-optimizer-hivepress-addon): take ownership of hp_* entity groups

- Add TMDO_HivePress_Entity_Groups registering hp_listing_core / hp_request_core / hp_vendor_core / hp_user, copied verbatim from core (same order; schema hashes match the persisted wpdo_registry_meta rows)
- Drop the core adapter's conflicting hp_user definition (hp_verified / hp_avatar_id — keys HivePress never writes)
- Verify: HivePressEntityGroupsTest (identical to core, same shared-key resolution, no collisions); HP unit 144 / integration 49 OK; hashes = dev20 registry_meta
- PR: PR-019
This commit is contained in:
2026-09-25 23:43:40 +08:00
parent ff6d6b10e4
commit 19add5fc16
7 changed files with 346 additions and 48 deletions
@@ -0,0 +1,251 @@
<?php
/**
* HivePress entity groups owned by the HivePress AddOn.
*
* Groups → flat tables:
* post:hp_listing_core → wp_wpdo_post_hp_listing_core (hp_listing)
* post:hp_request_core → wp_wpdo_post_hp_request_core (hp_request)
* post:hp_vendor_core → wp_wpdo_post_hp_vendor_core (hp_vendor)
* user:hp_user → wp_wpdo_user_hp_user
*
* The term/comment groups (hp_taxonomy, hp_review) live in
* TMDO_Hivepress_Term_Comment_Fields.
*
* ⚠️ These definitions must stay byte-identical to the ones live sites
* persisted in wpdo_registry_meta (originally registered by core's
* TMDO_Post_Fields / TMDO_Member_Fields). Any drift changes the schema hash
* and triggers ALTER TABLE on flat tables that may hold aeav_only data.
* The three post groups also share keys (hp_status, hp_user, …) and the
* entity field index is last-registered-wins, so keep their order.
*
* @package TMDO_HIVEPRESS
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Registers the HivePress post + user entity groups.
*/
final class TMDO_HivePress_Entity_Groups {
/**
* Hook into WPDO entity field registration.
*
* @return void
*/
public static function register(): void {
add_action( 'wpdo_register_entity_fields', array( __CLASS__, 'register_entity_fields' ) );
}
/**
* Register the groups (order matters, see file header).
*
* @return void
*/
public static function register_entity_fields(): void {
if ( ! class_exists( 'TMDO_Entity_Registry' ) ) {
return;
}
self::register_hp_listing_core_group();
self::register_hp_request_core_group();
self::register_hp_vendor_core_group();
self::register_hp_user_group();
}
// ── Group definitions ────────────────────────────────────────────────────
/**
* HivePress listing core meta keys (post_type=hp_listing).
* Aligns with the existing wpdo_hot_hp_listing flat table; v2.9.5 will
* copy-then-cutover the 230 dev10 rows to this group's table.
*
* @return void
*/
private static function register_hp_listing_core_group(): void {
TMDO_Entity_Registry::register_group(
'post',
'hp_listing_core',
array(
array(
'key' => 'hp_price',
'type' => 'decimal',
'searchable' => true,
'label' => 'Listing price',
),
array(
'key' => 'hp_status',
'type' => 'enum',
'searchable' => true,
'options' => array( 'publish', 'draft', 'pending', 'expired', 'private' ),
'label' => 'Listing status',
),
array(
'key' => 'hp_featured',
'type' => 'integer',
'searchable' => true,
'label' => 'Featured flag (0/1)',
),
array(
'key' => 'hp_verified',
'type' => 'integer',
'searchable' => true,
'label' => 'Verified flag (0/1)',
),
array(
'key' => 'hp_vendor',
'type' => 'integer',
'searchable' => true,
'label' => 'Vendor user ID',
),
array(
'key' => 'hp_expired_time',
'type' => 'integer',
'searchable' => true,
'label' => 'Expiry unix ts',
),
array(
'key' => 'hp_featured_time',
'type' => 'integer',
'label' => 'Featured-until unix ts',
),
array(
'key' => 'hp_view_count',
'type' => 'integer',
'searchable' => true,
'label' => 'View counter',
),
array(
'key' => 'hp_rating',
'type' => 'decimal',
'searchable' => true,
'label' => 'Average rating',
),
array(
'key' => 'hp_rating_count',
'type' => 'integer',
'label' => 'Rating count',
),
array(
'key' => 'hp_hourly_rate',
'type' => 'decimal',
'label' => 'Hourly rate',
),
)
);
}
/**
* HivePress request core meta keys (post_type=hp_request).
*
* @return void
*/
private static function register_hp_request_core_group(): void {
TMDO_Entity_Registry::register_group(
'post',
'hp_request_core',
array(
array(
'key' => 'hp_status',
'type' => 'enum',
'searchable' => true,
'options' => array( 'publish', 'draft', 'pending', 'expired' ),
'label' => 'Request status',
),
array(
'key' => 'hp_user',
'type' => 'integer',
'searchable' => true,
'label' => 'Request author user ID',
),
array(
'key' => 'hp_expired_time',
'type' => 'integer',
'searchable' => true,
'label' => 'Expiry unix ts',
),
array(
'key' => 'hp_budget',
'type' => 'decimal',
'searchable' => true,
'label' => 'Budget amount',
),
array(
'key' => 'hp_view_count',
'type' => 'integer',
'label' => 'View counter',
),
)
);
}
/**
* HivePress vendor core meta keys (post_type=hp_vendor).
*
* @return void
*/
private static function register_hp_vendor_core_group(): void {
TMDO_Entity_Registry::register_group(
'post',
'hp_vendor_core',
array(
array(
'key' => 'hp_user',
'type' => 'integer',
'searchable' => true,
'label' => 'Vendor user ID (linked WP user)',
),
array(
'key' => 'hp_verified',
'type' => 'integer',
'searchable' => true,
'label' => 'Verified flag (0/1)',
),
array(
'key' => 'hp_hourly_rate',
'type' => 'decimal',
'searchable' => true,
'label' => 'Hourly rate',
),
array(
'key' => 'hp_rating_count',
'type' => 'integer',
'label' => 'Rating count',
),
array(
'key' => 'hp_rating',
'type' => 'decimal',
'searchable' => true,
'label' => 'Average rating',
),
)
);
}
/**
* HivePress per-user fields (favorites + avatar attachment).
*
* Hp_favorited_listings is a serialized array of post IDs in legacy storage;
* the migration engine safe_unserialize()s it (allowed_classes=false to block
* PHP-object injection) then the json type encodes back to a JSON array column.
*
* @return void
*/
private static function register_hp_user_group(): void {
TMDO_Entity_Registry::register_group(
'user',
'hp_user',
array(
array(
'key' => 'hp_favorited_listings',
'type' => 'json',
'label' => 'HivePress favorited listing IDs (array)',
),
array(
'key' => 'hp_image',
'type' => 'text',
'label' => 'HivePress avatar attachment ID',
),
)
);
}
}