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
This commit is contained in:
@@ -19,7 +19,15 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
class TMDO_Admin {
|
||||
|
||||
/** Menu slug. */
|
||||
private const MENU_SLUG = '2meet-data-optimizer';
|
||||
/**
|
||||
* Admin page slug.
|
||||
*
|
||||
* Kept as `wp-data-optimizer` on purpose: this plugin already inherits the
|
||||
* wpdo_ table / option / cron / hook / CLI namespace, existing bookmarks and
|
||||
* sister-plugin links point here, and ~10 links inside this plugin (help tabs,
|
||||
* setup wizard, conflict monitor, stress-test templates) hardcode it.
|
||||
*/
|
||||
private const MENU_SLUG = 'wp-data-optimizer';
|
||||
|
||||
/** Nonce action. */
|
||||
private const NONCE_ACTION = 'wpdo_admin_action';
|
||||
|
||||
@@ -553,9 +553,16 @@ class TMDO_CLI_Member {
|
||||
|
||||
// ── Register subcommands ──────────────────────────────────────────────────────
|
||||
WP_CLI::add_command( 'wpdo member-audit', array( 'TMDO_CLI_Member', 'member_audit' ) );
|
||||
WP_CLI::add_command( 'tmdo member-audit', array( 'TMDO_CLI_Member', 'member_audit' ) );
|
||||
WP_CLI::add_command( 'wpdo member-backfill', array( 'TMDO_CLI_Member', 'member_backfill' ) );
|
||||
WP_CLI::add_command( 'tmdo member-backfill', array( 'TMDO_CLI_Member', 'member_backfill' ) );
|
||||
WP_CLI::add_command( 'wpdo member-shadow-report', array( 'TMDO_CLI_Member', 'member_shadow_report' ) );
|
||||
WP_CLI::add_command( 'tmdo member-shadow-report', array( 'TMDO_CLI_Member', 'member_shadow_report' ) );
|
||||
WP_CLI::add_command( 'wpdo member-cutover', array( 'TMDO_CLI_Member', 'member_cutover' ) );
|
||||
WP_CLI::add_command( 'tmdo member-cutover', array( 'TMDO_CLI_Member', 'member_cutover' ) );
|
||||
WP_CLI::add_command( 'wpdo member-points-check', array( 'TMDO_CLI_Member', 'member_points_check' ) );
|
||||
WP_CLI::add_command( 'tmdo member-points-check', array( 'TMDO_CLI_Member', 'member_points_check' ) );
|
||||
WP_CLI::add_command( 'wpdo member-sso-sync', array( 'TMDO_CLI_Member', 'member_sso_sync' ) );
|
||||
WP_CLI::add_command( 'tmdo member-sso-sync', array( 'TMDO_CLI_Member', 'member_sso_sync' ) );
|
||||
WP_CLI::add_command( 'wpdo member-force-logout', array( 'TMDO_CLI_Member', 'member_force_logout' ) );
|
||||
WP_CLI::add_command( 'tmdo member-force-logout', array( 'TMDO_CLI_Member', 'member_force_logout' ) );
|
||||
|
||||
@@ -835,10 +835,18 @@ class TMDO_CLI_Post {
|
||||
|
||||
// ── Register subcommands ──────────────────────────────────────────────────────
|
||||
WP_CLI::add_command( 'wpdo postmeta-cleanup', array( 'TMDO_CLI_Post', 'postmeta_cleanup' ) );
|
||||
WP_CLI::add_command( 'tmdo postmeta-cleanup', array( 'TMDO_CLI_Post', 'postmeta_cleanup' ) );
|
||||
WP_CLI::add_command( 'wpdo post-diagnose', array( 'TMDO_CLI_Post', 'post_diagnose' ) );
|
||||
WP_CLI::add_command( 'tmdo post-diagnose', array( 'TMDO_CLI_Post', 'post_diagnose' ) );
|
||||
WP_CLI::add_command( 'wpdo post-migrate-group', array( 'TMDO_CLI_Post', 'post_migrate_group' ) );
|
||||
WP_CLI::add_command( 'tmdo post-migrate-group', array( 'TMDO_CLI_Post', 'post_migrate_group' ) );
|
||||
WP_CLI::add_command( 'wpdo post-cleanup', array( 'TMDO_CLI_Post', 'post_cleanup' ) );
|
||||
WP_CLI::add_command( 'tmdo post-cleanup', array( 'TMDO_CLI_Post', 'post_cleanup' ) );
|
||||
WP_CLI::add_command( 'wpdo post-cutover-legacy', array( 'TMDO_CLI_Post', 'post_cutover_legacy' ) );
|
||||
WP_CLI::add_command( 'tmdo post-cutover-legacy', array( 'TMDO_CLI_Post', 'post_cutover_legacy' ) );
|
||||
WP_CLI::add_command( 'wpdo cleanup-hp-transients', array( 'TMDO_CLI_Post', 'cleanup_hp_transients' ) );
|
||||
WP_CLI::add_command( 'tmdo cleanup-hp-transients', array( 'TMDO_CLI_Post', 'cleanup_hp_transients' ) );
|
||||
WP_CLI::add_command( 'wpdo post-benchmark', array( 'TMDO_CLI_Post', 'post_benchmark' ) );
|
||||
WP_CLI::add_command( 'tmdo post-benchmark', array( 'TMDO_CLI_Post', 'post_benchmark' ) );
|
||||
WP_CLI::add_command( 'wpdo post-shadow-report', array( 'TMDO_CLI_Post', 'post_shadow_report' ) );
|
||||
WP_CLI::add_command( 'tmdo post-shadow-report', array( 'TMDO_CLI_Post', 'post_shadow_report' ) );
|
||||
|
||||
@@ -1004,10 +1004,18 @@ class TMDO_CLI_Term_Comment {
|
||||
// (Originally class closed here in v2.12.0; v2.12.5+ adds new methods inside.)
|
||||
|
||||
WP_CLI::add_command( 'wpdo termmeta-cleanup', array( 'TMDO_CLI_Term_Comment', 'termmeta_cleanup' ) );
|
||||
WP_CLI::add_command( 'tmdo termmeta-cleanup', array( 'TMDO_CLI_Term_Comment', 'termmeta_cleanup' ) );
|
||||
WP_CLI::add_command( 'wpdo commentmeta-cleanup', array( 'TMDO_CLI_Term_Comment', 'commentmeta_cleanup' ) );
|
||||
WP_CLI::add_command( 'tmdo commentmeta-cleanup', array( 'TMDO_CLI_Term_Comment', 'commentmeta_cleanup' ) );
|
||||
WP_CLI::add_command( 'wpdo term-promote-mode', array( 'TMDO_CLI_Term_Comment', 'term_promote_mode' ) );
|
||||
WP_CLI::add_command( 'tmdo term-promote-mode', array( 'TMDO_CLI_Term_Comment', 'term_promote_mode' ) );
|
||||
WP_CLI::add_command( 'wpdo comment-promote-mode', array( 'TMDO_CLI_Term_Comment', 'comment_promote_mode' ) );
|
||||
WP_CLI::add_command( 'tmdo comment-promote-mode', array( 'TMDO_CLI_Term_Comment', 'comment_promote_mode' ) );
|
||||
WP_CLI::add_command( 'wpdo term-comment-diagnose', array( 'TMDO_CLI_Term_Comment', 'term_comment_diagnose' ) );
|
||||
WP_CLI::add_command( 'tmdo term-comment-diagnose', array( 'TMDO_CLI_Term_Comment', 'term_comment_diagnose' ) );
|
||||
WP_CLI::add_command( 'wpdo term-comment-shadow-report', array( 'TMDO_CLI_Term_Comment', 'term_comment_shadow_report' ) );
|
||||
WP_CLI::add_command( 'tmdo term-comment-shadow-report', array( 'TMDO_CLI_Term_Comment', 'term_comment_shadow_report' ) );
|
||||
WP_CLI::add_command( 'wpdo term-comment-backfill', array( 'TMDO_CLI_Term_Comment', 'term_comment_backfill' ) );
|
||||
WP_CLI::add_command( 'tmdo term-comment-backfill', array( 'TMDO_CLI_Term_Comment', 'term_comment_backfill' ) );
|
||||
WP_CLI::add_command( 'wpdo comment-stress-test', array( 'TMDO_CLI_Term_Comment', 'comment_stress_test' ) );
|
||||
WP_CLI::add_command( 'tmdo comment-stress-test', array( 'TMDO_CLI_Term_Comment', 'comment_stress_test' ) );
|
||||
|
||||
@@ -779,17 +779,32 @@ class TMDO_CLI_V2 {
|
||||
}
|
||||
|
||||
WP_CLI::add_command( 'wpdo bridge-status', array( 'TMDO_CLI_V2', 'bridge_status' ) );
|
||||
WP_CLI::add_command( 'tmdo bridge-status', array( 'TMDO_CLI_V2', 'bridge_status' ) );
|
||||
WP_CLI::add_command( 'wpdo bridge-set', array( 'TMDO_CLI_V2', 'bridge_set' ) );
|
||||
WP_CLI::add_command( 'tmdo bridge-set', array( 'TMDO_CLI_V2', 'bridge_set' ) );
|
||||
WP_CLI::add_command( 'wpdo mode-audit', array( 'TMDO_CLI_V2', 'mode_audit' ) );
|
||||
WP_CLI::add_command( 'tmdo mode-audit', array( 'TMDO_CLI_V2', 'mode_audit' ) );
|
||||
WP_CLI::add_command( 'wpdo mode-set', array( 'TMDO_CLI_V2', 'mode_set' ) );
|
||||
WP_CLI::add_command( 'tmdo mode-set', array( 'TMDO_CLI_V2', 'mode_set' ) );
|
||||
WP_CLI::add_command( 'wpdo shadow-enable', array( 'TMDO_CLI_V2', 'shadow_enable' ) );
|
||||
WP_CLI::add_command( 'tmdo shadow-enable', array( 'TMDO_CLI_V2', 'shadow_enable' ) );
|
||||
WP_CLI::add_command( 'wpdo shadow-disable', array( 'TMDO_CLI_V2', 'shadow_disable' ) );
|
||||
WP_CLI::add_command( 'tmdo shadow-disable', array( 'TMDO_CLI_V2', 'shadow_disable' ) );
|
||||
WP_CLI::add_command( 'wpdo conflict-scan', array( 'TMDO_CLI_V2', 'conflict_scan' ) );
|
||||
WP_CLI::add_command( 'tmdo conflict-scan', array( 'TMDO_CLI_V2', 'conflict_scan' ) );
|
||||
WP_CLI::add_command( 'wpdo lint', array( 'TMDO_CLI_V2', 'lint' ) );
|
||||
WP_CLI::add_command( 'tmdo lint', array( 'TMDO_CLI_V2', 'lint' ) );
|
||||
WP_CLI::add_command( 'wpdo snapshot create', array( 'TMDO_CLI_V2', 'snapshot_create' ) );
|
||||
WP_CLI::add_command( 'tmdo snapshot create', array( 'TMDO_CLI_V2', 'snapshot_create' ) );
|
||||
WP_CLI::add_command( 'wpdo snapshot list', array( 'TMDO_CLI_V2', 'snapshot_list' ) );
|
||||
WP_CLI::add_command( 'tmdo snapshot list', array( 'TMDO_CLI_V2', 'snapshot_list' ) );
|
||||
WP_CLI::add_command( 'wpdo snapshot restore', array( 'TMDO_CLI_V2', 'snapshot_restore' ) );
|
||||
WP_CLI::add_command( 'tmdo snapshot restore', array( 'TMDO_CLI_V2', 'snapshot_restore' ) );
|
||||
WP_CLI::add_command( 'wpdo snapshot prune', array( 'TMDO_CLI_V2', 'snapshot_prune' ) );
|
||||
WP_CLI::add_command( 'tmdo snapshot prune', array( 'TMDO_CLI_V2', 'snapshot_prune' ) );
|
||||
WP_CLI::add_command( 'wpdo snapshot verify', array( 'TMDO_CLI_V2', 'snapshot_verify' ) );
|
||||
WP_CLI::add_command( 'tmdo snapshot verify', array( 'TMDO_CLI_V2', 'snapshot_verify' ) );
|
||||
WP_CLI::add_command( 'wpdo crypto-status', array( 'TMDO_CLI_V2', 'crypto_status' ) );
|
||||
WP_CLI::add_command( 'tmdo crypto-status', array( 'TMDO_CLI_V2', 'crypto_status' ) );
|
||||
WP_CLI::add_command( 'wpdo crypto-migrate', array( 'TMDO_CLI_V2', 'crypto_migrate' ) );
|
||||
WP_CLI::add_command( 'tmdo crypto-migrate', array( 'TMDO_CLI_V2', 'crypto_migrate' ) );
|
||||
|
||||
@@ -126,14 +126,14 @@ final class TMDO_Conflict_Detector {
|
||||
esc_html( $c['uaepg_group'] )
|
||||
);
|
||||
}
|
||||
$extra = $count > 5 ? sprintf( __( '… 另有 %d 個欄位未顯示', 'uae' ), $count - 5 ) : '';
|
||||
$extra = $count > 5 ? sprintf( __( '… 另有 %d 個欄位未顯示', '2meet-data-optimizer' ), $count - 5 ) : '';
|
||||
|
||||
printf(
|
||||
'<div class="notice notice-error"><p><strong>%s</strong></p><ul style="list-style:disc;margin-left:20px;"><li>%s</li></ul>%s<p>%s <code>wp uae conflicts</code></p></div>',
|
||||
esc_html(
|
||||
sprintf(
|
||||
/* translators: %d: conflict count */
|
||||
__( 'UAE × UAEPG 欄位衝突偵測:發現 %d 個同 meta_key 被雙方 Registry 重複登錄 — UAEPG 會搶先短路,UAE 寫入將被靜默跳過', 'uae' ),
|
||||
__( 'UAE × UAEPG 欄位衝突偵測:發現 %d 個同 meta_key 被雙方 Registry 重複登錄 — UAEPG 會搶先短路,UAE 寫入將被靜默跳過', '2meet-data-optimizer' ),
|
||||
$count
|
||||
)
|
||||
),
|
||||
@@ -141,7 +141,7 @@ final class TMDO_Conflict_Detector {
|
||||
// implode joins escaped strings with literal HTML markers — safe.
|
||||
implode( '</li><li>', $lines ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- pre-escaped above.
|
||||
$extra ? '<p><em>' . esc_html( $extra ) . '</em></p>' : '',
|
||||
esc_html__( '查看完整清單:', 'uae' )
|
||||
esc_html__( '查看完整清單:', '2meet-data-optimizer' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ final class TMDO_Mode_Manager {
|
||||
return new \WP_Error(
|
||||
'unsafe_transition',
|
||||
sprintf(
|
||||
__( '不安全的模式轉換:%1$s → %2$s。建議路徑:disabled → dual_write → shadow_read → aeav_only', 'uae' ),
|
||||
__( '不安全的模式轉換:%1$s → %2$s。建議路徑:disabled → dual_write → shadow_read → aeav_only', '2meet-data-optimizer' ),
|
||||
$current,
|
||||
$new_mode
|
||||
)
|
||||
@@ -348,13 +348,13 @@ final class TMDO_Mode_Manager {
|
||||
public static function label( string $mode ): string {
|
||||
switch ( $mode ) {
|
||||
case self::MODE_DISABLED:
|
||||
return __( '停用(原生 EAV)', 'uae' );
|
||||
return __( '停用(原生 EAV)', '2meet-data-optimizer' );
|
||||
case self::MODE_DUAL_WRITE:
|
||||
return __( '雙寫', 'uae' );
|
||||
return __( '雙寫', '2meet-data-optimizer' );
|
||||
case self::MODE_SHADOW_READ:
|
||||
return __( '影子讀取(驗證中)', 'uae' );
|
||||
return __( '影子讀取(驗證中)', '2meet-data-optimizer' );
|
||||
case self::MODE_AEAV_ONLY:
|
||||
return __( '僅 UAE(生產模式)', 'uae' );
|
||||
return __( '僅 UAE(生產模式)', '2meet-data-optimizer' );
|
||||
default:
|
||||
return $mode;
|
||||
}
|
||||
@@ -366,13 +366,13 @@ final class TMDO_Mode_Manager {
|
||||
public static function description( string $mode ): string {
|
||||
switch ( $mode ) {
|
||||
case self::MODE_DISABLED:
|
||||
return __( '完全停用 UAE 攔截,使用 WordPress 原生 wp_*meta 表。安全 fallback。', 'uae' );
|
||||
return __( '完全停用 UAE 攔截,使用 WordPress 原生 wp_*meta 表。安全 fallback。', '2meet-data-optimizer' );
|
||||
case self::MODE_DUAL_WRITE:
|
||||
return __( '寫入 UAE + 原生 meta 表,讀取仍走原生。遷移前期的安全起點。', 'uae' );
|
||||
return __( '寫入 UAE + 原生 meta 表,讀取仍走原生。遷移前期的安全起點。', '2meet-data-optimizer' );
|
||||
case self::MODE_SHADOW_READ:
|
||||
return __( '寫入雙寫,讀取走 UAE 並比對原生 meta。驗證資料一致性的階段。', 'uae' );
|
||||
return __( '寫入雙寫,讀取走 UAE 並比對原生 meta。驗證資料一致性的階段。', '2meet-data-optimizer' );
|
||||
case self::MODE_AEAV_ONLY:
|
||||
return __( '僅讀寫 UAE,不再寫入原生 meta 表。最終生產模式,效能最佳。', 'uae' );
|
||||
return __( '僅讀寫 UAE,不再寫入原生 meta 表。最終生產模式,效能最佳。', '2meet-data-optimizer' );
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user