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
+217
View File
@@ -0,0 +1,217 @@
<?php
/**
* One-click User Entity Migration Wizard.
*
* Variables in scope (from class-tmdo-admin.php::render_migration_wizard):
* $preflight array TMDO_Migration_Orchestrator::preflight() snapshot.
* $status array TMDO_Migration_Orchestrator::get_status() snapshot.
*
* @package WP_Data_Optimizer
* @since 2.8.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$ratio = $preflight['ratio'] ?? 0;
$users_count = $preflight['users'] ?? 0;
$usermeta_count = $preflight['usermeta'] ?? 0;
$eav_residue = $preflight['eav_rows'] ?? 0;
$current_mode = $preflight['mode'] ?? 'unknown';
$strategy = $preflight['estimated_strategy'] ?? 'sync';
$est_sec = $preflight['estimated_sec'] ?? 0;
$groups = $preflight['groups'] ?? array();
$state = $status['state'] ?? 'idle';
$active = in_array( $state, array( 'running', 'paused' ), true );
$completed = 'completed' === $state;
$failed = 'failed' === $state;
?>
<div class="wpdo-migration-wizard" data-state="<?php echo esc_attr( $state ); ?>">
<header class="wpdo-mw-header">
<h2><?php esc_html_e( 'User Entity 遷移精靈', '2meet-data-optimizer' ); ?></h2>
<p class="description">
<?php esc_html_e( '把 wp_usermeta 中已註冊為 entity field 的 legacy keys 一次遷移到 flat tables。流程包含自動備份、demote、bulk SQL backfill、shadow_read 驗證、aeav_only cutover、以及最終的 EAV 殘留清除。', '2meet-data-optimizer' ); ?>
</p>
</header>
<!-- Pre-flight diagnostic panel ─────────────────────────────────────── -->
<section class="wpdo-mw-panel wpdo-mw-preflight" id="wpdo-mw-preflight">
<h3><?php esc_html_e( '當前狀態', '2meet-data-optimizer' ); ?></h3>
<div class="wpdo-mw-metrics">
<div class="wpdo-mw-metric">
<span class="wpdo-mw-metric-label"><?php esc_html_e( 'wp_users', '2meet-data-optimizer' ); ?></span>
<span class="wpdo-mw-metric-value" id="wpdo-mw-users"><?php echo esc_html( number_format_i18n( $users_count ) ); ?></span>
</div>
<div class="wpdo-mw-metric">
<span class="wpdo-mw-metric-label"><?php esc_html_e( 'wp_usermeta', '2meet-data-optimizer' ); ?></span>
<span class="wpdo-mw-metric-value" id="wpdo-mw-usermeta"><?php echo esc_html( number_format_i18n( $usermeta_count ) ); ?></span>
</div>
<div class="wpdo-mw-metric wpdo-mw-metric-primary">
<span class="wpdo-mw-metric-label"><?php esc_html_e( '當前 ratio', '2meet-data-optimizer' ); ?></span>
<span class="wpdo-mw-metric-value" id="wpdo-mw-ratio">1:<?php echo esc_html( (string) $ratio ); ?></span>
</div>
<div class="wpdo-mw-metric">
<span class="wpdo-mw-metric-label"><?php esc_html_e( 'EAV 殘留', '2meet-data-optimizer' ); ?></span>
<span class="wpdo-mw-metric-value" id="wpdo-mw-residue"><?php echo esc_html( number_format_i18n( $eav_residue ) ); ?></span>
</div>
<div class="wpdo-mw-metric">
<span class="wpdo-mw-metric-label"><?php esc_html_e( 'user mode', '2meet-data-optimizer' ); ?></span>
<span class="wpdo-mw-metric-value wpdo-mw-mode wpdo-mw-mode-<?php echo esc_attr( $current_mode ); ?>"><?php echo esc_html( $current_mode ); ?></span>
</div>
</div>
<details class="wpdo-mw-groups">
<summary><?php esc_html_e( '各 entity group 詳細狀態', '2meet-data-optimizer' ); ?></summary>
<table class="widefat striped">
<thead>
<tr>
<th><?php esc_html_e( 'Group', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( 'Keys', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( 'Flat rows', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( 'EAV 殘留', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( 'Backfill 策略', '2meet-data-optimizer' ); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ( $groups as $name => $g ) : ?>
<tr>
<td><code><?php echo esc_html( $name ); ?></code></td>
<td><?php echo esc_html( (string) count( $g['keys'] ) ); ?></td>
<td><?php echo esc_html( (string) $g['flat_rows'] ); ?></td>
<td>
<?php if ( $g['residue'] > 0 ) : ?>
<strong><?php echo esc_html( (string) $g['residue'] ); ?></strong>
<?php else : ?>
<span class="wpdo-mw-zero">0</span>
<?php endif; ?>
</td>
<td><code><?php echo esc_html( $g['strategy'] ); ?></code></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</details>
</section>
<!-- Run-migration panel (idle state) ──────────────────────────────── -->
<section class="wpdo-mw-panel wpdo-mw-run" id="wpdo-mw-run-panel"
<?php echo $active || $completed ? 'hidden' : ''; ?>>
<?php if ( 0 === $eav_residue && 'aeav_only' === $current_mode ) : ?>
<div class="wpdo-mw-nothing-todo">
<h3>✅ <?php esc_html_e( '無事可做', '2meet-data-optimizer' ); ?></h3>
<p><?php esc_html_e( '所有 entity group 已 aeav_only / 0 EAV 殘留。', '2meet-data-optimizer' ); ?></p>
<p>
<?php
echo esc_html(
sprintf(
/* translators: %s: ratio */
__( '當前 ratio1:%s', '2meet-data-optimizer' ),
(string) $ratio
)
);
?>
</p>
</div>
<?php else : ?>
<h3><?php esc_html_e( '執行一鍵遷移', '2meet-data-optimizer' ); ?></h3>
<div class="wpdo-mw-estimate">
<?php
printf(
/* translators: 1: rows count, 2: strategy, 3: estimated seconds */
esc_html__( '將遷移 %1$s 行 EAV 殘留,預估策略:%2$s(約 %3$s 秒)。', '2meet-data-optimizer' ),
'<strong>' . esc_html( number_format_i18n( $eav_residue ) ) . '</strong>',
'<code>' . esc_html( $strategy ) . '</code>',
'<strong>' . esc_html( (string) $est_sec ) . '</strong>'
);
?>
</div>
<fieldset class="wpdo-mw-options">
<legend><?php esc_html_e( '進階選項', '2meet-data-optimizer' ); ?></legend>
<label>
<input type="checkbox" id="wpdo-mw-opt-backup" checked>
<?php esc_html_e( '自動備份 wp_usermeta 至 uploads/wpdo-backups/(推薦)', '2meet-data-optimizer' ); ?>
</label>
<label>
<input type="checkbox" id="wpdo-mw-opt-strict" checked>
<?php esc_html_e( '嚴格驗證(500 users / 10% 抽樣)', '2meet-data-optimizer' ); ?>
</label>
<label>
<input type="checkbox" id="wpdo-mw-opt-24h">
<?php esc_html_e( '24 小時 shadow_read 觀察視窗(生產環境用,會暫停 24h 才繼續)', '2meet-data-optimizer' ); ?>
</label>
<label>
<input type="checkbox" id="wpdo-mw-opt-async">
<?php esc_html_e( '強制 asynccron 推進,不阻塞 HTTP 請求)', '2meet-data-optimizer' ); ?>
</label>
<label>
<input type="checkbox" id="wpdo-mw-opt-dryrun">
<?php esc_html_e( 'Dry-run(不寫入、不刪除,僅模擬流程)', '2meet-data-optimizer' ); ?>
</label>
</fieldset>
<div class="wpdo-mw-confirm">
<label>
<input type="checkbox" id="wpdo-mw-confirm-backup" required>
<?php esc_html_e( '我已了解:流程將從 wp_usermeta 刪除已註冊欄位的 EAV 行,過程不可逆(自動備份提供救援路徑)。', '2meet-data-optimizer' ); ?>
</label>
</div>
<button type="button" class="button button-primary button-hero" id="wpdo-mw-start" disabled>
🚀 <?php esc_html_e( '開始一鍵遷移', '2meet-data-optimizer' ); ?>
</button>
<?php endif; ?>
</section>
<!-- Live progress panel (running state) ───────────────────────────── -->
<section class="wpdo-mw-panel wpdo-mw-progress" id="wpdo-mw-progress-panel"
<?php echo $active || $failed ? '' : 'hidden'; ?>>
<h3 id="wpdo-mw-progress-title"><?php esc_html_e( '執行中…', '2meet-data-optimizer' ); ?></h3>
<div class="wpdo-mw-progress-bar">
<div class="wpdo-mw-progress-fill" id="wpdo-mw-progress-fill"
style="width:<?php echo esc_attr( (string) ( $status['overall_progress'] ?? 0 ) ); ?>%"></div>
<span class="wpdo-mw-progress-pct" id="wpdo-mw-progress-pct"><?php echo esc_html( (string) ( $status['overall_progress'] ?? 0 ) ); ?>%</span>
</div>
<div class="wpdo-mw-current">
<span class="wpdo-mw-current-phase">
<?php esc_html_e( '當前階段:', '2meet-data-optimizer' ); ?>
<code id="wpdo-mw-current-phase-name"><?php echo esc_html( $status['phase'] ?? 'idle' ); ?></code>
</span>
<span class="wpdo-mw-elapsed" id="wpdo-mw-elapsed">0.0s</span>
</div>
<div class="wpdo-mw-live-ratio">
<span><?php esc_html_e( 'Live ratio', '2meet-data-optimizer' ); ?></span>
<span id="wpdo-mw-live-ratio-text">
1:<?php echo esc_html( (string) ( $status['metrics']['ratio_start'] ?? $ratio ) ); ?>
1:<?php echo esc_html( (string) ( $status['metrics']['ratio_now'] ?? $ratio ) ); ?>
</span>
</div>
<div class="wpdo-mw-log-wrap">
<h4><?php esc_html_e( 'Log', '2meet-data-optimizer' ); ?></h4>
<pre class="wpdo-mw-log" id="wpdo-mw-log"><?php echo esc_html( implode( "\n", (array) ( $status['log'] ?? array() ) ) ); ?></pre>
</div>
<div class="wpdo-mw-actions">
<button type="button" class="button" id="wpdo-mw-cancel"><?php esc_html_e( '取消', '2meet-data-optimizer' ); ?></button>
<button type="button" class="button button-primary" id="wpdo-mw-resume" hidden><?php esc_html_e( 'Resume', '2meet-data-optimizer' ); ?></button>
</div>
</section>
<!-- Completed state ───────────────────────────────────────────────── -->
<section class="wpdo-mw-panel wpdo-mw-done" id="wpdo-mw-done-panel"
<?php echo $completed ? '' : 'hidden'; ?>>
<h3>✅ <?php esc_html_e( '遷移完成', '2meet-data-optimizer' ); ?></h3>
<div class="wpdo-mw-done-summary" id="wpdo-mw-done-summary"></div>
<button type="button" class="button" id="wpdo-mw-reset"><?php esc_html_e( '回到診斷頁', '2meet-data-optimizer' ); ?></button>
</section>
</div>