chore: initial snapshot of 2meet-data-optimizer-woocommerce-addon 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 47288db826
17 changed files with 3903 additions and 0 deletions
+238
View File
@@ -0,0 +1,238 @@
<?php
/**
* TMDO_Admin_WC — admin dashboard panel for WooCommerce integration.
*
* URL: Tools → WP Data Optimizer (parent menu) → WooCommerce sub-page.
*
* Shows:
* - HPOS status + recommendation
* - WC tables registered (count + health)
* - Top vendors by commission (from wp_wpdo_wc_commissions)
*
* @package WP_Data_Optimizer
* @since 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC admin panel.
*/
final class TMDO_Admin_WC {
private const MENU_SLUG = 'wpdo-wc';
private const CAP = 'manage_options';
/**
* Wire the menu item — only when WC is active.
*
* @return void
*/
public static function register(): void {
if ( ! class_exists( 'TMDO_WooCommerce' ) || ! TMDO_WooCommerce::is_active() ) {
return;
}
add_action( 'admin_menu', array( __CLASS__, 'register_menu' ), 11 );
}
/**
* Add submenu under "WP Data Optimizer" (which lives under Tools).
*
* @return void
*/
public static function register_menu(): void {
add_submenu_page(
'tools.php',
__( 'WPDO WooCommerce', 'tmdo-woocommerce' ),
__( 'WPDO WC', 'tmdo-woocommerce' ),
self::CAP,
self::MENU_SLUG,
array( __CLASS__, 'render' )
);
}
/**
* Render the dashboard.
*
* @return void
*/
public static function render(): void {
$hpos = class_exists( 'TMDO_WooCommerce' ) ? TMDO_WooCommerce::is_hpos_enabled() : false;
$wc_ver = class_exists( 'TMDO_WooCommerce' ) ? TMDO_WooCommerce::wc_version() : 'unknown';
$tables = class_exists( 'TMDO_Custom_Table_Registry' )
? TMDO_Custom_Table_Registry::instance()->for_provider( 'woocommerce' )
: array();
$vendors = self::top_vendors_by_commission( 10 );
$totals = self::global_commission_totals();
?>
<div class="wrap">
<h1><?php esc_html_e( 'WPDO × WooCommerce', 'tmdo-woocommerce' ); ?></h1>
<h2><?php esc_html_e( 'WC 環境', 'tmdo-woocommerce' ); ?></h2>
<table class="widefat" style="max-width:520px;">
<tr>
<th><?php esc_html_e( 'WC 版本', 'tmdo-woocommerce' ); ?></th>
<td><?php echo esc_html( $wc_ver ); ?></td>
</tr>
<tr>
<th><?php esc_html_e( 'HPOS 啟用', 'tmdo-woocommerce' ); ?></th>
<td>
<?php if ( $hpos ) : ?>
<span style="color:#2a5a2a;">✅ <?php esc_html_e( '是 — orders 走 wp_wc_orders 不污染 postmeta', 'tmdo-woocommerce' ); ?></span>
<?php else : ?>
<span style="color:#c44;">⚠️ <?php esc_html_e( '否 — orders 仍存於 wp_postmeta(建議啟用以加速)', 'tmdo-woocommerce' ); ?></span>
&nbsp;<a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced&section=features' ) ); ?>" class="button button-small"><?php esc_html_e( '前往設定', 'tmdo-woocommerce' ); ?></a>
<?php endif; ?>
</td>
</tr>
<tr>
<th><?php esc_html_e( 'WPDO 註冊的 WC 表', 'tmdo-woocommerce' ); ?></th>
<td><?php echo (int) count( $tables ); ?> tables</td>
</tr>
</table>
<h2><?php esc_html_e( 'Vendor Commissionsmarketplace 訂單)', 'tmdo-woocommerce' ); ?></h2>
<?php if ( $totals['order_count'] > 0 ) : ?>
<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:1rem;max-width:720px;margin:1rem 0;">
<div class="wpdo-card">
<div class="wpdo-card__num"><?php echo esc_html( number_format_i18n( $totals['order_count'] ) ); ?></div>
<div class="wpdo-card__lbl"><?php esc_html_e( '總訂單數', 'tmdo-woocommerce' ); ?></div>
</div>
<div class="wpdo-card">
<div class="wpdo-card__num">$<?php echo esc_html( number_format_i18n( $totals['total_subtotal'], 2 ) ); ?></div>
<div class="wpdo-card__lbl"><?php esc_html_e( '總交易額', 'tmdo-woocommerce' ); ?></div>
</div>
<div class="wpdo-card">
<div class="wpdo-card__num">$<?php echo esc_html( number_format_i18n( $totals['total_commission'], 2 ) ); ?></div>
<div class="wpdo-card__lbl"><?php esc_html_e( '平台抽成', 'tmdo-woocommerce' ); ?></div>
</div>
<div class="wpdo-card">
<div class="wpdo-card__num">$<?php echo esc_html( number_format_i18n( $totals['total_payout'], 2 ) ); ?></div>
<div class="wpdo-card__lbl"><?php esc_html_e( 'Vendor 應得', 'tmdo-woocommerce' ); ?></div>
</div>
</div>
<h3><?php esc_html_e( 'Top 10 Vendors', 'tmdo-woocommerce' ); ?></h3>
<table class="widefat striped">
<thead>
<tr>
<th><?php esc_html_e( 'Vendor', 'tmdo-woocommerce' ); ?></th>
<th><?php esc_html_e( '訂單數', 'tmdo-woocommerce' ); ?></th>
<th><?php esc_html_e( '交易額', 'tmdo-woocommerce' ); ?></th>
<th><?php esc_html_e( '平台抽成', 'tmdo-woocommerce' ); ?></th>
<th><?php esc_html_e( 'Vendor 應得', 'tmdo-woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php
foreach ( $vendors as $v ) :
$user = get_userdata( (int) $v['vendor_id'] );
?>
<tr>
<td><?php echo $user ? esc_html( $user->display_name ) : '#' . (int) $v['vendor_id']; ?></td>
<td><?php echo (int) $v['order_count']; ?></td>
<td>$<?php echo esc_html( number_format_i18n( (float) $v['subtotal'], 2 ) ); ?></td>
<td>$<?php echo esc_html( number_format_i18n( (float) $v['commission'], 2 ) ); ?></td>
<td>$<?php echo esc_html( number_format_i18n( (float) $v['payout'], 2 ) ); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else : ?>
<p style="opacity:.6;"><?php esc_html_e( '尚未有 marketplace 訂單。當客戶下訂並進入 processing/completed 狀態,commission 會自動寫入 wp_wpdo_wc_commissions。', 'tmdo-woocommerce' ); ?></p>
<?php endif; ?>
<h2><?php esc_html_e( '已註冊的 WC 表', 'tmdo-woocommerce' ); ?></h2>
<table class="widefat striped">
<thead>
<tr>
<th><?php esc_html_e( '表名', 'tmdo-woocommerce' ); ?></th>
<th><?php esc_html_e( '描述', 'tmdo-woocommerce' ); ?></th>
<th><?php esc_html_e( '健康', 'tmdo-woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php
foreach ( $tables as $t ) :
$probe = TMDO_WooCommerce::doctor_check( $t['table_name'] );
?>
<tr>
<td><code><?php echo esc_html( $t['table_name'] ); ?></code></td>
<td><?php echo esc_html( $t['description'] ?? '' ); ?></td>
<td>
<?php
// Sec-3 hardening: wrap literal ternary in wp_kses_post for pattern hygiene.
echo wp_kses_post( $probe['ok'] ? '✅ ' : '⚠️ ' );
echo esc_html( $probe['message'] );
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<style>
.wpdo-card { background:#fff; padding:1rem; border-radius:8px; border:1px solid #dcdcde; text-align:center; }
.wpdo-card__num { font-size:1.75rem; font-weight:700; color:#c08a5b; }
.wpdo-card__lbl { font-size:.8rem; opacity:.7; margin-top:.25rem; }
</style>
</div>
<?php
}
/**
* Top N vendors by total commission.
*
* @param int $limit Limit.
* @return array
*/
private static function top_vendors_by_commission( int $limit = 10 ): array {
global $wpdb;
$table = TMDO_DB::table( 'wpdo_wc_commissions' );
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $table from TMDO_DB::table() (sanitised); aggregate query.
return $wpdb->get_results(
$wpdb->prepare(
"SELECT vendor_id, COUNT(*) AS order_count,
SUM(subtotal) AS subtotal,
SUM(commission) AS commission,
SUM(vendor_payout) AS payout
FROM `{$table}`
GROUP BY vendor_id
ORDER BY commission DESC
LIMIT %d",
$limit
),
ARRAY_A
) ?: array();
// phpcs:enable
}
/**
* Global commission summary across all vendors.
*
* @return array
*/
private static function global_commission_totals(): array {
global $wpdb;
$table = TMDO_DB::table( 'wpdo_wc_commissions' );
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared -- $table from TMDO_DB::table() (sanitised); aggregate query.
$row = $wpdb->get_row(
"SELECT
COUNT(*) AS order_count,
SUM(subtotal) AS total_subtotal,
SUM(commission) AS total_commission,
SUM(vendor_payout) AS total_payout
FROM `{$table}`",
ARRAY_A
);
// phpcs:enable
return array(
'order_count' => (int) ( $row['order_count'] ?? 0 ),
'total_subtotal' => (float) ( $row['total_subtotal'] ?? 0 ),
'total_commission' => (float) ( $row['total_commission'] ?? 0 ),
'total_payout' => (float) ( $row['total_payout'] ?? 0 ),
);
}
}