Files

329 lines
9.2 KiB
PHP

<?php
/**
* Admin menu, tabs and routing.
*
* @package WC_Email_Discount_Manager
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Registers the admin page under WooCommerce and routes tabs/actions.
*/
class WC_EDM_Admin {
/**
* Admin page slug.
*/
const PAGE_SLUG = 'wc-email-discounts';
/**
* Groups controller.
*
* @var WC_EDM_Admin_Groups
*/
private $groups;
/**
* Emails controller.
*
* @var WC_EDM_Admin_Emails
*/
private $emails;
/**
* Shipping controller.
*
* @var WC_EDM_Admin_Shipping
*/
private $shipping;
/**
* Audit log controller.
*
* @var WC_EDM_Admin_Audit
*/
private $audit;
/**
* Hook everything up.
*/
public function __construct() {
// Each sub-controller lives in its own file. Guarding here means an
// incomplete plugin folder costs a tab, not the whole admin screen.
$this->groups = class_exists( 'WC_EDM_Admin_Groups' ) ? new WC_EDM_Admin_Groups() : null;
$this->emails = class_exists( 'WC_EDM_Admin_Emails' ) ? new WC_EDM_Admin_Emails() : null;
$this->shipping = class_exists( 'WC_EDM_Admin_Shipping' ) ? new WC_EDM_Admin_Shipping() : null;
$this->audit = class_exists( 'WC_EDM_Admin_Audit' ) ? new WC_EDM_Admin_Audit() : null;
add_action( 'admin_menu', array( $this, 'register_menu' ) );
add_action( 'admin_init', array( $this, 'handle_actions' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
}
/**
* Register the submenu page under WooCommerce.
*/
public function register_menu() {
add_submenu_page(
'woocommerce',
__( 'Email Discounts', 'wc-email-discount' ),
__( 'Email Discounts', 'wc-email-discount' ),
'manage_woocommerce',
self::PAGE_SLUG,
array( $this, 'render_page' )
);
}
/**
* Enqueue admin CSS/JS on the plugin page only.
*
* @param string $hook Current admin page hook.
*/
public function enqueue_assets( $hook ) {
if ( false === strpos( $hook, self::PAGE_SLUG ) ) {
return;
}
wp_enqueue_style(
'wc-edm-admin',
WC_EDM_PLUGIN_URL . 'assets/css/admin.css',
array(),
WC_EDM_VERSION
);
wp_enqueue_script(
'wc-edm-admin',
WC_EDM_PLUGIN_URL . 'assets/js/admin.js',
array( 'jquery', 'jquery-ui-sortable' ),
WC_EDM_VERSION,
true
);
wp_localize_script(
'wc-edm-admin',
'wcEdmAdmin',
array(
'confirmDelete' => __( 'Are you sure you want to delete this item? This cannot be undone.', 'wc-email-discount' ),
)
);
}
/**
* Get the currently active tab.
*
* @return string
*/
public function current_tab() {
$tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'dashboard'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$tabs = array_keys( $this->get_tabs() );
return in_array( $tab, $tabs, true ) ? $tab : 'dashboard';
}
/**
* Tab definitions.
*
* @return array
*/
private function get_tabs() {
$tabs = array( 'dashboard' => __( 'Dashboard', 'wc-email-discount' ) );
// Only offer tabs whose controller actually loaded.
if ( $this->groups ) {
$tabs['groups'] = __( 'Discount Groups', 'wc-email-discount' );
}
if ( $this->emails ) {
$tabs['emails'] = __( 'Email Assignments', 'wc-email-discount' );
}
if ( $this->shipping ) {
$tabs['shipping'] = __( 'Shipping Rules', 'wc-email-discount' );
}
if ( $this->audit ) {
$tabs['audit'] = __( 'Audit Log', 'wc-email-discount' );
}
return $tabs;
}
/**
* Handle POST/GET actions before any output (allows redirects).
*/
public function handle_actions() {
if ( ! isset( $_GET['page'] ) || self::PAGE_SLUG !== $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
return;
}
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return;
}
switch ( $this->current_tab() ) {
case 'groups':
$this->groups->handle_actions();
break;
case 'emails':
$this->emails->handle_actions();
break;
case 'shipping':
$this->shipping->handle_actions();
break;
case 'audit':
$this->audit->handle_actions();
break;
}
}
/**
* Render the admin page with tab navigation.
*/
public function render_page() {
if ( ! current_user_can( 'manage_woocommerce' ) ) {
wp_die( esc_html__( 'You do not have permission to access this page.', 'wc-email-discount' ) );
}
$current = $this->current_tab();
?>
<div class="wrap wc-edm-wrap">
<h1><?php esc_html_e( 'Email Discounts', 'wc-email-discount' ); ?></h1>
<?php $this->render_notices(); ?>
<nav class="nav-tab-wrapper wc-edm-nav">
<?php foreach ( $this->get_tabs() as $slug => $label ) : ?>
<a href="<?php echo esc_url( WC_EDM_Helpers::admin_url( array( 'tab' => $slug ) ) ); ?>"
class="nav-tab <?php echo $current === $slug ? 'nav-tab-active' : ''; ?>">
<?php echo esc_html( $label ); ?>
</a>
<?php endforeach; ?>
</nav>
<div class="wc-edm-content">
<?php
switch ( $current ) {
case 'groups':
$this->groups->render();
break;
case 'emails':
$this->emails->render();
break;
case 'shipping':
$this->shipping->render();
break;
case 'audit':
$this->audit->render();
break;
default:
$this->render_dashboard();
break;
}
?>
</div>
</div>
<?php
}
/**
* Render success/error notices based on the ?message= query arg.
*/
private function render_notices() {
if ( ! isset( $_GET['message'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
return;
}
$message = sanitize_key( wp_unslash( $_GET['message'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$messages = array(
'saved' => array( 'success', __( 'Saved successfully.', 'wc-email-discount' ) ),
'deleted' => array( 'success', __( 'Deleted successfully.', 'wc-email-discount' ) ),
'error' => array( 'error', __( 'Something went wrong. Please try again.', 'wc-email-discount' ) ),
);
if ( ! isset( $messages[ $message ] ) ) {
return;
}
list( $type, $text ) = $messages[ $message ];
printf(
'<div class="notice notice-%1$s is-dismissible"><p>%2$s</p></div>',
esc_attr( $type ),
esc_html( $text )
);
}
/**
* Render the dashboard tab: stats cards, quick actions, recent groups.
*/
private function render_dashboard() {
$group_count = WC_EDM_DB::count_groups();
$email_count = WC_EDM_DB::count_emails();
$active_count = WC_EDM_DB::count_emails( true );
$recent = WC_EDM_DB::get_recent_groups( 5 );
?>
<div class="wc-edm-stats">
<div class="wc-edm-stat-card">
<span class="wc-edm-stat-number"><?php echo esc_html( $group_count ); ?></span>
<span class="wc-edm-stat-label"><?php esc_html_e( 'Discount Groups', 'wc-email-discount' ); ?></span>
</div>
<div class="wc-edm-stat-card">
<span class="wc-edm-stat-number"><?php echo esc_html( $email_count ); ?></span>
<span class="wc-edm-stat-label"><?php esc_html_e( 'Email Assignments', 'wc-email-discount' ); ?></span>
</div>
<div class="wc-edm-stat-card">
<span class="wc-edm-stat-number"><?php echo esc_html( $active_count ); ?></span>
<span class="wc-edm-stat-label"><?php esc_html_e( 'Active Assignments', 'wc-email-discount' ); ?></span>
</div>
</div>
<h2><?php esc_html_e( 'Quick Actions', 'wc-email-discount' ); ?></h2>
<p class="wc-edm-quick-actions">
<a class="button button-primary" href="<?php echo esc_url( WC_EDM_Helpers::admin_url( array( 'tab' => 'groups', 'action' => 'new' ) ) ); ?>">
<?php esc_html_e( 'Add Discount Group', 'wc-email-discount' ); ?>
</a>
<a class="button button-primary" href="<?php echo esc_url( WC_EDM_Helpers::admin_url( array( 'tab' => 'emails', 'action' => 'new' ) ) ); ?>">
<?php esc_html_e( 'Add Email Assignment', 'wc-email-discount' ); ?>
</a>
<a class="button" href="<?php echo esc_url( WC_EDM_Helpers::admin_url( array( 'tab' => 'shipping' ) ) ); ?>">
<?php esc_html_e( 'Manage Shipping Rules', 'wc-email-discount' ); ?>
</a>
</p>
<h2><?php esc_html_e( 'Recent Discount Groups', 'wc-email-discount' ); ?></h2>
<?php if ( empty( $recent ) ) : ?>
<p><?php esc_html_e( 'No discount groups yet. Create your first one to get started.', 'wc-email-discount' ); ?></p>
<?php else : ?>
<table class="widefat striped wc-edm-table">
<thead>
<tr>
<th><?php esc_html_e( 'Name', 'wc-email-discount' ); ?></th>
<th><?php esc_html_e( 'Discount', 'wc-email-discount' ); ?></th>
<th><?php esc_html_e( 'Categories', 'wc-email-discount' ); ?></th>
<th><?php esc_html_e( 'Created', 'wc-email-discount' ); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ( $recent as $group ) : ?>
<tr>
<td>
<a href="<?php echo esc_url( WC_EDM_Helpers::admin_url( array( 'tab' => 'groups', 'action' => 'edit', 'id' => (int) $group->id ) ) ); ?>">
<strong><?php echo esc_html( $group->name ); ?></strong>
</a>
</td>
<td><?php echo esc_html( wc_format_localized_decimal( $group->discount_percent ) ); ?>%</td>
<td><?php echo esc_html( count( WC_EDM_DB::get_group_category_ids( (int) $group->id ) ) ); ?></td>
<td><?php echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $group->created_at ) ) ); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php
}
}