255 lines
8.2 KiB
PHP
255 lines
8.2 KiB
PHP
<?php
|
|
/**
|
|
* Statistics Admin Page
|
|
*
|
|
* Displays campaign performance metrics and historical data.
|
|
*
|
|
* @package ROBOTSTXT_SMTP_Newsletter
|
|
* @since 2.2.0
|
|
*/
|
|
|
|
namespace Robotstxt_SMTP_Newsletter\Admin;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Statistics Page class.
|
|
*
|
|
* Provides admin UI for viewing campaign statistics and performance metrics.
|
|
*/
|
|
class Statistics_Page {
|
|
|
|
/**
|
|
* Register admin page hooks.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function register() {
|
|
add_submenu_page(
|
|
'newsletter_main_main',
|
|
__( 'Email Statistics', 'robotstxt-smtp-newsletter' ),
|
|
__( 'Statistics', 'robotstxt-smtp-newsletter' ),
|
|
'manage_options',
|
|
'robotstxt-smtp-newsletter-stats',
|
|
array( __CLASS__, 'render_page' )
|
|
);
|
|
|
|
add_action( 'admin_post_delete_campaign_history', array( __CLASS__, 'handle_delete_campaign' ) );
|
|
}
|
|
|
|
/**
|
|
* Render admin page.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function render_page() {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_die( esc_html__( 'Insufficient permissions', 'robotstxt-smtp-newsletter' ) );
|
|
}
|
|
|
|
$stats_instance = \Robotstxt_SMTP_Newsletter\Statistics::get_instance();
|
|
|
|
// Sync from queue first to get latest data.
|
|
$stats_instance->sync_from_queue();
|
|
|
|
$campaigns = $stats_instance->get_recent_campaigns( 20 );
|
|
$global = $stats_instance->get_global_stats( 30 );
|
|
|
|
// Handle success message.
|
|
if ( isset( $_GET['deleted'] ) ) {
|
|
?>
|
|
<div class="notice notice-success is-dismissible">
|
|
<p>
|
|
<?php
|
|
printf(
|
|
/* translators: %d: number of records deleted */
|
|
esc_html__( '%d queue records deleted.', 'robotstxt-smtp-newsletter' ),
|
|
absint( $_GET['deleted'] )
|
|
);
|
|
?>
|
|
</p>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
?>
|
|
<div class="wrap">
|
|
<h1><?php esc_html_e( 'Email Statistics', 'robotstxt-smtp-newsletter' ); ?></h1>
|
|
|
|
<!-- Global Stats -->
|
|
<h2><?php esc_html_e( 'Global Performance (Last 30 Days)', 'robotstxt-smtp-newsletter' ); ?></h2>
|
|
<table class="widefat" style="max-width:600px; margin-bottom:30px;">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong><?php esc_html_e( 'Total Emails Sent', 'robotstxt-smtp-newsletter' ); ?></strong></td>
|
|
<td style="text-align:right;">
|
|
<?php echo number_format_i18n( $global['total_sent'] ); ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong><?php esc_html_e( 'Total Failed', 'robotstxt-smtp-newsletter' ); ?></strong></td>
|
|
<td style="text-align:right; color:#d9534f;">
|
|
<?php echo number_format_i18n( $global['total_failed'] ); ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong><?php esc_html_e( 'Average Speed', 'robotstxt-smtp-newsletter' ); ?></strong></td>
|
|
<td style="text-align:right;">
|
|
<?php
|
|
printf(
|
|
/* translators: %s: emails per hour */
|
|
esc_html__( '%s emails/hour', 'robotstxt-smtp-newsletter' ),
|
|
number_format_i18n( $global['avg_emails_per_hour'], 0 )
|
|
);
|
|
?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong><?php esc_html_e( 'Success Rate', 'robotstxt-smtp-newsletter' ); ?></strong></td>
|
|
<td style="text-align:right;">
|
|
<?php
|
|
$total = $global['total_sent'] + $global['total_failed'];
|
|
$rate = $total > 0 ? ( $global['total_sent'] / $total ) * 100 : 0;
|
|
echo number_format_i18n( $rate, 1 ) . '%';
|
|
?>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<!-- Campaign Stats -->
|
|
<h2><?php esc_html_e( 'Recent Campaigns', 'robotstxt-smtp-newsletter' ); ?></h2>
|
|
<table class="wp-list-table widefat fixed striped">
|
|
<thead>
|
|
<tr>
|
|
<th><?php esc_html_e( 'Campaign', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
<th style="text-align:right;"><?php esc_html_e( 'Total', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
<th style="text-align:right;"><?php esc_html_e( 'Sent', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
<th style="text-align:right;"><?php esc_html_e( 'Failed', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
<th><?php esc_html_e( 'Started', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
<th><?php esc_html_e( 'Finished', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
<th style="text-align:right;"><?php esc_html_e( 'Duration', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
<th style="text-align:right;"><?php esc_html_e( 'Speed', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
<th><?php esc_html_e( 'Actions', 'robotstxt-smtp-newsletter' ); ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if ( empty( $campaigns ) ) : ?>
|
|
<tr>
|
|
<td colspan="9" style="text-align:center; padding:40px;">
|
|
<p><?php esc_html_e( 'No campaigns found', 'robotstxt-smtp-newsletter' ); ?></p>
|
|
</td>
|
|
</tr>
|
|
<?php else : ?>
|
|
<?php foreach ( $campaigns as $campaign ) : ?>
|
|
<tr>
|
|
<td><strong><?php echo esc_html( $campaign->campaign_name ); ?></strong></td>
|
|
<td style="text-align:right;">
|
|
<?php echo number_format_i18n( $campaign->total_emails ); ?>
|
|
</td>
|
|
<td style="text-align:right; color:#5cb85c;">
|
|
<?php echo number_format_i18n( $campaign->sent_emails ); ?>
|
|
</td>
|
|
<td style="text-align:right; color:#d9534f;">
|
|
<?php echo number_format_i18n( $campaign->failed_emails ); ?>
|
|
</td>
|
|
<td>
|
|
<?php
|
|
if ( $campaign->started_at ) {
|
|
$started_time = mysql2date( 'Y-m-d H:i:s', $campaign->started_at );
|
|
echo esc_html( $started_time );
|
|
} else {
|
|
echo '-';
|
|
}
|
|
?>
|
|
</td>
|
|
<td>
|
|
<?php
|
|
if ( $campaign->finished_at ) {
|
|
$finished_time = mysql2date( 'Y-m-d H:i:s', $campaign->finished_at );
|
|
echo esc_html( $finished_time );
|
|
} else {
|
|
echo '<em>' . esc_html__( 'In progress', 'robotstxt-smtp-newsletter' ) . '</em>';
|
|
}
|
|
?>
|
|
</td>
|
|
<td style="text-align:right;">
|
|
<?php
|
|
if ( $campaign->duration_seconds ) {
|
|
$minutes = floor( $campaign->duration_seconds / 60 );
|
|
$seconds = $campaign->duration_seconds % 60;
|
|
echo sprintf( '%dm %ds', absint( $minutes ), absint( $seconds ) );
|
|
} else {
|
|
echo '-';
|
|
}
|
|
?>
|
|
</td>
|
|
<td style="text-align:right;">
|
|
<?php
|
|
if ( $campaign->emails_per_hour ) {
|
|
echo number_format_i18n( $campaign->emails_per_hour, 0 ) . '/h<br>';
|
|
echo '<small>' . number_format_i18n( $campaign->emails_per_minute, 1 ) . '/min</small>';
|
|
} else {
|
|
echo '-';
|
|
}
|
|
?>
|
|
</td>
|
|
<td>
|
|
<?php if ( $campaign->newsletter_id ) : ?>
|
|
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="display:inline;">
|
|
<?php wp_nonce_field( 'delete_campaign_history', 'delete_campaign_nonce' ); ?>
|
|
<input type="hidden" name="action" value="delete_campaign_history">
|
|
<input type="hidden" name="newsletter_id" value="<?php echo absint( $campaign->newsletter_id ); ?>">
|
|
<button type="submit" class="button button-small" onclick="return confirm('<?php echo esc_attr__( 'Delete all queue records for this campaign? Statistics will be preserved.', 'robotstxt-smtp-newsletter' ); ?>');">
|
|
<?php esc_html_e( 'Delete Queue', 'robotstxt-smtp-newsletter' ); ?>
|
|
</button>
|
|
</form>
|
|
<?php else : ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Handle delete campaign queue action.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function handle_delete_campaign() {
|
|
check_admin_referer( 'delete_campaign_history', 'delete_campaign_nonce' );
|
|
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_die( esc_html__( 'Insufficient permissions', 'robotstxt-smtp-newsletter' ) );
|
|
}
|
|
|
|
$newsletter_id = isset( $_POST['newsletter_id'] ) ? absint( $_POST['newsletter_id'] ) : 0;
|
|
|
|
if ( $newsletter_id > 0 ) {
|
|
$queue = \Robotstxt_SMTP_Newsletter\Queue::get_instance();
|
|
$deleted = $queue->delete_campaign_history( $newsletter_id );
|
|
|
|
wp_safe_redirect(
|
|
add_query_arg(
|
|
array(
|
|
'page' => 'robotstxt-smtp-newsletter-stats',
|
|
'deleted' => $deleted,
|
|
),
|
|
admin_url( 'admin.php' )
|
|
)
|
|
);
|
|
exit;
|
|
}
|
|
|
|
wp_safe_redirect( admin_url( 'admin.php?page=robotstxt-smtp-newsletter-stats' ) );
|
|
exit;
|
|
}
|
|
}
|