diff --git a/includes/integrations/class-tmdo-member-fields.php b/includes/integrations/class-tmdo-member-fields.php index 7947554..776d9cd 100644 --- a/includes/integrations/class-tmdo-member-fields.php +++ b/includes/integrations/class-tmdo-member-fields.php @@ -43,6 +43,7 @@ final class TMDO_Member_Fields { * V2.7.0: Adds four legacy-key groups (core_profile, social, commerce, hp_user) * to absorb wp_usermeta rows that previously bypassed the entity bridge — * driving the wp_users:wp_usermeta ratio from 1:5.5 toward 1:2.5. + * (hp_user is now registered by the HivePress AddOn.) * * V2.8.4: Adds admin_prefs group — the 7 default keys WP core writes for * EVERY new user via wp_insert_user (rich_editing, syntax_highlighting, @@ -64,7 +65,6 @@ final class TMDO_Member_Fields { self::register_core_profile_group(); self::register_social_group(); self::register_commerce_group(); - self::register_hp_user_group(); self::register_admin_prefs_group(); } @@ -414,34 +414,6 @@ final class TMDO_Member_Fields { TMDO_Entity_Registry::register_group( 'user', 'commerce', $fields ); } - /** - * 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', - ), - ) - ); - } - /** * WP-core admin pref defaults — written by `wp_insert_user()` for EVERY * new user regardless of role. Without registering these, a fresh user diff --git a/includes/integrations/class-tmdo-post-fields.php b/includes/integrations/class-tmdo-post-fields.php index c3e5574..0f2d202 100644 --- a/includes/integrations/class-tmdo-post-fields.php +++ b/includes/integrations/class-tmdo-post-fields.php @@ -2,7 +2,7 @@ /** * Post entity field registration for WP Data Optimizer (v2.9.1). * - * Registers seven post entity groups designed to absorb the bulk of + * Registers four post entity groups designed to absorb the bulk of * wp_postmeta rows that previously bypassed any flat-table strategy. * All groups use TMDO_Entity_Registry → flat tables instead of wp_postmeta EAV. * @@ -10,20 +10,20 @@ * wp_core → wp_wpdo_post_wp_core (cross post_type) * attachment → wp_wpdo_post_attachment (attachment) * wc_product → wp_wpdo_post_wc_product (product) - * hp_listing_core → wp_wpdo_post_hp_listing_core (hp_listing) - * hp_request_core → wp_wpdo_post_hp_request_core (hp_request) - * hp_vendor_core → wp_wpdo_post_hp_vendor_core (hp_vendor) * nav_menu_item → wp_wpdo_post_nav_menu_item (nav_menu_item) * * Pattern mirrors TMDO_Member_Fields::register(). Called from * TMDO_Core::run() before the wpdo_register_entity_fields action fires; - * Schema_Manager materializes the seven flat tables in init:1 + * Schema_Manager materializes the four flat tables in init:1 * via process_pending_migrations() (idempotent via schema_hash compare). * * Keys not registered here (HivePress dynamic attrs, WPCS legacy keys, * etc.) pass through to wp_postmeta unchanged — same fall-back behavior * as user entity bridge. * + * The HivePress groups (hp_listing_core / hp_request_core / hp_vendor_core) + * are registered by the HivePress AddOn (TMDO_HivePress_Entity_Groups). + * * 🔒 v2.9.x frozen contract: this class must NEVER call register_group() * with entity_type='user'. User entity registration is owned exclusively * by TMDO_Member_Fields. @@ -39,7 +39,7 @@ if ( ! defined( 'ABSPATH' ) ) { } /** - * Registers seven post entity groups. + * Registers four post entity groups. */ final class TMDO_Post_Fields { @@ -65,9 +65,6 @@ final class TMDO_Post_Fields { self::register_wp_core_group(); self::register_attachment_group(); self::register_wc_product_group(); - self::register_hp_listing_core_group(); - self::register_hp_request_core_group(); - self::register_hp_vendor_core_group(); self::register_nav_menu_item_group(); } @@ -264,176 +261,6 @@ final class TMDO_Post_Fields { ); } - /** - * 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', - ), - ), - array( 'post_types' => array( 'hp_listing' ) ) - ); - } - - /** - * 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', - ), - ), - array( 'post_types' => array( 'hp_request' ) ) - ); - } - - /** - * 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', - ), - ), - array( 'post_types' => array( 'hp_vendor' ) ) - ); - } - /** * Nav menu item meta keys (post_type=nav_menu_item). * diff --git a/tests/integration/SyncBridgeEntityGuardTest.php b/tests/integration/SyncBridgeEntityGuardTest.php index 573fea4..3f943ff 100644 --- a/tests/integration/SyncBridgeEntityGuardTest.php +++ b/tests/integration/SyncBridgeEntityGuardTest.php @@ -103,10 +103,11 @@ class SyncBridgeEntityGuardTest extends TestCase { 'indexed' => false, ) ); - // Register post adapter + post-fields groups (puts hp_price into Entity_Registry). + // Register post adapter + an entity group that owns hp_price (as the + // HivePress AddOn's hp_listing_core does). WPDO_Entity_Registry::init(); WPDO_Entity_Registry::register_adapter( 'post', new WPDO_Adapter_Post() ); - WPDO_Post_Fields::register_entity_fields(); + WPDO_Entity_Registry::register_group( 'post', 'hp_listing_core', array( array( 'key' => 'hp_price', 'type' => 'decimal', 'searchable' => true ) ) ); } public static function tearDownAfterClass(): void { diff --git a/tests/unit/EntityRegistryScopeTest.php b/tests/unit/EntityRegistryScopeTest.php index dfbb4fa..1aeb1e4 100644 --- a/tests/unit/EntityRegistryScopeTest.php +++ b/tests/unit/EntityRegistryScopeTest.php @@ -77,26 +77,4 @@ class EntityRegistryScopeTest extends TestCase { $this->assertSame( '1', TMDO_Installer::post_scoped_routing_default( 'aeav_only', false ) ); $this->assertSame( '1', TMDO_Installer::post_scoped_routing_default( 'disabled', true ) ); } - - public function test_core_hivepress_groups_are_scoped_without_changing_their_hash(): void { - TMDO_Entity_Registry::init(); - TMDO_Entity_Registry::register_adapter( 'post', $this->createMock( TMDO_Entity_Adapter_Interface::class ) ); - TMDO_Post_Fields::register_entity_fields(); - - $persisted = array( - 'hp_listing_core' => 'fb5ab760', - 'hp_request_core' => '27d6f4f5', - 'hp_vendor_core' => '5366e5c8', - ); - foreach ( $persisted as $group => $hash ) { - $fields = TMDO_Entity_Registry::get_group_fields( 'post', $group ); - $this->assertSame( $hash, substr( TMDO_Schema_Manager::calculate_schema_hash( $fields ), 0, 8 ), $group ); - } - - $this->assertSame( 'hp_listing_core', TMDO_Entity_Registry::get_field( 'post', 'hp_rating', 'hp_listing' )['group'] ); - $this->assertSame( 'hp_listing_core', TMDO_Entity_Registry::get_field( 'post', 'hp_status', 'hp_listing' )['group'] ); - $this->assertSame( 'hp_request_core', TMDO_Entity_Registry::get_field( 'post', 'hp_status', 'hp_request' )['group'] ); - $this->assertSame( 'hp_vendor_core', TMDO_Entity_Registry::get_field( 'post', 'hp_user', 'hp_vendor' )['group'] ); - $this->assertSame( 'hp_request_core', TMDO_Entity_Registry::get_field( 'post', 'hp_user', 'hp_request' )['group'] ); - } } diff --git a/tests/unit/MemberFields/MemberFieldsRegistrationTest.php b/tests/unit/MemberFields/MemberFieldsRegistrationTest.php index d80d1ae..f3dcaea 100644 --- a/tests/unit/MemberFields/MemberFieldsRegistrationTest.php +++ b/tests/unit/MemberFields/MemberFieldsRegistrationTest.php @@ -45,6 +45,12 @@ class MemberFieldsRegistrationTest extends TestCase { } } + public function test_core_registers_no_hp_user_group(): void { + WPDO_Member_Fields::register_entity_fields(); + + $this->assertSame( array(), WPDO_Entity_Registry::get_group_fields( 'user', 'hp_user' ), 'hp_user is owned by the HivePress AddOn' ); + } + // ── membership group ───────────────────────────────────────────────────── public function test_membership_group_has_six_fields(): void { diff --git a/tests/unit/PostFields/PostFieldsRegistrationTest.php b/tests/unit/PostFields/PostFieldsRegistrationTest.php index 3d1242e..42dc942 100644 --- a/tests/unit/PostFields/PostFieldsRegistrationTest.php +++ b/tests/unit/PostFields/PostFieldsRegistrationTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase; /** * Unit tests for WPDO_Post_Fields entity group registration (v2.9.1). * - * Verifies that register_entity_fields() correctly registers all seven + * Verifies that register_entity_fields() correctly registers all four * post groups with the expected field counts, types, and post_type targets. * * Mirrors MemberFieldsRegistrationTest's structure. @@ -33,16 +33,13 @@ class PostFieldsRegistrationTest extends TestCase { $this->assertTrue( true ); } - public function test_all_seven_groups_are_registered(): void { + public function test_all_four_groups_are_registered(): void { WPDO_Post_Fields::register_entity_fields(); $expected = array( 'wp_core', 'attachment', 'wc_product', - 'hp_listing_core', - 'hp_request_core', - 'hp_vendor_core', 'nav_menu_item', ); @@ -129,24 +126,15 @@ class PostFieldsRegistrationTest extends TestCase { $this->assertContains( 'outofstock', $field['options'] ); } - // ── hp_listing_core group ──────────────────────────────────────────────── + // ── HivePress groups moved to the HivePress AddOn ─────────────────────── - public function test_hp_listing_core_critical_keys_present(): void { + public function test_core_registers_no_hivepress_groups(): void { WPDO_Post_Fields::register_entity_fields(); - $keys = $this->get_field_keys( 'hp_listing_core' ); - foreach ( array( 'hp_price', 'hp_status', 'hp_featured', 'hp_verified', 'hp_vendor' ) as $key ) { - $this->assertContains( $key, $keys, "hp_listing_core missing critical key: {$key}" ); + foreach ( array( 'hp_listing_core', 'hp_request_core', 'hp_vendor_core' ) as $group ) { + $this->assertSame( array(), WPDO_Entity_Registry::get_group_fields( 'post', $group ), "{$group} is owned by the HivePress AddOn" ); } } - public function test_hp_listing_price_is_searchable_decimal(): void { - WPDO_Post_Fields::register_entity_fields(); - $field = $this->find_field( 'hp_listing_core', 'hp_price' ); - $this->assertNotNull( $field ); - $this->assertSame( 'decimal', $field['type'] ); - $this->assertTrue( (bool) ( $field['searchable'] ?? false ) ); - } - // ── nav_menu_item group ────────────────────────────────────────────────── public function test_nav_menu_item_has_8_keys(): void { diff --git a/tests/unit/PostGroupReconcilerPlanTest.php b/tests/unit/PostGroupReconcilerPlanTest.php index 4b8f3e7..72354f8 100644 --- a/tests/unit/PostGroupReconcilerPlanTest.php +++ b/tests/unit/PostGroupReconcilerPlanTest.php @@ -52,28 +52,4 @@ class PostGroupReconcilerPlanTest extends TestCase { TMDO_Entity_Registry::init(); $this->assertSame( array(), TMDO_Entity_Registry::get_group_post_types( 'post', 'listing' ) ); } - - public function test_core_hivepress_groups_plan_the_eight_misrouted_keys(): void { - TMDO_Post_Fields::register_entity_fields(); - - $moves = array(); - foreach ( TMDO_Post_Group_Reconciler::plan() as $m ) { - $moves[] = "{$m['source']}>{$m['target']}:{$m['key']}"; - } - sort( $moves ); - - $this->assertSame( - array( - 'hp_request_core>hp_listing_core:hp_expired_time', - 'hp_request_core>hp_listing_core:hp_status', - 'hp_request_core>hp_listing_core:hp_view_count', - 'hp_vendor_core>hp_listing_core:hp_hourly_rate', - 'hp_vendor_core>hp_listing_core:hp_rating', - 'hp_vendor_core>hp_listing_core:hp_rating_count', - 'hp_vendor_core>hp_listing_core:hp_verified', - 'hp_vendor_core>hp_request_core:hp_user', - ), - $moves - ); - } }