Files
2meet-data-optimizer-woocom…/admin/class-tmdo-admin-wc.php
T
wpdev 2f9ed57390 chore(wc): 同步 A v3.4.6 的 WooCommerce 整合 + TablePrefix header(F4/F5)
4 個整合檔(woocommerce / wc-orders-interceptor / wc-term-count-filter /
admin-wc)對齊 A v3.4.6;主檔補 TablePrefix header。

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

239 lines
8.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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 TMDO
* @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', '2meet-data-optimizer' ),
__( 'WPDO WC', '2meet-data-optimizer' ),
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', '2meet-data-optimizer' ); ?></h1>
<h2><?php esc_html_e( 'WC 環境', '2meet-data-optimizer' ); ?></h2>
<table class="widefat wpdo-max-520">
<tr>
<th><?php esc_html_e( 'WC 版本', '2meet-data-optimizer' ); ?></th>
<td><?php echo esc_html( $wc_ver ); ?></td>
</tr>
<tr>
<th><?php esc_html_e( 'HPOS 啟用', '2meet-data-optimizer' ); ?></th>
<td>
<?php if ( $hpos ) : ?>
<span class="wpdo-text-success">✅ <?php esc_html_e( '是 — orders 走 wp_wc_orders 不污染 postmeta', '2meet-data-optimizer' ); ?></span>
<?php else : ?>
<span class="wpdo-text-error">⚠️ <?php esc_html_e( '否 — orders 仍存於 wp_postmeta(建議啟用以加速)', '2meet-data-optimizer' ); ?></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( '前往設定', '2meet-data-optimizer' ); ?></a>
<?php endif; ?>
</td>
</tr>
<tr>
<th><?php esc_html_e( 'WPDO 註冊的 WC 表', '2meet-data-optimizer' ); ?></th>
<td><?php echo (int) count( $tables ); ?> tables</td>
</tr>
</table>
<h2><?php esc_html_e( 'Vendor Commissionsmarketplace 訂單)', '2meet-data-optimizer' ); ?></h2>
<?php if ( $totals['order_count'] > 0 ) : ?>
<div class="wpdo-grid-4col">
<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( '總訂單數', '2meet-data-optimizer' ); ?></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( '總交易額', '2meet-data-optimizer' ); ?></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( '平台抽成', '2meet-data-optimizer' ); ?></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 應得', '2meet-data-optimizer' ); ?></div>
</div>
</div>
<h3><?php esc_html_e( 'Top 10 Vendors', '2meet-data-optimizer' ); ?></h3>
<table class="widefat striped">
<thead>
<tr>
<th><?php esc_html_e( 'Vendor', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( '訂單數', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( '交易額', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( '平台抽成', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( 'Vendor 應得', '2meet-data-optimizer' ); ?></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 class="wpdo-opacity-60"><?php esc_html_e( '尚未有 marketplace 訂單。當客戶下訂並進入 processing/completed 狀態,commission 會自動寫入 wp_wpdo_wc_commissions。', '2meet-data-optimizer' ); ?></p>
<?php endif; ?>
<h2><?php esc_html_e( '已註冊的 WC 表', '2meet-data-optimizer' ); ?></h2>
<table class="widefat striped">
<thead>
<tr>
<th><?php esc_html_e( '表名', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( '描述', '2meet-data-optimizer' ); ?></th>
<th><?php esc_html_e( '健康', '2meet-data-optimizer' ); ?></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 ),
);
}
}