refactor(2meet-data-optimizer): stop registering HivePress entity groups in core
- Drop hp_listing_core / hp_request_core / hp_vendor_core from TMDO_Post_Fields and hp_user from TMDO_Member_Fields; the HivePress AddOn registers identical definitions (PR-019/020a/033b) - Tests: core asserts it registers none of them; HP-specific core tests removed (covered by the AddOn); SyncBridgeEntityGuardTest registers its own hp_price group - Verify: core unit 633 / integration 449, HP 145/49, WC 10/22 OK - Deploy: activate the HivePress AddOn on dev20/21/22 first - PR: PR-020b
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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).
|
||||
*
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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'] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user