4 Commits

Author SHA1 Message Date
wpdev fa356a63b1 fix(bootstrap): 舊外掛互斥偵測改查 active_plugins
Anti-EAV Lint + Quality Gate / anti-eav-lint (push) Successful in 8s
Tests / Unit Tests (push) Successful in 10s
Tests / Integration Tests (push) Successful in 33s
Tests / PHP Lint (push) Successful in 8s
Tests / PHPCS (push) Successful in 20s
Tests / PHPStan (push) Successful in 22s
Release / Test Gate (lint + phpcs + phpstan + unit + integration) (push) Successful in 1m2s
Release / release (push) Successful in 11s
WPDO_VERSION 由 class-tmdo-back-compat.php 自行 define 為 TMDO_VERSION,
兩者永遠相等,admin notice 從未觸發;PHPStan L6 認出 notIdentical.alwaysFalse
並卡掉 main run #8 與 v1.0.0 tag 的 Test Gate。改查 active_plugins basename,
與 HP AddOn detector 的偵測方式一致。
2026-07-31 09:50:23 +08:00
wpdev fbe41e2130 release: v1.0.0 — 取代 wp-data-optimizer v3.4.6
Anti-EAV Lint + Quality Gate / anti-eav-lint (push) Successful in 9s
Tests / Unit Tests (push) Successful in 10s
Tests / Integration Tests (push) Successful in 33s
Tests / PHP Lint (push) Successful in 8s
Tests / PHPCS (push) Successful in 20s
Tests / PHPStan (push) Failing after 25s
Release / Test Gate (lint + phpcs + phpstan + unit + integration) (push) Failing after 36s
Release / release (push) Has been skipped
版本 0.1.0 → 1.0.0(含 TMDO_VERSION / TWO_MEET_DATA_OPTIMIZER_VERSION /
WP_DATA_OPTIMIZER_VERSION 與 unit bootstrap)。姊妹外掛只在診斷 CLI 顯示
WP_DATA_OPTIMIZER_VERSION、無版本比較,故報 1.0.0 安全。

wp-data-optimizer 退休:兩站台已停用,本機三個目錄改名為 *.retired
(wp-data-optimizer / -v3.1.1 / _audit),git 歷史保留在 gitea。

CHANGELOG 記錄本次 backport 全貌與 4 項 ABI/行為變更。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 09:45:22 +08:00
wpdev bc4fad3b86 fix(ci): packaging 步驟不可在每次 push 執行
Anti-EAV Lint + Quality Gate / anti-eav-lint (push) Successful in 10s
Tests / Unit Tests (push) Successful in 13s
Tests / Integration Tests (push) Successful in 35s
Tests / PHP Lint (push) Successful in 9s
Tests / PHPCS (push) Successful in 24s
Tests / PHPStan (push) Successful in 26s
package-plugin.sh 依 SLUG 解析到 wp-content/plugins 下的固定路徑,打包的是
線上工作副本而非 CI 的 checkout,且會在該目錄跑 composer install --no-dev
→ 每次 push 都會把開發機的 vendor/bin 清掉(本 session 中發生兩次)。

- anti-eav-lint.yml:移除 packaging 步驟,只保留 lint
- ci-package.sh:委派共用腳本後補跑 composer install 還原 dev 依賴

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 09:31:09 +08:00
wpdev c712bf6e0a ci: 觸發首次完整 CI(secret 設定後)
Anti-EAV Lint + Quality Gate / anti-eav-lint (push) Has been cancelled
Tests / Unit Tests (push) Successful in 9s
Tests / Integration Tests (push) Successful in 33s
Tests / PHP Lint (push) Successful in 9s
Tests / PHPCS (push) Successful in 21s
Tests / PHPStan (push) Successful in 24s
首次 push 早於 TMDO_TEST_DB_PASS secret 建立,integration job 的 DB
preflight 因此拿不到密碼。此空 commit 用於驗證 secret 生效後全綠。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 09:29:14 +08:00
5 changed files with 86 additions and 17 deletions
+6 -11
View File
@@ -53,14 +53,9 @@ jobs:
echo "TMDO_HOST not found; skipping anti-eav lint" echo "TMDO_HOST not found; skipping anti-eav lint"
fi fi
- name: Packaging audit (10-check) # NOTE: no packaging audit here on purpose.
run: | # The shared package-plugin.sh resolves the plugin by SLUG to a fixed path
# package-plugin.sh lives in the wp-local-dev tree and is shared by all # under wp-content/plugins — it does NOT package the CI checkout. Running it
# custom plugins; its output goes to wp-local-dev/dist/. # from a job therefore rebuilds (and `composer install --no-dev`s) the live
PACKAGING_HOST="/var/www/Studio/wp-local-dev" # working copy, wiping the developer's vendor/bin. Packaging belongs to the
if [ -d "$PACKAGING_HOST" ]; then # release workflow / a manual run, not to every push.
SLUG="2meet-data-optimizer"
bash "$PACKAGING_HOST/scripts/package-plugin.sh" "$SLUG"
else
echo "PACKAGING_HOST not found; skipping packaging audit"
fi
+9 -5
View File
@@ -3,7 +3,7 @@
* Plugin Name: 2meet Data Optimizer * Plugin Name: 2meet Data Optimizer
* Plugin URI: https://2meet.io/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。 * Description: 通用 WordPress 反 EAV 引擎:將 postmeta / usermeta / termmeta / commentmeta 自動分流至四象限扁平表(Hot / Warm / Cold / Archive),大幅提升搜尋與篩選效能。從 wp-data-optimizer v2.16.0 提煉的純核心,整合層交給 11 個 AddOn。
* Version: 0.1.0 * Version: 1.0.0
* Requires at least: 6.0 * Requires at least: 6.0
* Tested up to: 6.9.4 * Tested up to: 6.9.4
* Requires PHP: 8.1 * Requires PHP: 8.1
@@ -26,7 +26,7 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
// ── Constants ────────────────────────────────────────────────────────────── // ── Constants ──────────────────────────────────────────────────────────────
define( 'TMDO_VERSION', '0.1.0' ); define( 'TMDO_VERSION', '1.0.0' );
define( 'TMDO_DB_VERSION', '2.1.0' ); define( 'TMDO_DB_VERSION', '2.1.0' );
define( 'TMDO_PATH', plugin_dir_path( __FILE__ ) ); define( 'TMDO_PATH', plugin_dir_path( __FILE__ ) );
define( 'TMDO_URL', plugin_dir_url( __FILE__ ) ); define( 'TMDO_URL', plugin_dir_url( __FILE__ ) );
@@ -52,12 +52,12 @@ define(
define( 'TMDO_IS_MYSQL', ! TMDO_IS_SQLITE ); define( 'TMDO_IS_MYSQL', ! TMDO_IS_SQLITE );
// ── 跨外掛偵測訊號(dual-fire 對外保留 wp-data-optimizer 訊號)──────────── // ── 跨外掛偵測訊號(dual-fire 對外保留 wp-data-optimizer 訊號)────────────
const TWO_MEET_DATA_OPTIMIZER_VERSION = '0.1.0'; const TWO_MEET_DATA_OPTIMIZER_VERSION = '1.0.0';
const TWO_MEET_DATA_OPTIMIZER_FILE = __FILE__; const TWO_MEET_DATA_OPTIMIZER_FILE = __FILE__;
const TWO_MEET_DATA_OPTIMIZER_DB_VERSION = '1.2.0'; const TWO_MEET_DATA_OPTIMIZER_DB_VERSION = '1.2.0';
// 向後相容:對外 sister plugins 仍以 WP_DATA_OPTIMIZER_VERSION 偵測。 // 向後相容:對外 sister plugins 仍以 WP_DATA_OPTIMIZER_VERSION 偵測。
if ( ! defined( 'WP_DATA_OPTIMIZER_VERSION' ) ) { if ( ! defined( 'WP_DATA_OPTIMIZER_VERSION' ) ) {
define( 'WP_DATA_OPTIMIZER_VERSION', '0.1.0' ); define( 'WP_DATA_OPTIMIZER_VERSION', '1.0.0' );
} }
if ( ! defined( 'WP_DATA_OPTIMIZER_FILE' ) ) { if ( ! defined( 'WP_DATA_OPTIMIZER_FILE' ) ) {
define( 'WP_DATA_OPTIMIZER_FILE', __FILE__ ); define( 'WP_DATA_OPTIMIZER_FILE', __FILE__ );
@@ -88,7 +88,11 @@ if ( version_compare( PHP_VERSION, TMDO_MIN_PHP, '<' ) ) {
add_action( add_action(
'admin_notices', 'admin_notices',
static function () { static function () {
if ( defined( 'WPDO_VERSION' ) && WPDO_VERSION !== TMDO_VERSION ) { // Deliberately not a WPDO_VERSION comparison: this plugin defines that
// constant itself (includes/class-tmdo-back-compat.php), so the two
// would always match and the notice could never fire.
$tmdo_legacy = 'wp-data-optimizer/wp-data-optimizer.php';
if ( in_array( $tmdo_legacy, (array) get_option( 'active_plugins', array() ), true ) ) {
echo '<div class="notice notice-error"><p>'; echo '<div class="notice notice-error"><p>';
esc_html_e( '⚠ 偵測到舊版 wp-data-optimizer 已啟用。請停用舊外掛以避免 hook 雙觸發。', '2meet-data-optimizer' ); esc_html_e( '⚠ 偵測到舊版 wp-data-optimizer 已啟用。請停用舊外掛以避免 hook 雙觸發。', '2meet-data-optimizer' );
echo '</p></div>'; echo '</p></div>';
+59
View File
@@ -7,6 +7,65 @@ Versioning follows [Semantic Versioning](https://semver.org/).
--- ---
## [1.0.0] — 2026-07-31 — 取代 wp-data-optimizer v3.4.6
本版把 `wp-data-optimizer` v3.0.1v3.4.692 個 commit)全數 backport 進來,
`wp-data-optimizer` 自此退休:兩個站台皆已停用它,本機目錄改名為
`wp-data-optimizer.retired`,其 git 歷史保留在 gitea。
### 🔒 Security / 正確性
- **7 處 `Logger::error()` 參數不足**array 傳給 string `$hook`)修正 —— 4 個 stress
tester、auto-promoter、conflict-detector、hook-bus,皆為 TypeError fatal
- **`Logger::trace_id()` 補回**`Audit_Logger::write_row()` 一直呼叫它,但提煉時漏了;
`Audit_Logger::init()` 從未註冊所以隱藏至今 —— 實機驗證才暴露
- REST 4 個公開端點加上 `show_in_rest` 欄位 allowlistCVSS 5.3
- 13 個破壞性 admin 動作由 GET 改 POST + nonce
- DDL 型別白名單(19 型別)、CLI 表名守衛
- 整欄清空改 `wpdo_allow_mass_column_clear` opt-in(原本 >500 列才擋)
- audit 表補 `group_name` / `action` 欄並註冊 `Audit_Logger::init()`
- `known_login_ips` 註冊(spoke-sso 實際寫入的欄位,先前落 `wp_usermeta`
### ⚡ 並發
- warm 表 `UNIQUE KEY ui_post_meta`(缺它 `ON DUPLICATE KEY UPDATE` 不生效)
- Zone_Cold 改 `JSON_MERGE_PATCH` / `JSON_REMOVE`、Zone_Warm 原子 `increment()`
hook-bus `write_to_flat` 改 upsert
### 🏗 架構
- 回填 `TMDO_Zone_Router` + `TMDO_Routing_Predicate`Sync_Bridge 400→269 行)
- 回填 Migration Phase Strategyinterface + base + 11 個 phase 類別,
orchestrator 1107→640 行,公開介面不變
- 核心新增 `TMDO_Standard_Post_Interceptor`HP AddOn 4 個 interceptor 573→344 行
### 🔌 相容性
- hook 橋改**雙向**:核心一律 `do_action('wpdo_*')`,原本單向轉發使所有
`tmdo_*` 契約收不到事件
- 57 個 AddOn 類別補 `WPDO_*` alias(核心 alias 表在 `plugins_loaded:4` 執行,
涵蓋不到 `:6` 才載入的 AddOn
- 38 個 CLI 子指令補 `wp tmdo` 命名空間
- 選單 slug 統一回 `wp-data-optimizer`(B 內部 10+ 處連結本來就指向它)
- HP adapter 介面改為 `TMDO_ extends WPDO_`,讓 `instanceof WPDO_HivePress_Adapter` 成立
### ✅ 品質
- 128 個生產檔 `declare(strict_types=1)`
- PHPCS 0 errors / PHPStan level 6baseline 710
- 測試:核心 unit 451 / integration 416、hivepress-addon 145、woocommerce-addon 10
- gitea CI:核心 6 個 job 全綠 + 11 個 AddOn workflow + branch protection
### ⚠️ ABI / 行為變更
- `doctor_callback` 由 3 參數改為 1 參數(表名)
- `wpdo_capture_before_value` 預設 `true``false`;需要 `value_before`
消費者(audit log)要 `add_filter( 'wpdo_capture_before_value', '__return_true' )`
- `wpdo_allow_mass_column_clear` 現為 opt-in,整欄清空預設被拒
- `SCHEMA_VERSION` 2.0.0 → 2.1.0audit 表 ALTER
---
## [0.1.0] — 2026-05-15 (initial release, Phase 0-5 完成) ## [0.1.0] — 2026-05-15 (initial release, Phase 0-5 完成)
### Phase 5 hotfix(同日完成) ### Phase 5 hotfix(同日完成)
+11
View File
@@ -19,11 +19,22 @@ SHARED_DIST="/var/www/Studio/wp-local-dev/dist"
echo "=== Packaging ${SLUG} v${VERSION} ===" echo "=== Packaging ${SLUG} v${VERSION} ==="
if [ -f "${SHARED}" ]; then if [ -f "${SHARED}" ]; then
# WARNING: package-plugin.sh resolves the plugin by SLUG to its fixed path
# under wp-content/plugins — it packages the live working copy, not this
# checkout, and runs `composer install --no-dev` there. Restore the dev
# dependencies afterwards so a developer's vendor/bin survives.
bash "${SHARED}" "${SLUG}" bash "${SHARED}" "${SLUG}"
# Surface the artefact under ./dist too so the release job's `ls dist/*.zip` # Surface the artefact under ./dist too so the release job's `ls dist/*.zip`
# works regardless of which path produced it. # works regardless of which path produced it.
mkdir -p dist mkdir -p dist
cp "${SHARED_DIST}/${SLUG}-v${VERSION}.zip" "dist/${SLUG}-v${VERSION}.zip" cp "${SHARED_DIST}/${SLUG}-v${VERSION}.zip" "dist/${SLUG}-v${VERSION}.zip"
if [ -f composer.json ]; then
echo "--- Restoring dev dependencies (package-plugin.sh ran --no-dev) ---"
composer install --no-interaction --quiet
fi
echo "=== Done: dist/${SLUG}-v${VERSION}.zip (via shared package-plugin.sh) ===" echo "=== Done: dist/${SLUG}-v${VERSION}.zip (via shared package-plugin.sh) ==="
exit 0 exit 0
fi fi
+1 -1
View File
@@ -17,7 +17,7 @@ define( 'ABSPATH', '/fake/wordpress/' );
define( 'TMDO_PATH', dirname( __DIR__ ) . '/' ); define( 'TMDO_PATH', dirname( __DIR__ ) . '/' );
define( 'TMDO_URL', 'http://localhost/wp-content/plugins/2meet-data-optimizer/' ); define( 'TMDO_URL', 'http://localhost/wp-content/plugins/2meet-data-optimizer/' );
define( 'TMDO_FILE', dirname( __DIR__ ) . '/2meet-data-optimizer.php' ); define( 'TMDO_FILE', dirname( __DIR__ ) . '/2meet-data-optimizer.php' );
define( 'TMDO_VERSION', '0.1.0' ); define( 'TMDO_VERSION', '1.0.0' );
define( 'TMDO_DB_VERSION', '2.1.0' ); define( 'TMDO_DB_VERSION', '2.1.0' );
define( 'TMDO_IS_SQLITE', false ); define( 'TMDO_IS_SQLITE', false );
define( 'TMDO_IS_MYSQL', true ); define( 'TMDO_IS_MYSQL', true );