From f4eee2338bd1602b8c5397ea53d625cb2ae6a5f0 Mon Sep 17 00:00:00 2001 From: wpdev Date: Sat, 26 Sep 2026 01:16:05 +0800 Subject: [PATCH] feat(2meet-data-optimizer): flag new Hot zone registrations as deprecated - ADR-003 step 4 (core side): TMDO_Schema_Registry::register() raises _doing_it_wrong() the first time each provider registers a zone=hot field in a request (zone omitted defaults to hot). Fields still register, so existing hot data stays readable. - Cold / warm / archive registrations are unaffected. - Test bootstrap's _doing_it_wrong stub now records calls. - Verify: core unit 658 / integration 459, HP 142/49, WC 10/22 green, phpcs clean - PR: PR-038 --- includes/class-tmdo-schema-registry.php | 31 +++++++++++++++++++++++++ tests/bootstrap.php | 2 +- tests/unit/SchemaRegistryTest.php | 24 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/includes/class-tmdo-schema-registry.php b/includes/class-tmdo-schema-registry.php index 45ef898..93b390c 100644 --- a/includes/class-tmdo-schema-registry.php +++ b/includes/class-tmdo-schema-registry.php @@ -67,6 +67,13 @@ class TMDO_Schema_Registry { */ private array $warm_fields = array(); + /** + * Providers already told the Hot zone is frozen (once per request). + * + * @var array + */ + private array $hot_deprecation_flagged = array(); + /** * Private constructor — use instance() to get the singleton. */ @@ -138,6 +145,7 @@ class TMDO_Schema_Registry { switch ( $config['zone'] ) { case 'hot': $this->hot_columns[ $config['post_type'] ][ $config['column'] ] = $config['data_type']; + $this->flag_hot_deprecation( $provider, $config['meta_key'] ); break; case 'warm': @@ -159,6 +167,29 @@ class TMDO_Schema_Registry { } } + /** + * The Hot zone is frozen (ADR-003): fields still register so existing hot + * data stays readable, but each provider gets one notice per request. + * + * @param string $provider Provider name. + * @param string $meta_key First hot meta_key seen from it. + */ + private function flag_hot_deprecation( string $provider, string $meta_key ): void { + if ( isset( $this->hot_deprecation_flagged[ $provider ] ) ) { + return; + } + $this->hot_deprecation_flagged[ $provider ] = true; + _doing_it_wrong( + __CLASS__ . '::register', + sprintf( + 'Provider "%1$s" registered Hot zone field "%2$s". The Hot zone is frozen; register an entity group (TMDO_Entity_Registry::register_group) instead.', + esc_html( $provider ), + esc_html( $meta_key ) + ), + esc_html( TMDO_VERSION ) + ); + } + /** * Bulk register multiple fields. * diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2c897b0..ccef6bc 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -231,7 +231,7 @@ if ( ! function_exists( 'esc_sql' ) ) { } } if ( ! function_exists( '_doing_it_wrong' ) ) { - function _doing_it_wrong( string $fn, string $msg, string $ver ): void {} + function _doing_it_wrong( string $fn, string $msg, string $ver ): void { $GLOBALS['_doing_it_wrong_calls'][] = array( $fn, $msg ); } } if ( ! function_exists( 'get_option' ) ) { function get_option( string $key, $default = false ) { return $GLOBALS['_wp_options'][ $key ] ?? $default; } diff --git a/tests/unit/SchemaRegistryTest.php b/tests/unit/SchemaRegistryTest.php index 73cfe93..91c0af7 100644 --- a/tests/unit/SchemaRegistryTest.php +++ b/tests/unit/SchemaRegistryTest.php @@ -18,6 +18,30 @@ class SchemaRegistryTest extends TestCase { $instance->setValue( null, null ); $this->registry = WPDO_Schema_Registry::instance(); + $GLOBALS['_doing_it_wrong_calls'] = array(); + } + + // ── Hot zone deprecation (ADR-003) ────────────────────────────────────── + + public function test_hot_registration_is_flagged_once_per_provider(): void { + foreach ( array( 'p1', 'p1', 'p2' ) as $i => $provider ) { + $this->registry->register( $provider, array( 'post_type' => 'x', 'meta_key' => "k{$i}", 'zone' => 'hot' ) ); + } + $this->registry->register( 'p1', array( 'post_type' => 'x', 'meta_key' => 'k9' ) ); // zone defaults to hot. + + $calls = $GLOBALS['_doing_it_wrong_calls']; + $this->assertCount( 2, $calls ); + $this->assertStringContainsString( 'p1', $calls[0][1] ); + $this->assertStringContainsString( 'p2', $calls[1][1] ); + $this->assertSame( 'hot', $this->registry->get_field_zone( 'x', 'k9' ), 'still registered: frozen, not rejected' ); + } + + public function test_other_zones_are_not_flagged(): void { + $this->registry->register( 'p', array( 'post_type' => 'x', 'meta_key' => 'c', 'zone' => 'cold' ) ); + $this->registry->register( 'p', array( 'post_type' => 'x', 'meta_key' => 'w', 'zone' => 'warm' ) ); + $this->registry->register( 'p', array( 'post_type' => 'x', 'meta_key' => 'a', 'zone' => 'archive' ) ); + + $this->assertSame( array(), $GLOBALS['_doing_it_wrong_calls'] ); } // ── register() ──────────────────────────────────────────────────────────