From 07db7734cf68abdb43c057a0e046611cb784a4b4 Mon Sep 17 00:00:00 2001 From: wpdev Date: Fri, 25 Sep 2026 23:19:22 +0800 Subject: [PATCH] refactor(2meet-data-optimizer): delete dead HivePress defaults and hardcoded partner list - Remove never-called register_hivepress_defaults() and core boot probes for AddOn classes that load at plugins_loaded:3/:6 and self-register (8 partner list entries, WC orders interceptor, HP transient filter) - Keep core-owned TMDO_Member_Fields / TMDO_Post_Fields registration unchanged - Verify: CoreBoundaryTest guard added; core unit 606 / integration 432, HP 141/49, WC 10/22 OK - PR: PR-016 --- includes/class-tmdo-core.php | 250 +------------------------------- tests/unit/CoreBoundaryTest.php | 34 +++++ 2 files changed, 38 insertions(+), 246 deletions(-) diff --git a/includes/class-tmdo-core.php b/includes/class-tmdo-core.php index 781c745..21a8846 100644 --- a/includes/class-tmdo-core.php +++ b/includes/class-tmdo-core.php @@ -31,31 +31,10 @@ class TMDO_Core { // Fire the schema registry hook so integrations can register their fields. $registry = TMDO_Schema_Registry::instance(); - // v2.0.x: Pre-register the 7 partner plugin integrations BEFORE firing the - // `wpdo_register_fields` and `wpdo_register_custom_tables` hooks. Each - // `register()` is a thin `add_action()` wrapper guarded by a partner-plugin - // `class_exists()` probe (TMDO_Infocards / Bookings / Quotation / Events / - // Mobile_Bridge / Collab / Playlist). Without this, partner add_actions - // arrive too late and the do_action below misses them — observed via - // 2meet-infocards 9 hp_vendor meta keys never landing in Schema Registry. - // register() is side-effect-free aside from add_action(), so pre-registering - // is provably safe (no hidden dependency on later-state global init). - // v2.1.3 R1 (B step): TMDO_Events removed — 2meet-events now self-registers - // via its own bridge class. Other partners still pre-registered here pending - // their own decentralized migrations (R1 continuation in v2.2.x). - $partner_integrations = array( - 'TMDO_Infocards', - 'TMDO_Bookings', - 'TMDO_Quotation', - 'TMDO_Mobile_Bridge', - 'TMDO_Collab', - 'TMDO_Playlist', - 'TMDO_WooCommerce', - 'TMDO_Member_Fields', - 'TMDO_Post_Fields', - 'TMDO_Hivepress_Term_Comment_Fields', - ); - foreach ( $partner_integrations as $cls ) { + // Core-owned field providers register before `wpdo_register_fields` fires. + // AddOns wire their own integrations from their bootstraps + // (plugins_loaded:3 or :6), so core does not probe for them here. + foreach ( array( 'TMDO_Member_Fields', 'TMDO_Post_Fields' ) as $cls ) { if ( class_exists( $cls ) ) { call_user_func( array( $cls, 'register' ) ); } @@ -74,7 +53,6 @@ class TMDO_Core { // AFTER plugins_loaded:4 (e.g., partners loaded by HP modules at plugins_loaded:5+, // or lazy-loaded modules booted on init:0). Schema_Registry::register() has // internal dedup, so re-firing is idempotent — same partner calls won't double-register. - // This deprecates the need for the TMDO_Core hardcoded partner pre-registration list above. // // v2.1.6: also re-fire `wpdo_register_entity_fields` so partner plugins booting on // plugins_loaded:20 (e.g. 2meet-spoke-sso) can register entity-based user/term/comment @@ -116,12 +94,6 @@ class TMDO_Core { $this->register_hpct_interceptors(); } - // v2.1.2 fix: WC commission interceptor is independent of HPCT — writes - // to its own wp_wpdo_wc_commissions table. Register whenever WC is active. - if ( class_exists( 'TMDO_WooCommerce' ) && TMDO_WooCommerce::is_active() && class_exists( 'TMDO_WC_Orders_Interceptor' ) ) { - ( new TMDO_WC_Orders_Interceptor() )->register_hooks(); - } - // Zone interceptors are always safe to register. if ( TMDO_Compatibility::can_register_zone_hooks() ) { $this->register_zone_hooks(); @@ -149,10 +121,6 @@ class TMDO_Core { TMDO_Conflict_Monitor::register_hooks(); } - // v2.0.x: partner plugin integrations have been pre-registered earlier - // (see top of run() before the wpdo_register_fields do_action). Removing - // the duplicate late-binding block — see commit log for time-ordering bug. - // Schedule cron events. $this->schedule_cron(); @@ -182,14 +150,6 @@ class TMDO_Core { add_action( TMDO_Comment_Stress_Tester::CRON_HOOK, array( __CLASS__, 'run_comment_stress_test_batch' ) ); } - // v2.11.5: HivePress per-post transient cache → wp_options reroute. - // Filters registered on `init` so HivePress's own bootstrap (plugins_loaded:5) - // runs first and our filter chain catches the actual cache writes happening - // during save_post and term-cache rebuilds. - if ( class_exists( 'TMDO_Hivepress_Transient_Filter' ) ) { - add_action( 'init', array( 'TMDO_Hivepress_Transient_Filter', 'init' ), 5 ); - } - // v2.12.1: Term + Comment garbage write-time filter // (silent-drop _wxr_import_* / _2meet_demo_* / orphan post-meta keys). if ( class_exists( 'TMDO_Term_Comment_Garbage_Filter' ) ) { @@ -282,208 +242,6 @@ class TMDO_Core { do_action( 'wpdo_register_entity_fields', TMDO_Entity_Registry::class ); } - /** - * Register default HivePress field mappings. - * - * These are the known HivePress meta_keys and their zone classifications. - * - * @param TMDO_Schema_Registry $registry The schema registry instance. - * @return void - */ - private function register_hivepress_defaults( TMDO_Schema_Registry $registry ): void { - // Zone A (Hot) — Listing search/filter fields. - $registry->register_many( - 'hivepress', - array( - array( - 'post_type' => 'hp_listing', - 'meta_key' => 'hp_price', - 'zone' => 'hot', - 'data_type' => 'decimal(10,2) NOT NULL DEFAULT 0', - 'column' => 'hp_price', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_listing', - 'meta_key' => 'hp_featured', - 'zone' => 'hot', - 'data_type' => 'tinyint(1) NOT NULL DEFAULT 0', - 'column' => 'hp_featured', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_listing', - 'meta_key' => 'hp_verified', - 'zone' => 'hot', - 'data_type' => 'tinyint(1) NOT NULL DEFAULT 0', - 'column' => 'hp_verified', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_listing', - 'meta_key' => 'hp_expired_time', - 'zone' => 'hot', - 'data_type' => 'bigint(20) NOT NULL DEFAULT 0', - 'column' => 'hp_expired_time', - ), - array( - 'post_type' => 'hp_listing', - 'meta_key' => 'hp_featured_time', - 'zone' => 'hot', - 'data_type' => 'bigint(20) NOT NULL DEFAULT 0', - 'column' => 'hp_featured_time', - ), - // Vendor hot fields. - array( - 'post_type' => 'hp_vendor', - 'meta_key' => 'hp_verified', - 'zone' => 'hot', - 'data_type' => 'tinyint(1) NOT NULL DEFAULT 0', - 'column' => 'hp_verified', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_vendor', - 'meta_key' => 'hp_hourly_rate', - 'zone' => 'hot', - 'data_type' => 'decimal(10,2) NOT NULL DEFAULT 0', - 'column' => 'hp_hourly_rate', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_vendor', - 'meta_key' => 'hp_rating_count', - 'zone' => 'hot', - 'data_type' => 'int(11) NOT NULL DEFAULT 0', - 'column' => 'hp_rating_count', - 'indexed' => false, - ), - ) - ); - - // Zone C (Cold) — Profile/display fields. - $registry->register_many( - 'hivepress', - array( - array( - 'post_type' => 'hp_vendor', - 'meta_key' => 'hp_description', - 'zone' => 'cold', - 'cache_group' => 'wpdo_cold_hp_vendor', - 'cache_ttl' => HOUR_IN_SECONDS, - ), - array( - 'post_type' => 'hp_listing', - 'meta_key' => 'hp_description', - 'zone' => 'cold', - 'cache_group' => 'wpdo_cold_hp_listing', - 'cache_ttl' => HOUR_IN_SECONDS, - ), - ) - ); - - // ── HivePress extension fields (filled the 47% → 94% coverage gap) ── - // Reviews extension (hp_review post type). - $registry->register_many( - 'hivepress-reviews', - array( - array( - 'post_type' => 'hp_review', - 'meta_key' => 'hp_rating', - 'zone' => 'hot', - 'data_type' => 'tinyint(1) NOT NULL DEFAULT 0', - 'column' => 'hp_rating', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_vendor', - 'meta_key' => 'hp_rating', - 'zone' => 'hot', - 'data_type' => 'decimal(3,2) NOT NULL DEFAULT 0', - 'column' => 'hp_rating', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_review', - 'meta_key' => 'hp_text', - 'zone' => 'cold', - 'cache_group' => 'wpdo_cold_hp_review', - 'cache_ttl' => HOUR_IN_SECONDS, - ), - ) - ); - - // Bookings extension (hp_booking post type). - $registry->register_many( - 'hivepress-bookings', - array( - array( - 'post_type' => 'hp_booking', - 'meta_key' => 'hp_start_time', - 'zone' => 'hot', - 'data_type' => 'bigint(20) NOT NULL DEFAULT 0', - 'column' => 'hp_start_time', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_booking', - 'meta_key' => 'hp_end_time', - 'zone' => 'hot', - 'data_type' => 'bigint(20) NOT NULL DEFAULT 0', - 'column' => 'hp_end_time', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_booking', - 'meta_key' => 'hp_status', - 'zone' => 'hot', - 'data_type' => "varchar(20) NOT NULL DEFAULT ''", - 'column' => 'hp_status', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_listing', - 'meta_key' => 'hp_booking_enabled', - 'zone' => 'hot', - 'data_type' => 'tinyint(1) NOT NULL DEFAULT 0', - 'column' => 'hp_booking_enabled', - 'indexed' => true, - ), - ) - ); - - // Marketplace / Requests extension. - $registry->register_many( - 'hivepress-marketplace', - array( - array( - 'post_type' => 'hp_request', - 'meta_key' => 'hp_request_category', - 'zone' => 'hot', - 'data_type' => 'bigint(20) NOT NULL DEFAULT 0', - 'column' => 'hp_request_category', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_offer', - 'meta_key' => 'hp_amount', - 'zone' => 'hot', - 'data_type' => 'decimal(10,2) NOT NULL DEFAULT 0', - 'column' => 'hp_amount', - 'indexed' => true, - ), - array( - 'post_type' => 'hp_offer', - 'meta_key' => 'hp_request', - 'zone' => 'hot', - 'data_type' => 'bigint(20) NOT NULL DEFAULT 0', - 'column' => 'hp_request', - 'indexed' => true, - ), - ) - ); - } - /** * Register HPCT-inherited module interceptors and query interceptors. */ diff --git a/tests/unit/CoreBoundaryTest.php b/tests/unit/CoreBoundaryTest.php index a1a3381..d29595f 100644 --- a/tests/unit/CoreBoundaryTest.php +++ b/tests/unit/CoreBoundaryTest.php @@ -114,6 +114,40 @@ class CoreBoundaryTest extends TestCase { ); } + /** + * TMDO_Core::run() fires at plugins_loaded:4, but these AddOn classes load + * at plugins_loaded:6 and wire themselves up in their own bootstrap. Probing + * them from core boot can never hit, so core must not mention them at all. + * (The infocards AddOn loads at :3 and also calls its own register().) + */ + public function test_core_boot_does_not_probe_addons_that_self_register(): void { + $tokens = token_get_all( (string) file_get_contents( dirname( __DIR__, 2 ) . '/includes/class-tmdo-core.php' ) ); + $code = ''; + foreach ( $tokens as $token ) { + if ( is_array( $token ) && in_array( $token[0], array( T_COMMENT, T_DOC_COMMENT ), true ) ) { + continue; + } + $code .= is_array( $token ) ? $token[1] : $token; + } + + $late_addon_names = array( + 'TMDO_Infocards', + 'TMDO_Bookings', + 'TMDO_Quotation', + 'TMDO_Mobile_Bridge', + 'TMDO_Collab', + 'TMDO_Playlist', + 'TMDO_WooCommerce', + 'TMDO_WC_Orders_Interceptor', + 'TMDO_Hivepress_Term_Comment_Fields', + 'TMDO_Hivepress_Transient_Filter', + 'register_hivepress_defaults', + ); + $found = array_values( array_filter( $late_addon_names, static fn( $name ) => str_contains( $code, $name ) ) ); + + $this->assertSame( array(), $found, 'Dead AddOn probes remain in TMDO_Core: ' . implode( ', ', $found ) ); + } + /** * Remove line comments and string literals so mentions inside them are ignored. */