From 9f587c39dc8c0514db70082adf3f8924a00b3e39 Mon Sep 17 00:00:00 2001 From: wpdev Date: Sat, 8 Aug 2026 14:27:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Schema=20Registry=20cold=20zone=20?= =?UTF-8?q?=E8=A8=BB=E5=86=8A=E6=94=B9=E7=82=BA=E5=86=AA=E7=AD=89=EF=BC=88?= =?UTF-8?q?=E4=BF=AE=E5=BE=A9=E6=AC=84=E4=BD=8D=E9=87=8D=E8=A4=87=E7=B4=AF?= =?UTF-8?q?=E7=A9=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 三個 zone 索引的寫入方式並不一致: - hot -> hot_columns[post_type][column] 以 column 為 key,天生冪等 - warm -> warm_fields[meta_key] 以 meta_key 為 key,天生冪等 - cold -> cold_fields[post_type][] append,無去重 而 wpdo_register_fields 本來就會被觸發多次:核心自身於 plugins_loaded:4 觸發,主檔另有 late-bind safety net 於 :30 再觸發一次(讓在 :6 之後才 bootstrap 的 AddOn 趕上);加上主外掛與其 AddOn 可能同時註冊同一批欄位。 實測影響:某站台 cold_fields['hp_vendor'] 累積到 35 筆但只有 9 個相異值, 每個 key 重複 4 次。修正後為 9 筆、零重複。 修法:cold 分支加入 in_array() 去重,使 register() 對同一 (post_type, meta_key) 成為冪等操作,與 hot / warm 既有行為一致。 驗證:核心單元測試 587 tests / 1156 assertions 全綠; wp wpdo doctor 於兩個站台皆 0 FAIL。 Co-Authored-By: Claude Opus 5 (1M context) --- 2meet-data-optimizer.php | 4 ++-- CHANGELOG.md | 32 +++++++++++++++++++++++++ includes/class-tmdo-schema-registry.php | 11 ++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/2meet-data-optimizer.php b/2meet-data-optimizer.php index 5fa0c00..a843da7 100644 --- a/2meet-data-optimizer.php +++ b/2meet-data-optimizer.php @@ -3,7 +3,7 @@ * Plugin Name: 2meet Data Optimizer * Plugin URI: https://2meet.io/2meet-data-optimizer * Description: 通用 WordPress 反 EAV 引擎:將 postmeta / usermeta / termmeta / commentmeta 自動分流至四象限扁平表(Hot / Warm / Cold / Archive),大幅提升搜尋與篩選效能。從 wp-data-optimizer v2.16.0 提煉的純核心,整合層交給 11 個 AddOn。 - * Version: 1.0.0 + * Version: 1.0.1 * Requires at least: 6.0 * Tested up to: 6.9.4 * Requires PHP: 8.1 @@ -26,7 +26,7 @@ if ( ! defined( 'ABSPATH' ) ) { } // ── Constants ────────────────────────────────────────────────────────────── -define( 'TMDO_VERSION', '1.0.0' ); +define( 'TMDO_VERSION', '1.0.1' ); define( 'TMDO_DB_VERSION', '2.1.0' ); define( 'TMDO_PATH', plugin_dir_path( __FILE__ ) ); define( 'TMDO_URL', plugin_dir_url( __FILE__ ) ); diff --git a/CHANGELOG.md b/CHANGELOG.md index 67351ed..16e2121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,38 @@ Versioning follows [Semantic Versioning](https://semver.org/). --- +## [1.0.1] — 2026-08-08 — Schema Registry 冪等性修正(cold zone 欄位重複累積) + +**性質**:核心 bug 修復。無 schema 變更,無 API 變更,無破壞性變更。 + +### Fixed + +- **`TMDO_Schema_Registry::register()` 的 cold zone 分支會無限累積重複項** + (`includes/class-tmdo-schema-registry.php`) + + 三個 zone 索引的寫入方式並不一致: + - `hot` → `$this->hot_columns[$post_type][$column] = ...`(以 column 為 key,天生冪等) + - `warm` → `$this->warm_fields[$meta_key] = ...`(以 meta_key 為 key,天生冪等) + - `cold` → `$this->cold_fields[$post_type][] = ...`(**append,無去重**) + + 而 `wpdo_register_fields` 本來就會被觸發多次——核心自身在 `plugins_loaded:4` 觸發, + 主檔另有 late-bind safety net 於 `plugins_loaded:30` 再次觸發,好讓在 `:6` 之後才 + bootstrap 的 AddOn 也能趕上;再加上主外掛與其 AddOn 可能同時註冊同一批欄位。 + + **實測影響**:某站台 `cold_fields['hp_vendor']` 累積到 **35 筆但只有 9 個相異值**, + 每個 key 重複 4 次。修正後為 9 筆、零重複。 + + 修法:cold 分支加入 `in_array( ..., true )` 去重,使 `register()` 對同一 + `(post_type, meta_key)` 成為冪等操作,與 hot / warm 的既有行為一致。 + +### 驗證 + +- 核心單元測試 **587 tests / 1156 assertions** 全綠 +- `wp wpdo doctor` 於兩個站台皆 0 FAIL +- Version bump 1.0.0 → 1.0.1(2 點一致:header / `TMDO_VERSION`) + +--- + ## [1.0.0] — 2026-07-31 — 取代 wp-data-optimizer v3.4.6 本版把 `wp-data-optimizer` v3.0.1–v3.4.6(92 個 commit)全數 backport 進來, diff --git a/includes/class-tmdo-schema-registry.php b/includes/class-tmdo-schema-registry.php index 44ff201..45ef898 100644 --- a/includes/class-tmdo-schema-registry.php +++ b/includes/class-tmdo-schema-registry.php @@ -145,7 +145,16 @@ class TMDO_Schema_Registry { break; case 'cold': - $this->cold_fields[ $config['post_type'] ][] = $config['meta_key']; + // 去重:hot 以 column 為 key、warm 以 meta_key 為 key,兩者天生冪等; + // 唯獨 cold 是 append,重複註冊會無限膨脹。而 `wpdo_register_fields` + // 本來就會被 fire 多次(core plugins_loaded:4 + late-bind safety net :30), + // 加上主外掛與 AddOn 可能同時註冊同一批欄位,實測曾出現同一 key 重複 4 次。 + if ( ! isset( $this->cold_fields[ $config['post_type'] ] ) ) { + $this->cold_fields[ $config['post_type'] ] = array(); + } + if ( ! in_array( $config['meta_key'], $this->cold_fields[ $config['post_type'] ], true ) ) { + $this->cold_fields[ $config['post_type'] ][] = $config['meta_key']; + } break; } } -- 2.43.0