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
This commit is contained in:
2026-07-31 05:06:36 +08:00
commit d36bb954d1
206 changed files with 66538 additions and 0 deletions
+221
View File
@@ -0,0 +1,221 @@
<?php
/**
* TMDO_Help_Tabs — Contextual help tabs (v2.3.0 M8).
*
* Registers `add_help_tab()` content on the WPDO admin page. Each tab gets a
* dedicated help panel that explains:
* - what this tab is for
* - what to do here as a first-time user
* - links to Entity Bridge, Snapshots, Doctor when relevant
*
* Hooked on `load-tools_page_wp-data-optimizer` so help tabs only appear on
* our admin page (not site-wide).
*
* @package WP_Data_Optimizer
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Help tab registrar — stateless static API.
*/
class TMDO_Help_Tabs {
/**
* Hook into admin page load.
*
* @return void
*/
public static function register(): void {
add_action( 'load-tools_page_wp-data-optimizer', array( __CLASS__, 'add_tabs' ) );
}
/**
* Register help tabs based on current `tab` GET param.
*
* @return void
*/
public static function add_tabs(): void {
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
if ( null === $screen ) {
return;
}
$tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( (string) $_GET['tab'] ) ) : 'dashboard'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
// Always-on overview tab.
$screen->add_help_tab(
array(
'id' => 'wpdo-help-overview',
'title' => __( '什麼是 WPDO', '2meet-data-optimizer' ),
'content' => self::content_overview(),
)
);
// Per-tab help (matches whichever tab is active).
$tab_help = array(
'dashboard' => array( __( '儀表板閱讀指南', '2meet-data-optimizer' ), 'content_dashboard' ),
'zones' => array( __( '4 個 Zone 是什麼', '2meet-data-optimizer' ), 'content_zones' ),
'classifier' => array( __( 'Classifier 解讀', '2meet-data-optimizer' ), 'content_classifier' ),
'snapshots' => array( __( '備份策略', '2meet-data-optimizer' ), 'content_snapshots' ),
'conflicts' => array( __( '衝突處理', '2meet-data-optimizer' ), 'content_conflicts' ),
'doctor' => array( __( '健康檢查解讀', '2meet-data-optimizer' ), 'content_doctor' ),
'logs' => array( __( '日誌使用', '2meet-data-optimizer' ), 'content_logs' ),
'rest-api' => array( __( 'REST API', '2meet-data-optimizer' ), 'content_rest_api' ),
);
if ( isset( $tab_help[ $tab ] ) ) {
[ $title, $cb ] = $tab_help[ $tab ];
$screen->add_help_tab(
array(
'id' => 'wpdo-help-' . $tab,
'title' => $title,
'content' => call_user_func( array( __CLASS__, $cb ) ),
)
);
}
// Sidebar with persistent links.
$screen->set_help_sidebar(
'<p><strong>' . esc_html__( '更多資源', '2meet-data-optimizer' ) . '</strong></p>'
. '<p><a href="' . esc_url( admin_url( 'tools.php?page=wp-data-optimizer&tab=entity-bridge' ) ) . '">' . esc_html__( 'Entity Bridge — 主維運入口', '2meet-data-optimizer' ) . '</a></p>'
. '<p><a href="' . esc_url( admin_url( 'site-health.php' ) ) . '">' . esc_html__( 'WP Site Health', '2meet-data-optimizer' ) . '</a></p>'
. '<p><code>wp wpdo doctor</code><br/><code>wp wpdo mode-audit</code><br/><code>wp wpdo snapshot create</code></p>'
);
}
// ─── content templates ─────────────────────────────────────────────
/**
* Overview help content.
*
* @return string
*/
private static function content_overview(): string {
return '<p>' . esc_html__( 'WP Data Optimizer 是反 EAVmeta 爆炸)的解方。', '2meet-data-optimizer' ) . '</p>'
. '<p>' . esc_html__( '核心概念:把 wp_postmeta 的高頻欄位(Hot)、TTL 暫存(Warm)、低頻欄位(Cold)、歷史資料(Archive)拆到 4 種專用表,讀寫快很多、autoload 不再爆。', '2meet-data-optimizer' ) . '</p>'
. '<p><strong>' . esc_html__( '建議第一步:', '2meet-data-optimizer' ) . '</strong> ' . esc_html__( '逛一遍儀表板了解現況 → 看 Entity Bridge tab 各 entity 健康卡片 → 從 1 個 entity 開始用 Migration Wizard 漸進升級 mode。', '2meet-data-optimizer' ) . '</p>';
}
/**
* Dashboard help content.
*
* @return string
*/
private static function content_dashboard(): string {
return '<p>' . esc_html__( '儀表板顯示:', '2meet-data-optimizer' ) . '</p>'
. '<ul style="list-style: disc; padding-left: 1.5em;">'
. '<li>' . esc_html__( 'System Overview — DB 引擎、HivePress、HPCT、Object Cache 是否啟用', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( 'Zone 行數統計 — Hot/Warm/Cold/Archive 各自累積多少資料', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( 'Module 狀態 — 每個 module 在 7-state FSM 哪一格', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( 'Warm zone live view — 哪些 view counts / TTL 進來、24h 快過期數', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( 'Archive 統計 — 壓縮率、依 post_type 拆分', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( 'REST API rate limit — 429 事件 + Top 10 受限 post', '2meet-data-optimizer' ) . '</li>'
. '</ul>';
}
/**
* Zones help content.
*
* @return string
*/
private static function content_zones(): string {
return '<p>' . esc_html__( '4 個 Zone 對應不同存取頻率與保留需求:', '2meet-data-optimizer' ) . '</p>'
. '<ul style="list-style: disc; padding-left: 1.5em;">'
. '<li><strong>Hot</strong> — ' . esc_html__( '高頻索引欄位,如 listing 的 price / location。獨立 column + indexWP_Query 可 JOIN。', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>Warm</strong> — ' . esc_html__( 'TTL 暫存(如 view count、cache stats)。固定表 wp_wpdo_warm 含 expires_at。', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>Cold</strong> — ' . esc_html__( '低頻 metasettings / preferences)。讀寫透過 interceptor 攔截後保持 EAV 形式。', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>Archive</strong> — ' . esc_html__( 'Trashed / 90+ 天舊資料。可 gzip 壓縮。', '2meet-data-optimizer' ) . '</li>'
. '</ul>'
. '<p>' . esc_html__( '不確定要哪種 → 用 Classifier,它會看 access pattern 給建議。', '2meet-data-optimizer' ) . '</p>';
}
/**
* Classifier help content.
*
* @return string
*/
private static function content_classifier(): string {
return '<p>' . esc_html__( 'Classifier 分析 wp_postmeta 給每個 meta_key 一個 zone 建議:', '2meet-data-optimizer' ) . '</p>'
. '<ul style="list-style: disc; padding-left: 1.5em;">'
. '<li><strong>Confidence</strong> — ' . esc_html__( '0.0~1.0,越高代表分類越確定。≥ 0.8 可放心採納,< 0.5 建議 manual review。', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>Reasons</strong> — ' . esc_html__( '說明為什麼建議這個 zoneaccess frequency / row count / TTL hints)。', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>Already-assigned</strong> — ' . esc_html__( '已透過 Schema_Registry 註冊的 meta_key 數量。', '2meet-data-optimizer' ) . '</li>'
. '</ul>';
}
/**
* Snapshots help content.
*
* @return string
*/
private static function content_snapshots(): string {
return '<p>' . esc_html__( '快照保留政策(v2.2.0):', '2meet-data-optimizer' ) . '</p>'
. '<ul style="list-style: disc; padding-left: 1.5em;">'
. '<li>' . esc_html__( '預設 30 天 TTL,可在 wp wpdo snapshot create 時用 --retention-days 覆蓋。', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( 'pre_uninstall / pre_v2_upgrade triggers 受 size-cap 保護(不會被自動 evict)。', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( '檔案存於 wp-content/uploads/wpdo-backups/,含 .htaccess deny all + 每個檔 sha256 校驗。', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( '小於 5MB 自動 inline 到 wp_wpdo_snapshots.inline_blob,方便 wp db export 時跟著走。', '2meet-data-optimizer' ) . '</li>'
. '</ul>'
. '<p><strong>' . esc_html__( '災難還原 drill', '2meet-data-optimizer' ) . '</strong>'
. esc_html__( '建議每月做一次 dry-run 還原驗證 — wp wpdo snapshot restore <id>(不加 --apply)即可預覽會還原什麼。', '2meet-data-optimizer' ) . '</p>';
}
/**
* Conflicts help content.
*
* @return string
*/
private static function content_conflicts(): string {
return '<p>' . esc_html__( 'Hook 衝突偵測:當多個 plugin 在同一 WordPress 的 metadata filter 上掛 callback 時,可能造成資料寫入順序不確定 / 重複處理。', '2meet-data-optimizer' ) . '</p>'
. '<p>' . esc_html__( '常見原因:', '2meet-data-optimizer' ) . '</p>'
. '<ul style="list-style: disc; padding-left: 1.5em;">'
. '<li>' . esc_html__( 'Hook Bus 啟用(wpdo_hook_bus_enabled = 1+ legacy interceptors 還沒卸載', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( 'HPCT (HP Custom Tables) plugin 還沒移除 — 與 WPDO 同時攔截', '2meet-data-optimizer' ) . '</li>'
. '</ul>'
. '<p>' . esc_html__( '解法:先看 conflict-scan 詳情,必要時用 wp wpdo bridge-set off 暫停 Hook Bus 直到清理完。', '2meet-data-optimizer' ) . '</p>';
}
/**
* Doctor help content.
*
* @return string
*/
private static function content_doctor(): string {
return '<p>' . esc_html__( '7 項自動健康檢查:', '2meet-data-optimizer' ) . '</p>'
. '<ol style="padding-left: 1.5em;">'
. '<li><strong>schema_drift</strong> — ' . esc_html__( '所有 v2 表是否存在', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>error_budget</strong> — ' . esc_html__( '7 天內 wp_wpdo_errors 行數', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>hook_conflicts</strong> — ' . esc_html__( '同上 conflicts tab', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>autoload_bloat</strong> — ' . esc_html__( 'wp_options autoload 大小 > 5MB 警告', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>postmeta_explosion</strong> — ' . esc_html__( 'wp_postmeta > 5M 行', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>orphan_zone_rows</strong> — ' . esc_html__( '已 idle 的 module 但 zone 表還有資料', '2meet-data-optimizer' ) . '</li>'
. '<li><strong>missing_snapshot</strong> — ' . esc_html__( '在 cutover/cleanup/complete 但 7 天沒 snapshot', '2meet-data-optimizer' ) . '</li>'
. '</ol>'
. '<p>' . esc_html__( '結果有 5 分鐘 transient cache,剛操作完想立刻看新值請等下個週期。', '2meet-data-optimizer' ) . '</p>';
}
/**
* Logs help content.
*
* @return string
*/
private static function content_logs(): string {
return '<p>' . esc_html__( '日誌讀取:', '2meet-data-optimizer' ) . '</p>'
. '<ul style="list-style: disc; padding-left: 1.5em;">'
. '<li>' . esc_html__( '每筆對應 wp_wpdo_errors 一行:module / zone / hook / message / timestamp。', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( '預設保留 90 天(wpdo_errors_gc daily cron 自動清)。', '2meet-data-optimizer' ) . '</li>'
. '<li>' . esc_html__( '看 message 開頭 [WARN] 是 warning level(不影響運作但需注意)。', '2meet-data-optimizer' ) . '</li>'
. '</ul>';
}
/**
* REST API help content.
*
* @return string
*/
private static function content_rest_api(): string {
return '<p>' . esc_html__( 'REST API 提供 zone 操作 + diagnostics endpoints。', '2meet-data-optimizer' ) . '</p>'
. '<p>' . esc_html__( '所有 endpoint 用 X-WP-Nonce 認證;rate limit 預設 30/min。', '2meet-data-optimizer' ) . '</p>';
}
}