v2.2.0
This commit is contained in:
parent
0a42e00299
commit
0ece5f3a6d
16 changed files with 2342 additions and 785 deletions
255
admin/class-statistics-page.php
Normal file
255
admin/class-statistics-page.php
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue