8 Commits

Author SHA1 Message Date
wpdev e33ae4e626 test(boundary): 新增 CoreBoundaryTest,並補完 PR-I 的兩個缺漏測試
Anti-EAV Lint + Quality Gate / anti-eav-lint (push) Successful in 9s
Tests / Unit Tests (push) Successful in 9s
Tests / Integration Tests (push) Successful in 31s
Tests / PHP Lint (push) Successful in 8s
Tests / PHPCS (push) Successful in 20s
Tests / PHPStan (push) Successful in 24s
CoreBoundaryTest 靜態掃描核心 126 個生產檔,斷言每一處對 AddOn 類別的
static 呼叫都在同一個函式內有 class_exists() 守衛。上一個 commit 修的
TMDO_Listing_Stats fatal 就是這類缺陷,這個測試讓它不會再回來。

它當場又抓到 3 處同類違規(都是實際會 fatal 的路徑),一併修掉:
- admin render_hpct_import():改印 admin notice 並 return
- wp tmdo import-hpct:改 WP_CLI::error 明示需要 hivepress-addon
- cli-post cleanup-hp-transients 其實早有守衛,是測試的行距啟發式太窄;
  判斷範圍改成「同一個函式內」而非固定 12 行

負向驗證:暫時注入一處無守衛呼叫 → 測試如預期失敗;還原後回綠。

同時補完計畫階段 7 PR-I 列的兩個缺漏測試:
- 核心 tests/unit/StandardPostInterceptorTest.php(10 tests)
- HP AddOn tests/unit/ListingStatsTest.php(9 tests)——AddOn 的 unit
  bootstrap 先前刻意不載入真實 TMDO_Listing_Stats,改以
  TMDO_TEST_SKIP_LISTING_STATS_STUB 常數讓它跳過核心的 stub
- 核心 unit bootstrap 補 add_post_meta() stub(flush 路徑用得到)

核心 unit 451 → 587、HP AddOn 145 → 154。
2026-07-31 10:41:13 +08:00
wpdev 6751c69bc2 fix(boundary): 核心不得無守衛呼叫 AddOn 的 TMDO_Listing_Stats
實機渲染時 Dashboard 分頁 fatal:"Class TMDO_Listing_Stats not found"。
該類別住在 hivepress-addon,核心有 6 處直呼,沒裝 AddOn 的站台會炸掉
Dashboard 與兩個 REST 端點(GET /listing/{id}、POST /listing/{id}/view)。

- TMDO_Zone_Warm 新增 VIEW_KEY / VIEW_TTL 常數(值與 AddOn 的
  TMDO_Listing_Stats::VIEW_KEY 完全相同的 'wpdo_views',指向同一批列,
  無資料遷移)
- CLI benchmark 改用核心常數
- REST 兩個 handler 改走新的 read_view_count() / bump_view_count():
  AddOn 在場時仍委派過去(保留 hp_view_count postmeta fallback),
  否則核心自己讀寫 warm 列
- wp tmdo cleanup --archive-expired 加守衛,AddOn 缺席時印 warning 並跳過
2026-07-31 10:34:40 +08:00
wpdev f524ea3f16 build: 移植 PHPCS + PHPStan L6 品質 gate(PR-I 前半)
- phpcs.xml(自 A 移植):ruleset 改名、*/tools/* 例外換成 */back-compat/*、
  中文註解全域排除 Squiz.Commenting.InlineComment.InvalidEndChar、
  interface 別名檔排除 OneObjectStructurePerFile
- 檔頭正規化:16 個檔案的 declare(strict_types=1) 與前導 // 註解移到
  file docblock 之後,並移除 <?php 後多餘空行(phpcbf 另自動修 190 處)
- phpstan.neon + .phpstan/stubs.php(TMDO_ 與 WPDO_ 兩套常數)+
  重新產生的 phpstan-baseline.neon(710 errors,A 的 3877 行 baseline
  因前綴與路徑不同無法沿用)

現況:PHPCS 0 errors / 0 warnings、PHPStan L6 No errors、
unit 451 / integration 398 GREEN

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 06:22:00 +08:00
wpdev 76c01e44df refactor: 全部 128 個生產檔加入 declare(strict_types=1)(PR-H)
對齊 A v3.2.0。型別強制會把隱式轉換變成 TypeError,所以一次全檔加入
並跑完整測試(unit 451 / integration 398 全綠,無迴歸)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 06:13:33 +08:00
wpdev d6c1540444 feat(diagnostics): crypto 健檢 + backup 目錄探測 + 15 個 usermeta 欄位(PR-G)
- Crypto::is_key_derivable()(A v3.3.2):AUTH_KEY / SECURE_AUTH_SALT 皆缺
  時回 false,讓金鑰推導優雅短路
- wp tmdo doctor 新增兩項健檢:
  · backup 目錄 HTTP 可及性探測(200 = 紅旗並附 nginx 設定建議,
    403/404 = OK,0 = 離線時退回檢查 .htaccess)(A v3.1.9)
  · crypto 金鑰可推導性(缺常數時警告 notifier secrets 會以明文儲存)
- doctor_callback 呼叫簽章 3 參數 → 1 參數(A v3.0.3 修復)。**ABI 變更**:
  AddOn 註冊的 callback 若依賴 rows / full_name 需自行調整
- Member_Fields::register_admin_prefs_group() 由 7 欄擴到 22 欄(A v3.1.4),
  補上 wp_user_level / show_welcome_panel / wp_persisted_preferences /
  wp_user-settings / community-events-location 等 15 個 WP 原生 usermeta,
  這些先前全部落在 wp_usermeta
- capture_before_value 預設 true → false(A v3.1.5):每次受管寫入省一次
  DB read。**行為變更**:需要 value_before 的消費者(audit log)要
  add_filter( 'wpdo_capture_before_value', '__return_true' ) 明確開啟

unit 451 / integration 398 GREEN

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 06:11:52 +08:00
wpdev a8190a6828 fix(compat): CLI 雙命名空間 + 選單 slug 對齊 + i18n text domain(E4/E6/E7)
E4:38 個子指令補 'wp tmdo' 註冊(原本只有 'wp wpdo')
    cli-v2 15、cli-post 8、cli-member 7、cli-term-comment 8。
    CLAUDE.md 宣稱 tmdo 為主命名空間,但 wp tmdo bridge-status /
    snapshot create 等先前根本不存在。

E6:MENU_SLUG 由 '2meet-data-optimizer' 改回 'wp-data-optimizer'。
    B 內部有 10+ 處連結(help-tabs、setup-wizard ×5、conflict-monitor、
    export、3 個 template)硬編碼舊 slug,與註冊值不符 → 這些連結目前
    全部 404。既然本外掛已沿用 wpdo_ 的表/option/cron/hook/CLI 命名空間,
    選單 slug 一併回到同一套最連貫,A 退休後亦無衝突。

E7:13 處殘留的 'uae' text domain 改為 '2meet-data-optimizer'
    (conflict-detector 3、mode-manager 9、entity-migration-engine 1;
    另一處 'uae' 是陣列 key 非 text domain,保留)。

unit 451 / integration 398 GREEN

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 06:02:19 +08:00
wpdev fa31a0527b feat(security): DDL 型別白名單 + CLI 表名守衛(A7/A8)
- TMDO_Installer::ALLOWED_COL_BASE_TYPES(19 型別)+ validate_col_type(),
  在 ALTER TABLE ADD COLUMN 與 CREATE TABLE 組欄位前驗證:先前 partner
  plugin 經 Schema Registry 提供的 $col_type 直接拼進 DDL。
- TMDO_CLI::assert_safe_table_name(),守 doctor 的 SHOW COLUMNS / PRAGMA
  與 benchmark 的 COUNT(*) 三處無法 prepare 的識別字。

對應 A v3.3.4。unit 379 / integration 398 GREEN

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 05:18:55 +08:00
wpdev d36bb954d1 chore: initial snapshot of 2meet-data-optimizer v0.1.0
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6.

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