Files
2meet-data-optimizer-hivepr…/includes/hivepress/interface-tmdo-hp-adapter.php
T
wpdev 0a3b05789e test: 建立 phpunit 測試基建並移植 25 個 HivePress 測試
AddOn 先前 tests=0。新增:
- composer.json(dev 依賴 + phpunit/phpcs script)
- phpunit.xml(failOnWarning=true)
- tests/bootstrap.php:直接 require 核心 plugin 的 unit bootstrap,避免複製
  ~700 行 WP stub,再載入本 AddOn 的類別;補 trait wrapper 與自動 WPDO_ alias
  (includes/back-compat-aliases.php 掛在 plugins_loaded:7,PHPUnit 下不會跑)
- tests/unit/ 25 個測試 + WpdbMockTrait(自 A 移植)

生產碼一併修對外契約:interface-tmdo-hp-adapter.php 改為先宣告空的
WPDO_HivePress_Adapter、再讓 TMDO_HivePress_Adapter extends 它(PHP 無法
class_alias 介面,只有繼承能讓 instanceof WPDO_HivePress_Adapter 對
implements TMDO_ 名稱的 adapter 成立)。與核心 interface-entity-adapter.php
同一模式。這也讓第三方自訂 adapter 用舊介面名仍可通過核心檢查。

145 tests / 357 assertions GREEN

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 09:19:01 +08:00

181 lines
7.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Interface contract for a HivePress addon adapter.
*
* Each adapter represents one HivePress family plugin (`hivepress`,
* `hivepress-bookings`, `hivepress-reviews`, etc.) and is responsible for:
*
* - Declaring how to detect the addon (class / version constant)
* - Registering Hot/Warm/Cold/Archive zone field mappings owned by the addon
* - Registering entity field groups (post/user/term/comment)
* - Registering custom tables (if the addon owns its own tables)
* - Wiring query/comment routers (meta_query → JOIN rewrites)
* - Subscribing to `wpdo_after_write` for cross-addon event handling
* - Reporting an 8-dimension anti-EAV suitability score
* - Reporting health doctor probes
* - Listing the FSM migrations the adapter participates in
*
* The interface is intentionally `*_*` no-arg methods (instead of `register()`
* static entrypoint) because adapters are managed by `TMDO_HivePress_Bootstrap`
* — it instantiates one adapter per detected addon and binds the lifecycle
* methods to WPDO core hooks. Static `register()` is reserved for the
* Bootstrap itself, mirroring the existing partner-integration pattern.
*
* @package WP_Data_Optimizer
* @since 3.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! interface_exists( 'TMDO_HivePress_Adapter' ) ) {
/**
* Public surface every HivePress addon adapter MUST satisfy.
*
* The Trait `TMDO_HivePress_Adapter_Trait` provides safe no-op defaults for
* everything except `plugin_slug()` / `detection_class()` / `detection_const()`,
* so concrete adapters typically override 36 methods.
*/
// Back-compat: declare the WPDO_ marker first so TMDO_ can extend it.
// PHP class_alias() does not work on interfaces; inheritance is the only way
// to make `instanceof WPDO_HivePress_Adapter` true for adapters implementing
// the TMDO_ name. Mirrors the core's interface-entity-adapter.php.
if ( ! interface_exists( 'WPDO_HivePress_Adapter', false ) ) {
interface WPDO_HivePress_Adapter {}
}
interface TMDO_HivePress_Adapter extends WPDO_HivePress_Adapter {
/**
* Stable slug used as Schema_Registry / Custom_Table_Registry provider key.
*
* MUST exactly match the wp.org plugin slug (e.g. 'hivepress-reviews')
* so cross-tooling (CLI, admin UI, audit script) can correlate.
*/
public function plugin_slug(): string;
/**
* Fully-qualified class name whose presence indicates the addon is loaded.
*
* Adapter Bootstrap calls `class_exists()` on this string. If the addon
* publishes multiple Plugin/Core classes, return the most stable one
* (the one least likely to be renamed across releases).
*/
public function detection_class(): string;
/**
* Version constant whose `defined()` indicates the addon is loaded.
*
* Used as a backup signal when `class_exists()` is too late (e.g.
* adapters need the version string for compatibility gating). Return
* empty string when the addon does not expose a version constant.
*/
public function detection_const(): string;
/**
* Minimum HivePress addon version this adapter supports.
*
* Bootstrap compares against `defined($detection_const)` value and
* downgrades to `idle` mode (no hooks bound) when the installed
* version is below this floor. Return empty string to skip gating.
*/
public function minimum_addon_version(): string;
/**
* Register Hot/Warm/Cold/Archive zone field mappings.
*
* Called by Bootstrap on the `wpdo_register_fields` action, which fires
* inside `TMDO_Core::run()` at `plugins_loaded:4`. Schema_Registry
* already has internal dedup so re-firing on `init:1` is safe.
*
* @param TMDO_Schema_Registry $registry Singleton.
*/
public function on_register_fields( TMDO_Schema_Registry $registry ): void;
/**
* Register entity field groups (post/user/term/comment).
*
* Called on `wpdo_register_entity_fields`. Adapters that contribute
* user/term/comment fields (e.g. core adapter for hp_user) hook here.
*/
public function on_register_entity_fields(): void;
/**
* Register custom tables owned by the adapter (e.g. comment hot tables).
*
* Called on `wpdo_register_custom_tables`. Each table SHOULD include
* `expected_columns` + `expected_indexes` so `wp wpdo doctor` can
* validate. Tables are NOT created here — adapters declare ownership
* for tooling; actual DDL is owned by `TMDO_Schema_Manager`.
*
* @param TMDO_Custom_Table_Registry $registry Singleton.
*/
public function on_register_custom_tables( TMDO_Custom_Table_Registry $registry ): void;
/**
* Register WP_Query / WP_Comment_Query rewriting hooks.
*
* Adapters with hot zone fields used in search/filter MUST register a
* `pre_get_posts` / `pre_get_comments` filter that defers to
* `TMDO_HivePress_Query_Router` / `..._Comment_Router`.
*
* Called on `init:5` after Schema_Registry is fully populated.
*/
public function on_register_query_hooks(): void;
/**
* Subscribe to `wpdo_after_write` for cross-adapter event handling.
*
* Adapters that participate in cross-cutting workflows (e.g. listing
* sold-out → block bookings) hook here. Called once during boot.
*/
public function on_register_event_hooks(): void;
/**
* Self-report 8-dimension anti-EAV suitability score.
*
* Returns a flat array with keys `d1_meta_calls .. d8_perf` (each
* 0.01.0) plus an `aggregate` key (0.010.0). The
* `TMDO_HivePress_Suitability_Scorer` may inspect adapter source to
* verify, but the adapter's self-report is the primary signal.
*
* Concrete implementation guidance:
* D1: 1.0 if adapter never calls *_meta() directly, only TMDO_API
* D2: 1.0 if no hardcoded wp_postmeta etc. literals
* D3: 1.0 if every hot meta_key has a registered hot column
* D4: 1.0 if every registered table includes expected_columns + indexes
* D5: 1.0 if adapter subscribes to wpdo_after_write (when applicable)
* D6: 1.0 if zero autoload=yes options + zero raw transients
* D7: 1.0 if no direct queries against another adapter's tables
* D8: 1.0 if EXPLAIN of representative queries shows index scan only
*
* @return array{d1_meta_calls:float, d2_meta_sql:float, d3_table_coverage:float, d4_registry_meta:float, d5_hook_bus:float, d6_options:float, d7_coupling:float, d8_perf:float, aggregate:float}
*/
public function suitability_score(): array;
/**
* Health doctor probe — table existence, row counts, index sanity.
*
* Called by `wp wpdo hivepress doctor` and admin UI HivePress tab.
* MUST never throw; catch and report as `ok=false` with message.
*
* @return array{ok:bool, message:string, details?:array<string,mixed>}
*/
public function doctor_check(): array;
/**
* Module names this adapter contributes to the 7-state FSM.
*
* Each module is independently transitionable via `wp wpdo migrate
* <module>` etc. Names MUST be unique across adapters and align with
* `TMDO_Feature_Flags::ZONE_MODULES` registry conventions.
*
* @return array<int, string> e.g. ['hot_hp_listing', 'hot_hp_request']
*/
public function migrations(): array;
}
} // end if ( ! interface_exists )